1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 2005-2007  Brian Paul   All Rights Reserved.
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 2008  VMware, Inc.   All Rights Reserved.
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright © 2010 Intel Corporation
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright © 2011 Bryan Cain
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"),
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions:
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the next
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * paragraph) shall be included in all copies or substantial portions of the
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software.
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * DEALINGS IN THE SOFTWARE.
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \file glsl_to_tgsi.cpp
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Translate GLSL IR to TGSI.
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <stdio.h>
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/compiler.h"
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ir.h"
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ir_visitor.h"
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ir_print_visitor.h"
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ir_expression_flattening.h"
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "glsl_types.h"
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "glsl_parser_extras.h"
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "../glsl/program.h"
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ir_optimization.h"
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ast.h"
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/mtypes.h"
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/shaderobj.h"
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "program/hash_table.h"
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern "C" {
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/shaderapi.h"
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/uniforms.h"
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "program/prog_instruction.h"
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "program/prog_optimize.h"
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "program/prog_print.h"
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "program/program.h"
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "program/prog_parameter.h"
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "program/sampler.h"
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_compiler.h"
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_context.h"
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_screen.h"
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_shader_tokens.h"
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_state.h"
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_math.h"
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tgsi/tgsi_ureg.h"
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tgsi/tgsi_info.h"
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "st_context.h"
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "st_program.h"
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "st_glsl_to_tgsi.h"
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "st_mesa_to_tgsi.h"
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define PROGRAM_IMMEDIATE PROGRAM_FILE_MAX
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define PROGRAM_ANY_CONST ((1 << PROGRAM_LOCAL_PARAM) |  \
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           (1 << PROGRAM_ENV_PARAM) |    \
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           (1 << PROGRAM_STATE_VAR) |    \
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           (1 << PROGRAM_NAMED_PARAM) |  \
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           (1 << PROGRAM_CONSTANT) |     \
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           (1 << PROGRAM_UNIFORM))
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Maximum number of temporary registers.
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * It is too big for stack allocated arrays -- it will cause stack overflow on
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Windows and likely Mac OS X.
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define MAX_TEMPS         4096
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* will be 4 for GLSL 4.00 */
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define MAX_GLSL_TEXTURE_OFFSET 1
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass st_src_reg;
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass st_dst_reg;
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int swizzle_for_size(int size);
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This struct is a corresponding struct to TGSI ureg_src.
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass st_src_reg {
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic:
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_src_reg(gl_register_file file, int index, const glsl_type *type)
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->file = file;
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->index = index;
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (type && (type->is_scalar() || type->is_vector() || type->is_matrix()))
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         this->swizzle = swizzle_for_size(type->vector_elements);
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         this->swizzle = SWIZZLE_XYZW;
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->negate = 0;
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->type = type ? type->base_type : GLSL_TYPE_ERROR;
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->reladdr = NULL;
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_src_reg(gl_register_file file, int index, int type)
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->type = type;
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->file = file;
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->index = index;
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->swizzle = SWIZZLE_XYZW;
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->negate = 0;
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->reladdr = NULL;
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_src_reg()
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->type = GLSL_TYPE_ERROR;
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->file = PROGRAM_UNDEFINED;
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->index = 0;
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->swizzle = 0;
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->negate = 0;
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->reladdr = NULL;
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   explicit st_src_reg(st_dst_reg reg);
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gl_register_file file; /**< PROGRAM_* from Mesa */
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int negate; /**< NEGATE_XYZW mask from mesa */
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int type; /** GLSL_TYPE_* from GLSL IR (enum glsl_base_type) */
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /** Register index should be offset by the integer in this reg. */
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_src_reg *reladdr;
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass st_dst_reg {
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic:
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_dst_reg(gl_register_file file, int writemask, int type)
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->file = file;
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->index = 0;
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->writemask = writemask;
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->cond_mask = COND_TR;
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->reladdr = NULL;
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->type = type;
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_dst_reg()
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->type = GLSL_TYPE_ERROR;
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->file = PROGRAM_UNDEFINED;
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->index = 0;
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->writemask = 0;
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->cond_mask = COND_TR;
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->reladdr = NULL;
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   explicit st_dst_reg(st_src_reg reg);
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gl_register_file file; /**< PROGRAM_* from Mesa */
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int writemask; /**< Bitfield of WRITEMASK_[XYZW] */
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint cond_mask:4;
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int type; /** GLSL_TYPE_* from GLSL IR (enum glsl_base_type) */
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /** Register index should be offset by the integer in this reg. */
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_src_reg *reladdr;
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_src_reg::st_src_reg(st_dst_reg reg)
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->type = reg.type;
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->file = reg.file;
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->index = reg.index;
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->swizzle = SWIZZLE_XYZW;
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->negate = 0;
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->reladdr = reg.reladdr;
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_dst_reg::st_dst_reg(st_src_reg reg)
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->type = reg.type;
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->file = reg.file;
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->index = reg.index;
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->writemask = WRITEMASK_XYZW;
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->cond_mask = COND_TR;
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->reladdr = reg.reladdr;
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass glsl_to_tgsi_instruction : public exec_node {
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic:
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Callers of this ralloc-based new need not call delete. It's
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * easier to just ralloc_free 'ctx' (or any of its ancestors). */
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   static void* operator new(size_t size, void *ctx)
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      void *node;
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      node = rzalloc_size(ctx, size);
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(node != NULL);
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return node;
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned op;
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_dst_reg dst;
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_src_reg src[3];
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /** Pointer to the ir source this tree came from for debugging */
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_instruction *ir;
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLboolean cond_update;
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bool saturate;
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int sampler; /**< sampler index */
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int tex_target; /**< One of TEXTURE_*_INDEX */
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLboolean tex_shadow;
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct tgsi_texture_offset tex_offsets[MAX_GLSL_TEXTURE_OFFSET];
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned tex_offset_num_offset;
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int dead_mask; /**< Used in dead code elimination */
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   class function_entry *function; /* Set on TGSI_OPCODE_CAL or TGSI_OPCODE_BGNSUB */
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass variable_storage : public exec_node {
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic:
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   variable_storage(ir_variable *var, gl_register_file file, int index)
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      : file(file), index(index), var(var)
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* empty */
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gl_register_file file;
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int index;
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_variable *var; /* variable that maps to this, if any */
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass immediate_storage : public exec_node {
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic:
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   immediate_storage(gl_constant_value *values, int size, int type)
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      memcpy(this->values, values, size * sizeof(gl_constant_value));
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->size = size;
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->type = type;
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gl_constant_value values[4];
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int size; /**< Number of components (1-4) */
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int type; /**< GL_FLOAT, GL_INT, GL_BOOL, or GL_UNSIGNED_INT */
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass function_entry : public exec_node {
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic:
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_function_signature *sig;
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /**
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * identifier of this function signature used by the program.
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * At the point that TGSI instructions for function calls are
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * generated, we don't know the address of the first instruction of
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * the function body.  So we make the BranchTarget that is called a
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * small integer and rewrite them during set_branchtargets().
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int sig_id;
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /**
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Pointer to first instruction of the function body.
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Set during function body emits after main() is processed.
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glsl_to_tgsi_instruction *bgn_inst;
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /**
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Index of the first instruction of the function body in actual TGSI.
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Set after conversion from glsl_to_tgsi_instruction to TGSI.
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int inst;
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /** Storage for the return value. */
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_src_reg return_reg;
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass glsl_to_tgsi_visitor : public ir_visitor {
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic:
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glsl_to_tgsi_visitor();
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ~glsl_to_tgsi_visitor();
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   function_entry *current_function;
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_context *ctx;
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_program *prog;
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_shader_program *shader_program;
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_shader_compiler_options *options;
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int next_temp;
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int num_address_regs;
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int samplers_used;
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bool indirect_addr_temps;
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bool indirect_addr_consts;
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int glsl_version;
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bool native_integers;
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   variable_storage *find_variable_storage(ir_variable *var);
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int add_constant(gl_register_file file, gl_constant_value values[4],
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    int size, int datatype, GLuint *swizzle_out);
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   function_entry *get_function_signature(ir_function_signature *sig);
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_src_reg get_temp(const glsl_type *type);
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void reladdr_to_temp(ir_instruction *ir, st_src_reg *reg, int *num_reladdr);
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_src_reg st_src_reg_for_float(float val);
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_src_reg st_src_reg_for_int(int val);
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_src_reg st_src_reg_for_type(int type, int val);
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /**
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * \name Visit methods
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * As typical for the visitor pattern, there must be one \c visit method for
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * each concrete subclass of \c ir_instruction.  Virtual base classes within
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * the hierarchy should not have \c visit methods.
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*@{*/
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   virtual void visit(ir_variable *);
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   virtual void visit(ir_loop *);
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   virtual void visit(ir_loop_jump *);
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   virtual void visit(ir_function_signature *);
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   virtual void visit(ir_function *);
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   virtual void visit(ir_expression *);
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   virtual void visit(ir_swizzle *);
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   virtual void visit(ir_dereference_variable  *);
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   virtual void visit(ir_dereference_array *);
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   virtual void visit(ir_dereference_record *);
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   virtual void visit(ir_assignment *);
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   virtual void visit(ir_constant *);
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   virtual void visit(ir_call *);
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   virtual void visit(ir_return *);
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   virtual void visit(ir_discard *);
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   virtual void visit(ir_texture *);
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   virtual void visit(ir_if *);
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*@}*/
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_src_reg result;
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /** List of variable_storage */
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   exec_list variables;
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /** List of immediate_storage */
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   exec_list immediates;
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned num_immediates;
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /** List of function_entry */
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   exec_list function_signatures;
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int next_signature_id;
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /** List of glsl_to_tgsi_instruction */
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   exec_list instructions;
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op);
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op,
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		        st_dst_reg dst, st_src_reg src0);
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op,
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		        st_dst_reg dst, st_src_reg src0, st_src_reg src1);
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op,
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		        st_dst_reg dst,
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		        st_src_reg src0, st_src_reg src1, st_src_reg src2);
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned get_opcode(ir_instruction *ir, unsigned op,
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    st_dst_reg dst,
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    st_src_reg src0, st_src_reg src1);
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /**
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Emit the correct dot-product instruction for the type of arguments
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glsl_to_tgsi_instruction *emit_dp(ir_instruction *ir,
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     st_dst_reg dst,
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     st_src_reg src0,
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     st_src_reg src1,
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     unsigned elements);
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void emit_scalar(ir_instruction *ir, unsigned op,
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	    st_dst_reg dst, st_src_reg src0);
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void emit_scalar(ir_instruction *ir, unsigned op,
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	    st_dst_reg dst, st_src_reg src0, st_src_reg src1);
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void try_emit_float_set(ir_instruction *ir, unsigned op, st_dst_reg dst);
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void emit_arl(ir_instruction *ir, st_dst_reg dst, st_src_reg src0);
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void emit_scs(ir_instruction *ir, unsigned op,
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	 st_dst_reg dst, const st_src_reg &src);
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bool try_emit_mad(ir_expression *ir,
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              int mul_operand);
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bool try_emit_mad_for_and_not(ir_expression *ir,
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              int mul_operand);
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bool try_emit_sat(ir_expression *ir);
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void emit_swz(ir_expression *ir);
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bool process_move_condition(ir_rvalue *ir);
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void simplify_cmp(void);
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void rename_temp_register(int index, int new_index);
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int get_first_temp_read(int index);
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int get_first_temp_write(int index);
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int get_last_temp_read(int index);
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int get_last_temp_write(int index);
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void copy_propagate(void);
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void eliminate_dead_code(void);
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int eliminate_dead_code_advanced(void);
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void merge_registers(void);
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void renumber_registers(void);
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *mem_ctx;
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic st_src_reg undef_src = st_src_reg(PROGRAM_UNDEFINED, 0, GLSL_TYPE_ERROR);
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic st_dst_reg undef_dst = st_dst_reg(PROGRAM_UNDEFINED, SWIZZLE_NOOP, GLSL_TYPE_ERROR);
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic st_dst_reg address_reg = st_dst_reg(PROGRAM_ADDRESS, WRITEMASK_X, GLSL_TYPE_FLOAT);
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfail_link(struct gl_shader_program *prog, const char *fmt, ...) PRINTFLIKE(2, 3);
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfail_link(struct gl_shader_program *prog, const char *fmt, ...)
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   va_list args;
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   va_start(args, fmt);
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ralloc_vasprintf_append(&prog->InfoLog, fmt, args);
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   va_end(args);
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   prog->LinkStatus = GL_FALSE;
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgswizzle_for_size(int size)
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int size_swizzles[4] = {
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y),
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z),
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W),
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   };
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert((size >= 1) && (size <= 4));
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return size_swizzles[size - 1];
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic bool
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgis_tex_instruction(unsigned opcode)
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const tgsi_opcode_info* info = tgsi_get_opcode_info(opcode);
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return info->is_tex;
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnum_inst_dst_regs(unsigned opcode)
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const tgsi_opcode_info* info = tgsi_get_opcode_info(opcode);
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return info->num_dst;
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnum_inst_src_regs(unsigned opcode)
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const tgsi_opcode_info* info = tgsi_get_opcode_info(opcode);
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return info->is_tex ? info->num_src - 1 : info->num_src;
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_instruction *
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op,
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		 st_dst_reg dst,
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		 st_src_reg src0, st_src_reg src1, st_src_reg src2)
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glsl_to_tgsi_instruction *inst = new(mem_ctx) glsl_to_tgsi_instruction();
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int num_reladdr = 0, i;
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   op = get_opcode(ir, op, dst, src0, src1);
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* If we have to do relative addressing, we want to load the ARL
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * reg directly for one of the regs, and preload the other reladdr
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * sources into temps.
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   num_reladdr += dst.reladdr != NULL;
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   num_reladdr += src0.reladdr != NULL;
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   num_reladdr += src1.reladdr != NULL;
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   num_reladdr += src2.reladdr != NULL;
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   reladdr_to_temp(ir, &src2, &num_reladdr);
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   reladdr_to_temp(ir, &src1, &num_reladdr);
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   reladdr_to_temp(ir, &src0, &num_reladdr);
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dst.reladdr) {
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit_arl(ir, address_reg, *dst.reladdr);
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      num_reladdr--;
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(num_reladdr == 0);
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   inst->op = op;
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   inst->dst = dst;
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   inst->src[0] = src0;
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   inst->src[1] = src1;
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   inst->src[2] = src2;
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   inst->ir = ir;
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   inst->dead_mask = 0;
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   inst->function = NULL;
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (op == TGSI_OPCODE_ARL || op == TGSI_OPCODE_UARL)
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->num_address_regs = 1;
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Update indirect addressing status used by TGSI */
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dst.reladdr) {
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch(dst.file) {
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case PROGRAM_TEMPORARY:
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         this->indirect_addr_temps = true;
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case PROGRAM_LOCAL_PARAM:
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case PROGRAM_ENV_PARAM:
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case PROGRAM_STATE_VAR:
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case PROGRAM_NAMED_PARAM:
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case PROGRAM_CONSTANT:
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case PROGRAM_UNIFORM:
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         this->indirect_addr_consts = true;
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case PROGRAM_IMMEDIATE:
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(!"immediates should not have indirect addressing");
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i=0; i<3; i++) {
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if(inst->src[i].reladdr) {
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            switch(inst->src[i].file) {
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case PROGRAM_TEMPORARY:
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               this->indirect_addr_temps = true;
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               break;
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case PROGRAM_LOCAL_PARAM:
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case PROGRAM_ENV_PARAM:
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case PROGRAM_STATE_VAR:
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case PROGRAM_NAMED_PARAM:
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case PROGRAM_CONSTANT:
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case PROGRAM_UNIFORM:
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               this->indirect_addr_consts = true;
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               break;
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case PROGRAM_IMMEDIATE:
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               assert(!"immediates should not have indirect addressing");
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               break;
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            default:
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               break;
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->instructions.push_tail(inst);
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (native_integers)
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      try_emit_float_set(ir, op, dst);
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return inst;
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_instruction *
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op,
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		 st_dst_reg dst, st_src_reg src0, st_src_reg src1)
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return emit(ir, op, dst, src0, src1, undef_src);
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_instruction *
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op,
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		 st_dst_reg dst, st_src_reg src0)
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(dst.writemask != 0);
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return emit(ir, op, dst, src0, undef_src, undef_src);
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_instruction *
601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op)
602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return emit(ir, op, undef_dst, undef_src, undef_src, undef_src);
604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /**
607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Emits the code to convert the result of float SET instructions to integers.
608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::try_emit_float_set(ir_instruction *ir, unsigned op,
611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		 st_dst_reg dst)
612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if ((op == TGSI_OPCODE_SEQ ||
614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        op == TGSI_OPCODE_SNE ||
615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        op == TGSI_OPCODE_SGE ||
616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        op == TGSI_OPCODE_SLT))
617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      st_src_reg src = st_src_reg(dst);
619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src.negate = ~src.negate;
620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dst.type = GLSL_TYPE_FLOAT;
621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_F2I, dst, src);
622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Determines whether to use an integer, unsigned integer, or float opcode
627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * based on the operands and input opcode, then emits the result.
628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned
630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::get_opcode(ir_instruction *ir, unsigned op,
631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		 st_dst_reg dst,
632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		 st_src_reg src0, st_src_reg src1)
633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int type = GLSL_TYPE_FLOAT;
635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(src0.type != GLSL_TYPE_ARRAY);
637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(src0.type != GLSL_TYPE_STRUCT);
638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(src1.type != GLSL_TYPE_ARRAY);
639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(src1.type != GLSL_TYPE_STRUCT);
640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (src0.type == GLSL_TYPE_FLOAT || src1.type == GLSL_TYPE_FLOAT)
642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type = GLSL_TYPE_FLOAT;
643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (native_integers)
644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type = src0.type == GLSL_TYPE_BOOL ? GLSL_TYPE_INT : src0.type;
645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define case4(c, f, i, u) \
647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_##c: \
648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (type == GLSL_TYPE_INT) op = TGSI_OPCODE_##i; \
649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if (type == GLSL_TYPE_UINT) op = TGSI_OPCODE_##u; \
650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else op = TGSI_OPCODE_##f; \
651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define case3(f, i, u)  case4(f, f, i, u)
653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define case2fi(f, i)   case4(f, f, i, i)
654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define case2iu(i, u)   case4(i, LAST, i, u)
655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch(op) {
657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case2fi(ADD, UADD);
658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case2fi(MUL, UMUL);
659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case2fi(MAD, UMAD);
660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case3(DIV, IDIV, UDIV);
661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case3(MAX, IMAX, UMAX);
662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case3(MIN, IMIN, UMIN);
663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case2iu(MOD, UMOD);
664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case2fi(SEQ, USEQ);
666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case2fi(SNE, USNE);
667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case3(SGE, ISGE, USGE);
668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case3(SLT, ISLT, USLT);
669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case2iu(ISHR, USHR);
671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case2fi(SSG, ISSG);
673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case3(ABS, IABS, IABS);
674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default: break;
676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(op != TGSI_OPCODE_LAST);
679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return op;
680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_instruction *
683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::emit_dp(ir_instruction *ir,
684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		    st_dst_reg dst, st_src_reg src0, st_src_reg src1,
685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		    unsigned elements)
686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   static const unsigned dot_opcodes[] = {
688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      TGSI_OPCODE_DP2, TGSI_OPCODE_DP3, TGSI_OPCODE_DP4
689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   };
690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return emit(ir, dot_opcodes[elements - 2], dst, src0, src1);
692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Emits TGSI scalar opcodes to produce unique answers across channels.
696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Some TGSI opcodes are scalar-only, like ARB_fp/vp.  The src X
698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * channel determines the result across all channels.  So to do a vec4
699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of this operation, we want to emit a scalar per source channel used
700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to produce dest channels.
701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::emit_scalar(ir_instruction *ir, unsigned op,
704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		        st_dst_reg dst,
705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        			st_src_reg orig_src0, st_src_reg orig_src1)
706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i, j;
708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int done_mask = ~dst.writemask;
709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* TGSI RCP is a scalar operation splatting results to all channels,
711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * like ARB_fp/vp.  So emit as many RCPs as necessary to cover our
712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * dst channels.
713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < 4; i++) {
715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLuint this_mask = (1 << i);
716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      glsl_to_tgsi_instruction *inst;
717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      st_src_reg src0 = orig_src0;
718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      st_src_reg src1 = orig_src1;
719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (done_mask & this_mask)
721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         continue;
722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLuint src0_swiz = GET_SWZ(src0.swizzle, i);
724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLuint src1_swiz = GET_SWZ(src1.swizzle, i);
725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (j = i + 1; j < 4; j++) {
726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* If there is another enabled component in the destination that is
727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * derived from the same inputs, generate its value on this pass as
728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * well.
729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!(done_mask & (1 << j)) &&
731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             GET_SWZ(src0.swizzle, j) == src0_swiz &&
732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             GET_SWZ(src1.swizzle, j) == src1_swiz) {
733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            this_mask |= (1 << j);
734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz,
737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        			   src0_swiz, src0_swiz);
738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz,
739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        			  src1_swiz, src1_swiz);
740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst = emit(ir, op, dst, src0, src1);
742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst->dst.writemask = this_mask;
743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      done_mask |= this_mask;
744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::emit_scalar(ir_instruction *ir, unsigned op,
749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		        st_dst_reg dst, st_src_reg src0)
750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_src_reg undef = undef_src;
752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   undef.swizzle = SWIZZLE_XXXX;
754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit_scalar(ir, op, dst, src0, undef);
756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::emit_arl(ir_instruction *ir,
760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		        st_dst_reg dst, st_src_reg src0)
761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int op = TGSI_OPCODE_ARL;
763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (src0.type == GLSL_TYPE_INT || src0.type == GLSL_TYPE_UINT)
765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op = TGSI_OPCODE_UARL;
766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit(NULL, op, dst, src0);
768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Emit an TGSI_OPCODE_SCS instruction
772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The \c SCS opcode functions a bit differently than the other TGSI opcodes.
774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Instead of splatting its result across all four components of the
775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * destination, it writes one value to the \c x component and another value to
776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the \c y component.
777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param ir        IR instruction being processed
779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param op        Either \c TGSI_OPCODE_SIN or \c TGSI_OPCODE_COS depending
780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *                  on which value is desired.
781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param dst       Destination register
782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param src       Source register
783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::emit_scs(ir_instruction *ir, unsigned op,
786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		     st_dst_reg dst,
787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		     const st_src_reg &src)
788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Vertex programs cannot use the SCS opcode.
790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (this->prog->Target == GL_VERTEX_PROGRAM_ARB) {
792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit_scalar(ir, op, dst, src);
793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const unsigned component = (op == TGSI_OPCODE_SIN) ? 0 : 1;
797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const unsigned scs_mask = (1U << component);
798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int done_mask = ~dst.writemask;
799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_src_reg tmp;
800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(op == TGSI_OPCODE_SIN || op == TGSI_OPCODE_COS);
802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* If there are compnents in the destination that differ from the component
804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * that will be written by the SCS instrution, we'll need a temporary.
805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (scs_mask != unsigned(dst.writemask)) {
807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tmp = get_temp(glsl_type::vec4_type);
808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (unsigned i = 0; i < 4; i++) {
811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned this_mask = (1U << i);
812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      st_src_reg src0 = src;
813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if ((done_mask & this_mask) != 0)
815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         continue;
816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* The source swizzle specified which component of the source generates
818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * sine / cosine for the current component in the destination.  The SCS
819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * instruction requires that this value be swizzle to the X component.
820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Replace the current swizzle with a swizzle that puts the source in
821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * the X component.
822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned src0_swiz = GET_SWZ(src.swizzle, i);
824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz,
826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        			   src0_swiz, src0_swiz);
827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned j = i + 1; j < 4; j++) {
828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* If there is another enabled component in the destination that is
829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * derived from the same inputs, generate its value on this pass as
830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * well.
831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!(done_mask & (1 << j)) &&
833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             GET_SWZ(src0.swizzle, j) == src0_swiz) {
834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            this_mask |= (1 << j);
835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (this_mask != scs_mask) {
839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         glsl_to_tgsi_instruction *inst;
840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         st_dst_reg tmp_dst = st_dst_reg(tmp);
841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Emit the SCS instruction.
843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         inst = emit(ir, TGSI_OPCODE_SCS, tmp_dst, src0);
845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         inst->dst.writemask = scs_mask;
846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Move the result of the SCS instruction to the desired location in
848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * the destination.
849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         tmp.swizzle = MAKE_SWIZZLE4(component, component,
851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        			     component, component);
852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         inst = emit(ir, TGSI_OPCODE_SCS, dst, tmp);
853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         inst->dst.writemask = this_mask;
854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Emit the SCS instruction to write directly to the destination.
856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         glsl_to_tgsi_instruction *inst = emit(ir, TGSI_OPCODE_SCS, dst, src0);
858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         inst->dst.writemask = scs_mask;
859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      done_mask |= this_mask;
862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint
866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::add_constant(gl_register_file file,
867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		     gl_constant_value values[4], int size, int datatype,
868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		     GLuint *swizzle_out)
869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (file == PROGRAM_CONSTANT) {
871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return _mesa_add_typed_unnamed_constant(this->prog->Parameters, values,
872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              size, datatype, swizzle_out);
873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int index = 0;
875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      immediate_storage *entry;
876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(file == PROGRAM_IMMEDIATE);
877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Search immediate storage to see if we already have an identical
879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * immediate that we can use instead of adding a duplicate entry.
880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      foreach_iter(exec_list_iterator, iter, this->immediates) {
882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         entry = (immediate_storage *)iter.get();
883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (entry->size == size &&
885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             entry->type == datatype &&
886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             !memcmp(entry->values, values, size * sizeof(gl_constant_value))) {
887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             return index;
888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         index++;
890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Add this immediate to the list. */
893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      entry = new(mem_ctx) immediate_storage(values, size, datatype);
894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->immediates.push_tail(entry);
895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->num_immediates++;
896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return index;
897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_src_reg
901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::st_src_reg_for_float(float val)
902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_src_reg src(PROGRAM_IMMEDIATE, -1, GLSL_TYPE_FLOAT);
904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   union gl_constant_value uval;
905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uval.f = val;
907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src.index = add_constant(src.file, &uval, 1, GL_FLOAT, &src.swizzle);
908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return src;
910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_src_reg
913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::st_src_reg_for_int(int val)
914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_src_reg src(PROGRAM_IMMEDIATE, -1, GLSL_TYPE_INT);
916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   union gl_constant_value uval;
917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(native_integers);
919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uval.i = val;
921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src.index = add_constant(src.file, &uval, 1, GL_INT, &src.swizzle);
922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return src;
924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_src_reg
927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::st_src_reg_for_type(int type, int val)
928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (native_integers)
930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return type == GLSL_TYPE_FLOAT ? st_src_reg_for_float(val) :
931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       st_src_reg_for_int(val);
932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return st_src_reg_for_float(val);
934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int
937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtype_size(const struct glsl_type *type)
938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned int i;
940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int size;
941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (type->base_type) {
943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_TYPE_UINT:
944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_TYPE_INT:
945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_TYPE_FLOAT:
946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_TYPE_BOOL:
947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (type->is_matrix()) {
948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return type->matrix_columns;
949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Regardless of size of vector, it gets a vec4. This is bad
951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * packing for things like floats, but otherwise arrays become a
952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * mess.  Hopefully a later pass over the code can pack scalars
953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * down if appropriate.
954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return 1;
956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_TYPE_ARRAY:
958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(type->length > 0);
959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return type_size(type->fields.array) * type->length;
960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_TYPE_STRUCT:
961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      size = 0;
962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < type->length; i++) {
963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         size += type_size(type->fields.structure[i].type);
964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return size;
966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_TYPE_SAMPLER:
967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Samplers take up one slot in UNIFORMS[], but they're baked in
968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * at link time.
969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 1;
971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0);
973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 0;
974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * In the initial pass of codegen, we assign temporary numbers to
979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * intermediate results.  (not SSA -- variable assignments will reuse
980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * storage).
981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_src_reg
983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::get_temp(const glsl_type *type)
984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_src_reg src;
986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src.type = native_integers ? type->base_type : GLSL_TYPE_FLOAT;
988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src.file = PROGRAM_TEMPORARY;
989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src.index = next_temp;
990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src.reladdr = NULL;
991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   next_temp += type_size(type);
992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (type->is_array() || type->is_record()) {
994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src.swizzle = SWIZZLE_NOOP;
995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src.swizzle = swizzle_for_size(type->vector_elements);
997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src.negate = 0;
999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return src;
1001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvariable_storage *
1004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::find_variable_storage(ir_variable *var)
1005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   variable_storage *entry;
1008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_iter(exec_list_iterator, iter, this->variables) {
1010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      entry = (variable_storage *)iter.get();
1011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (entry->var == var)
1013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return entry;
1014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
1017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
1020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_variable *ir)
1021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (strcmp(ir->name, "gl_FragCoord") == 0) {
1023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog;
1024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fp->OriginUpperLeft = ir->origin_upper_left;
1026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fp->PixelCenterInteger = ir->pixel_center_integer;
1027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->mode == ir_var_uniform && strncmp(ir->name, "gl_", 3) == 0) {
1030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned int i;
1031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const ir_state_slot *const slots = ir->state_slots;
1032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->state_slots != NULL);
1033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Check if this statevar's setup in the STATE file exactly
1035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * matches how we'll want to reference it as a
1036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * struct/array/whatever.  If not, then we need to move it into
1037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * temporary storage and hope that it'll get copy-propagated
1038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * out.
1039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < ir->num_state_slots; i++) {
1041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (slots[i].swizzle != SWIZZLE_XYZW) {
1042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
1043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      variable_storage *storage;
1047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      st_dst_reg dst;
1048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (i == ir->num_state_slots) {
1049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* We'll set the index later. */
1050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         storage = new(mem_ctx) variable_storage(ir, PROGRAM_STATE_VAR, -1);
1051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         this->variables.push_tail(storage);
1052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         dst = undef_dst;
1054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
1055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* The variable_storage constructor allocates slots based on the size
1056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * of the type.  However, this had better match the number of state
1057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * elements that we're going to copy into the new temporary.
1058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
1059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert((int) ir->num_state_slots == type_size(ir->type));
1060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         storage = new(mem_ctx) variable_storage(ir, PROGRAM_TEMPORARY,
1062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        					 this->next_temp);
1063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         this->variables.push_tail(storage);
1064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         this->next_temp += type_size(ir->type);
1065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         dst = st_dst_reg(st_src_reg(PROGRAM_TEMPORARY, storage->index,
1067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               native_integers ? ir->type->base_type : GLSL_TYPE_FLOAT));
1068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned int i = 0; i < ir->num_state_slots; i++) {
1072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         int index = _mesa_add_state_reference(this->prog->Parameters,
1073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        				       (gl_state_index *)slots[i].tokens);
1074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (storage->file == PROGRAM_STATE_VAR) {
1076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (storage->index == -1) {
1077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               storage->index = index;
1078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            } else {
1079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               assert(index == storage->index + (int)i);
1080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         } else {
1082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         	/* We use GLSL_TYPE_FLOAT here regardless of the actual type of
1083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         	 * the data being moved since MOV does not care about the type of
1084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         	 * data it is moving, and we don't want to declare registers with
1085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         	 * array or struct types.
1086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         	 */
1087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            st_src_reg src(PROGRAM_STATE_VAR, index, GLSL_TYPE_FLOAT);
1088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            src.swizzle = slots[i].swizzle;
1089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            emit(ir, TGSI_OPCODE_MOV, dst, src);
1090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* even a float takes up a whole vec4 reg in a struct/array. */
1091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            dst.index++;
1092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (storage->file == PROGRAM_TEMPORARY &&
1096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          dst.index != storage->index + (int) ir->num_state_slots) {
1097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         fail_link(this->shader_program,
1098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	   "failed to load builtin uniform `%s'  (%d/%d regs loaded)\n",
1099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	   ir->name, dst.index - storage->index,
1100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	   type_size(ir->type));
1101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
1106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_loop *ir)
1107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_dereference_variable *counter = NULL;
1109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->counter != NULL)
1111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      counter = new(ir) ir_dereference_variable(ir->counter);
1112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->from != NULL) {
1114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->counter != NULL);
1115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_assignment *a = new(ir) ir_assignment(counter, ir->from, NULL);
1117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      a->accept(this);
1119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      delete a;
1120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit(NULL, TGSI_OPCODE_BGNLOOP);
1123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->to) {
1125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_expression *e =
1126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         new(ir) ir_expression(ir->cmp, glsl_type::bool_type,
1127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		       counter, ir->to);
1128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_if *if_stmt =  new(ir) ir_if(e);
1129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_loop_jump *brk = new(ir) ir_loop_jump(ir_loop_jump::jump_break);
1131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if_stmt->then_instructions.push_tail(brk);
1133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if_stmt->accept(this);
1135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      delete if_stmt;
1137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      delete e;
1138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      delete brk;
1139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   visit_exec_list(&ir->body_instructions, this);
1142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->increment) {
1144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_expression *e =
1145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         new(ir) ir_expression(ir_binop_add, counter->type,
1146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		       counter, ir->increment);
1147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_assignment *a = new(ir) ir_assignment(counter, e, NULL);
1149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      a->accept(this);
1151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      delete a;
1152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      delete e;
1153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit(NULL, TGSI_OPCODE_ENDLOOP);
1156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
1159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_loop_jump *ir)
1160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (ir->mode) {
1162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_loop_jump::jump_break:
1163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(NULL, TGSI_OPCODE_BRK);
1164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_loop_jump::jump_continue:
1166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(NULL, TGSI_OPCODE_CONT);
1167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
1173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_function_signature *ir)
1174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(0);
1176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void)ir;
1177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
1180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_function *ir)
1181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Ignore function bodies other than main() -- we shouldn't see calls to
1183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * them since they should all be inlined before we get to glsl_to_tgsi.
1184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (strcmp(ir->name, "main") == 0) {
1186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const ir_function_signature *sig;
1187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      exec_list empty;
1188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sig = ir->matching_signature(&empty);
1190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(sig);
1192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      foreach_iter(exec_list_iterator, iter, sig->body) {
1194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ir_instruction *ir = (ir_instruction *)iter.get();
1195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ir->accept(this);
1197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool
1202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::try_emit_mad(ir_expression *ir, int mul_operand)
1203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int nonmul_operand = 1 - mul_operand;
1205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_src_reg a, b, c;
1206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_dst_reg result_dst;
1207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_expression *expr = ir->operands[mul_operand]->as_expression();
1209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!expr || expr->operation != ir_binop_mul)
1210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
1211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   expr->operands[0]->accept(this);
1213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   a = this->result;
1214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   expr->operands[1]->accept(this);
1215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   b = this->result;
1216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir->operands[nonmul_operand]->accept(this);
1217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   c = this->result;
1218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->result = get_temp(ir->type);
1220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   result_dst = st_dst_reg(this->result);
1221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   result_dst.writemask = (1 << ir->type->vector_elements) - 1;
1222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit(ir, TGSI_OPCODE_MAD, result_dst, a, b, c);
1223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return true;
1225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
1228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Emit MAD(a, -b, a) instead of AND(a, NOT(b))
1229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
1230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The logic values are 1.0 for true and 0.0 for false.  Logical-and is
1231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * implemented using multiplication, and logical-or is implemented using
1232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * addition.  Logical-not can be implemented as (true - x), or (1.0 - x).
1233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * As result, the logical expression (a & !b) can be rewritten as:
1234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
1235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *     - a * !b
1236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *     - a * (1 - b)
1237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *     - (a * 1) - (a * b)
1238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *     - a + -(a * b)
1239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *     - a + (a * -b)
1240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
1241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This final expression can be implemented as a single MAD(a, -b, a)
1242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * instruction.
1243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool
1245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::try_emit_mad_for_and_not(ir_expression *ir, int try_operand)
1246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const int other_operand = 1 - try_operand;
1248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_src_reg a, b;
1249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_expression *expr = ir->operands[try_operand]->as_expression();
1251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!expr || expr->operation != ir_unop_logic_not)
1252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
1253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir->operands[other_operand]->accept(this);
1255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   a = this->result;
1256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   expr->operands[0]->accept(this);
1257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   b = this->result;
1258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   b.negate = ~b.negate;
1260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->result = get_temp(ir->type);
1262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit(ir, TGSI_OPCODE_MAD, st_dst_reg(this->result), a, b, a);
1263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return true;
1265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool
1268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::try_emit_sat(ir_expression *ir)
1269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Saturates were only introduced to vertex programs in
1271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * NV_vertex_program3, so don't give them to drivers in the VP.
1272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (this->prog->Target == GL_VERTEX_PROGRAM_ARB)
1274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
1275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_rvalue *sat_src = ir->as_rvalue_to_saturate();
1277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!sat_src)
1278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
1279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sat_src->accept(this);
1281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_src_reg src = this->result;
1282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* If we generated an expression instruction into a temporary in
1284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * processing the saturate's operand, apply the saturate to that
1285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * instruction.  Otherwise, generate a MOV to do the saturate.
1286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
1287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Note that we have to be careful to only do this optimization if
1288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * the instruction in question was what generated src->result.  For
1289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * example, ir_dereference_array might generate a MUL instruction
1290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * to create the reladdr, and return us a src reg using that
1291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * reladdr.  That MUL result is not the value we're trying to
1292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * saturate.
1293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_expression *sat_src_expr = sat_src->as_expression();
1295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (sat_src_expr && (sat_src_expr->operation == ir_binop_mul ||
1296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			sat_src_expr->operation == ir_binop_add ||
1297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			sat_src_expr->operation == ir_binop_dot)) {
1298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      glsl_to_tgsi_instruction *new_inst;
1299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      new_inst = (glsl_to_tgsi_instruction *)this->instructions.get_tail();
1300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      new_inst->saturate = true;
1301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
1302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->result = get_temp(ir->type);
1303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      st_dst_reg result_dst = st_dst_reg(this->result);
1304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result_dst.writemask = (1 << ir->type->vector_elements) - 1;
1305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      glsl_to_tgsi_instruction *inst;
1306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst = emit(ir, TGSI_OPCODE_MOV, result_dst, src);
1307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst->saturate = true;
1308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return true;
1311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
1314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::reladdr_to_temp(ir_instruction *ir,
1315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        			    st_src_reg *reg, int *num_reladdr)
1316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!reg->reladdr)
1318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
1319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit_arl(ir, address_reg, *reg->reladdr);
1321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (*num_reladdr != 1) {
1323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      st_src_reg temp = get_temp(glsl_type::vec4_type);
1324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_MOV, st_dst_reg(temp), *reg);
1326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *reg = temp;
1327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (*num_reladdr)--;
1330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
1333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_expression *ir)
1334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned int operand;
1336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_src_reg op[Elements(ir->operands)];
1337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_src_reg result_src;
1338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_dst_reg result_dst;
1339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Quick peephole: Emit MAD(a, b, c) instead of ADD(MUL(a, b), c)
1341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->operation == ir_binop_add) {
1343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (try_emit_mad(ir, 1))
1344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return;
1345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (try_emit_mad(ir, 0))
1346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return;
1347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Quick peephole: Emit OPCODE_MAD(-a, -b, a) instead of AND(a, NOT(b))
1350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->operation == ir_binop_logic_and) {
1352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (try_emit_mad_for_and_not(ir, 1))
1353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 return;
1354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (try_emit_mad_for_and_not(ir, 0))
1355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 return;
1356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (try_emit_sat(ir))
1359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
1360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->operation == ir_quadop_vector)
1362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(!"ir_quadop_vector should have been lowered");
1363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (operand = 0; operand < ir->get_num_operands(); operand++) {
1365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->result.file = PROGRAM_UNDEFINED;
1366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir->operands[operand]->accept(this);
1367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (this->result.file == PROGRAM_UNDEFINED) {
1368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ir_print_visitor v;
1369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         printf("Failed to get tree for expression operand:\n");
1370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ir->operands[operand]->accept(&v);
1371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         exit(1);
1372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[operand] = this->result;
1374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Matrix expression operands should have been broken down to vector
1376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * operations already.
1377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(!ir->operands[operand]->type->is_matrix());
1379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int vector_elements = ir->operands[0]->type->vector_elements;
1382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->operands[1]) {
1383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      vector_elements = MAX2(vector_elements,
1384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		     ir->operands[1]->type->vector_elements);
1385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->result.file = PROGRAM_UNDEFINED;
1388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Storage for our result.  Ideally for an assignment we'd be using
1390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * the actual storage for the result here, instead.
1391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   result_src = get_temp(ir->type);
1393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* convenience for the emit functions below. */
1394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   result_dst = st_dst_reg(result_src);
1395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Limit writes to the channels that will be used by result_src later.
1396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * This does limit this temp's use as a temporary for multi-instruction
1397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * sequences.
1398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   result_dst.writemask = (1 << ir->type->vector_elements) - 1;
1400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (ir->operation) {
1402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_logic_not:
1403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (result_dst.type != GLSL_TYPE_FLOAT)
1404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_NOT, result_dst, op[0]);
1405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
1406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Previously 'SEQ dst, src, 0.0' was used for this.  However, many
1407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * older GPUs implement SEQ using multiple instructions (i915 uses two
1408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * SGE instructions and a MUL instruction).  Since our logic values are
1409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * 0.0 and 1.0, 1-x also implements !x.
1410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
1411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         op[0].negate = ~op[0].negate;
1412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_ADD, result_dst, op[0], st_src_reg_for_float(1.0));
1413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_neg:
1416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (result_dst.type == GLSL_TYPE_INT || result_dst.type == GLSL_TYPE_UINT)
1417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_INEG, result_dst, op[0]);
1418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
1419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         op[0].negate = ~op[0].negate;
1420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         result_src = op[0];
1421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_abs:
1424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_ABS, result_dst, op[0]);
1425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_sign:
1427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_SSG, result_dst, op[0]);
1428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_rcp:
1430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit_scalar(ir, TGSI_OPCODE_RCP, result_dst, op[0]);
1431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_exp2:
1434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit_scalar(ir, TGSI_OPCODE_EX2, result_dst, op[0]);
1435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_exp:
1437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_log:
1438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(!"not reached: should be handled by ir_explog_to_explog2");
1439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_log2:
1441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit_scalar(ir, TGSI_OPCODE_LG2, result_dst, op[0]);
1442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_sin:
1444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit_scalar(ir, TGSI_OPCODE_SIN, result_dst, op[0]);
1445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_cos:
1447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit_scalar(ir, TGSI_OPCODE_COS, result_dst, op[0]);
1448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_sin_reduced:
1450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit_scs(ir, TGSI_OPCODE_SIN, result_dst, op[0]);
1451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_cos_reduced:
1453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit_scs(ir, TGSI_OPCODE_COS, result_dst, op[0]);
1454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_dFdx:
1457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_DDX, result_dst, op[0]);
1458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_dFdy:
1460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
1461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* The X component contains 1 or -1 depending on whether the framebuffer
1462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * is a FBO or the window system buffer, respectively.
1463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * It is then multiplied with the source operand of DDY.
1464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      static const gl_state_index transform_y_state[STATE_LENGTH]
1466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         = { STATE_INTERNAL, STATE_FB_WPOS_Y_TRANSFORM };
1467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned transform_y_index =
1469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_add_state_reference(this->prog->Parameters,
1470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   transform_y_state);
1471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      st_src_reg transform_y = st_src_reg(PROGRAM_STATE_VAR,
1473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          transform_y_index,
1474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          glsl_type::vec4_type);
1475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      transform_y.swizzle = SWIZZLE_XXXX;
1476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      st_src_reg temp = get_temp(glsl_type::vec4_type);
1478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_MUL, st_dst_reg(temp), transform_y, op[0]);
1480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_DDY, result_dst, temp);
1481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_noise: {
1485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* At some point, a motivated person could add a better
1486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * implementation of noise.  Currently not even the nvidia
1487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * binary drivers do anything more than this.  In any case, the
1488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * place to do this is in the GL state tracker, not the poor
1489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * driver.
1490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_MOV, result_dst, st_src_reg_for_float(0.5));
1492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_add:
1496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_ADD, result_dst, op[0], op[1]);
1497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_sub:
1499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_SUB, result_dst, op[0], op[1]);
1500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_mul:
1503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_MUL, result_dst, op[0], op[1]);
1504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_div:
1506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (result_dst.type == GLSL_TYPE_FLOAT)
1507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(!"not reached: should be handled by ir_div_to_mul_rcp");
1508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
1509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_DIV, result_dst, op[0], op[1]);
1510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_mod:
1512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (result_dst.type == GLSL_TYPE_FLOAT)
1513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(!"ir_binop_mod should have been converted to b * fract(a/b)");
1514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
1515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_MOD, result_dst, op[0], op[1]);
1516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_less:
1519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_SLT, result_dst, op[0], op[1]);
1520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_greater:
1522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_SLT, result_dst, op[1], op[0]);
1523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_lequal:
1525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_SGE, result_dst, op[1], op[0]);
1526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_gequal:
1528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_SGE, result_dst, op[0], op[1]);
1529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_equal:
1531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_SEQ, result_dst, op[0], op[1]);
1532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_nequal:
1534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], op[1]);
1535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_all_equal:
1537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* "==" operator producing a scalar boolean. */
1538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ir->operands[0]->type->is_vector() ||
1539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          ir->operands[1]->type->is_vector()) {
1540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         st_src_reg temp = get_temp(native_integers ?
1541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               glsl_type::get_instance(ir->operands[0]->type->base_type, 4, 1) :
1542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               glsl_type::vec4_type);
1543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (native_integers) {
1545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            st_dst_reg temp_dst = st_dst_reg(temp);
1546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            st_src_reg temp1 = st_src_reg(temp), temp2 = st_src_reg(temp);
1547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            emit(ir, TGSI_OPCODE_SEQ, st_dst_reg(temp), op[0], op[1]);
1549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* Emit 1-3 AND operations to combine the SEQ results. */
1551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            switch (ir->operands[0]->type->vector_elements) {
1552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case 2:
1553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               break;
1554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case 3:
1555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               temp_dst.writemask = WRITEMASK_Y;
1556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               temp1.swizzle = SWIZZLE_YYYY;
1557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               temp2.swizzle = SWIZZLE_ZZZZ;
1558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               emit(ir, TGSI_OPCODE_AND, temp_dst, temp1, temp2);
1559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               break;
1560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case 4:
1561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               temp_dst.writemask = WRITEMASK_X;
1562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               temp1.swizzle = SWIZZLE_XXXX;
1563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               temp2.swizzle = SWIZZLE_YYYY;
1564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               emit(ir, TGSI_OPCODE_AND, temp_dst, temp1, temp2);
1565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               temp_dst.writemask = WRITEMASK_Y;
1566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               temp1.swizzle = SWIZZLE_ZZZZ;
1567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               temp2.swizzle = SWIZZLE_WWWW;
1568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               emit(ir, TGSI_OPCODE_AND, temp_dst, temp1, temp2);
1569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            temp1.swizzle = SWIZZLE_XXXX;
1572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            temp2.swizzle = SWIZZLE_YYYY;
1573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            emit(ir, TGSI_OPCODE_AND, result_dst, temp1, temp2);
1574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         } else {
1575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            emit(ir, TGSI_OPCODE_SNE, st_dst_reg(temp), op[0], op[1]);
1576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* After the dot-product, the value will be an integer on the
1578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * range [0,4].  Zero becomes 1.0, and positive values become zero.
1579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             */
1580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            emit_dp(ir, result_dst, temp, temp, vector_elements);
1581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* Negating the result of the dot-product gives values on the range
1583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * [-4, 0].  Zero becomes 1.0, and negative values become zero.
1584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * This is achieved using SGE.
1585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             */
1586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            st_src_reg sge_src = result_src;
1587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sge_src.negate = ~sge_src.negate;
1588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            emit(ir, TGSI_OPCODE_SGE, result_dst, sge_src, st_src_reg_for_float(0.0));
1589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
1591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_SEQ, result_dst, op[0], op[1]);
1592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_any_nequal:
1595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* "!=" operator producing a scalar boolean. */
1596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ir->operands[0]->type->is_vector() ||
1597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          ir->operands[1]->type->is_vector()) {
1598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         st_src_reg temp = get_temp(native_integers ?
1599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               glsl_type::get_instance(ir->operands[0]->type->base_type, 4, 1) :
1600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               glsl_type::vec4_type);
1601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_SNE, st_dst_reg(temp), op[0], op[1]);
1602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (native_integers) {
1604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            st_dst_reg temp_dst = st_dst_reg(temp);
1605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            st_src_reg temp1 = st_src_reg(temp), temp2 = st_src_reg(temp);
1606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* Emit 1-3 OR operations to combine the SNE results. */
1608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            switch (ir->operands[0]->type->vector_elements) {
1609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case 2:
1610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               break;
1611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case 3:
1612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               temp_dst.writemask = WRITEMASK_Y;
1613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               temp1.swizzle = SWIZZLE_YYYY;
1614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               temp2.swizzle = SWIZZLE_ZZZZ;
1615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               emit(ir, TGSI_OPCODE_OR, temp_dst, temp1, temp2);
1616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               break;
1617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case 4:
1618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               temp_dst.writemask = WRITEMASK_X;
1619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               temp1.swizzle = SWIZZLE_XXXX;
1620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               temp2.swizzle = SWIZZLE_YYYY;
1621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               emit(ir, TGSI_OPCODE_OR, temp_dst, temp1, temp2);
1622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               temp_dst.writemask = WRITEMASK_Y;
1623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               temp1.swizzle = SWIZZLE_ZZZZ;
1624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               temp2.swizzle = SWIZZLE_WWWW;
1625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               emit(ir, TGSI_OPCODE_OR, temp_dst, temp1, temp2);
1626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            temp1.swizzle = SWIZZLE_XXXX;
1629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            temp2.swizzle = SWIZZLE_YYYY;
1630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            emit(ir, TGSI_OPCODE_OR, result_dst, temp1, temp2);
1631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         } else {
1632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* After the dot-product, the value will be an integer on the
1633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * range [0,4].  Zero stays zero, and positive values become 1.0.
1634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             */
1635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            glsl_to_tgsi_instruction *const dp =
1636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  emit_dp(ir, result_dst, temp, temp, vector_elements);
1637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
1638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               /* The clamping to [0,1] can be done for free in the fragment
1639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                * shader with a saturate.
1640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                */
1641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               dp->saturate = true;
1642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            } else {
1643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               /* Negating the result of the dot-product gives values on the range
1644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                * [-4, 0].  Zero stays zero, and negative values become 1.0.  This
1645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                * achieved using SLT.
1646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                */
1647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               st_src_reg slt_src = result_src;
1648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               slt_src.negate = ~slt_src.negate;
1649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               emit(ir, TGSI_OPCODE_SLT, result_dst, slt_src, st_src_reg_for_float(0.0));
1650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
1653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], op[1]);
1654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_any: {
1658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type->is_vector());
1659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* After the dot-product, the value will be an integer on the
1661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * range [0,4].  Zero stays zero, and positive values become 1.0.
1662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      glsl_to_tgsi_instruction *const dp =
1664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit_dp(ir, result_dst, op[0], op[0],
1665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 ir->operands[0]->type->vector_elements);
1666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB &&
1667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          result_dst.type == GLSL_TYPE_FLOAT) {
1668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      /* The clamping to [0,1] can be done for free in the fragment
1669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       * shader with a saturate.
1670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       */
1671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      dp->saturate = true;
1672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else if (result_dst.type == GLSL_TYPE_FLOAT) {
1673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      /* Negating the result of the dot-product gives values on the range
1674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       * [-4, 0].  Zero stays zero, and negative values become 1.0.  This
1675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       * is achieved using SLT.
1676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       */
1677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      st_src_reg slt_src = result_src;
1678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      slt_src.negate = ~slt_src.negate;
1679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      emit(ir, TGSI_OPCODE_SLT, result_dst, slt_src, st_src_reg_for_float(0.0));
1680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
1682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Use SNE 0 if integers are being used as boolean values. */
1683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_SNE, result_dst, result_src, st_src_reg_for_int(0));
1684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_logic_xor:
1689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (native_integers)
1690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_XOR, result_dst, op[0], op[1]);
1691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
1692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], op[1]);
1693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_logic_or: {
1696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (native_integers) {
1697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* If integers are used as booleans, we can use an actual "or"
1698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * instruction.
1699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
1700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(native_integers);
1701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_OR, result_dst, op[0], op[1]);
1702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
1703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* After the addition, the value will be an integer on the
1704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * range [0,2].  Zero stays zero, and positive values become 1.0.
1705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
1706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         glsl_to_tgsi_instruction *add =
1707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            emit(ir, TGSI_OPCODE_ADD, result_dst, op[0], op[1]);
1708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
1709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* The clamping to [0,1] can be done for free in the fragment
1710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * shader with a saturate if floats are being used as boolean values.
1711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             */
1712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            add->saturate = true;
1713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         } else {
1714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* Negating the result of the addition gives values on the range
1715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * [-2, 0].  Zero stays zero, and negative values become 1.0.  This
1716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * is achieved using SLT.
1717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             */
1718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            st_src_reg slt_src = result_src;
1719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            slt_src.negate = ~slt_src.negate;
1720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            emit(ir, TGSI_OPCODE_SLT, result_dst, slt_src, st_src_reg_for_float(0.0));
1721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_logic_and:
1727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* If native integers are disabled, the bool args are stored as float 0.0
1728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * or 1.0, so "mul" gives us "and".  If they're enabled, just use the
1729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * actual AND opcode.
1730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (native_integers)
1732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_AND, result_dst, op[0], op[1]);
1733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
1734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_MUL, result_dst, op[0], op[1]);
1735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_dot:
1738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type->is_vector());
1739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type == ir->operands[1]->type);
1740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit_dp(ir, result_dst, op[0], op[1],
1741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              ir->operands[0]->type->vector_elements);
1742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_sqrt:
1745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* sqrt(x) = x * rsq(x). */
1746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit_scalar(ir, TGSI_OPCODE_RSQ, result_dst, op[0]);
1747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_MUL, result_dst, result_src, op[0]);
1748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* For incoming channels <= 0, set the result to 0. */
1749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[0].negate = ~op[0].negate;
1750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_CMP, result_dst,
1751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		  op[0], result_src, st_src_reg_for_float(0.0));
1752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_rsq:
1754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit_scalar(ir, TGSI_OPCODE_RSQ, result_dst, op[0]);
1755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_i2f:
1757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (native_integers) {
1758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_I2F, result_dst, op[0]);
1759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* fallthrough to next case otherwise */
1762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_b2f:
1763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (native_integers) {
1764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_AND, result_dst, op[0], st_src_reg_for_float(1.0));
1765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* fallthrough to next case otherwise */
1768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_i2u:
1769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_u2i:
1770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Converting between signed and unsigned integers is a no-op. */
1771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result_src = op[0];
1772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_b2i:
1774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (native_integers) {
1775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Booleans are stored as integers using ~0 for true and 0 for false.
1776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * GLSL requires that int(bool) return 1 for true and 0 for false.
1777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * This conversion is done with AND, but it could be done with NEG.
1778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
1779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_AND, result_dst, op[0], st_src_reg_for_int(1));
1780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
1781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Booleans and integers are both stored as floats when native
1782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * integers are disabled.
1783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
1784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         result_src = op[0];
1785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_f2i:
1788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (native_integers)
1789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_F2I, result_dst, op[0]);
1790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
1791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_TRUNC, result_dst, op[0]);
1792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_f2u:
1794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (native_integers)
1795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_F2U, result_dst, op[0]);
1796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
1797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_TRUNC, result_dst, op[0]);
1798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_bitcast_f2i:
1800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_bitcast_f2u:
1801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_bitcast_i2f:
1802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_bitcast_u2f:
1803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result_src = op[0];
1804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_f2b:
1806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], st_src_reg_for_float(0.0));
1807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_i2b:
1809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (native_integers)
1810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_INEG, result_dst, op[0]);
1811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
1812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], st_src_reg_for_float(0.0));
1813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_trunc:
1815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_TRUNC, result_dst, op[0]);
1816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_ceil:
1818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_CEIL, result_dst, op[0]);
1819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_floor:
1821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_FLR, result_dst, op[0]);
1822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_round_even:
1824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_ROUND, result_dst, op[0]);
1825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_fract:
1827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_FRC, result_dst, op[0]);
1828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_min:
1831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_MIN, result_dst, op[0], op[1]);
1832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_max:
1834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_MAX, result_dst, op[0], op[1]);
1835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_pow:
1837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit_scalar(ir, TGSI_OPCODE_POW, result_dst, op[0], op[1]);
1838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_bit_not:
1841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (native_integers) {
1842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_NOT, result_dst, op[0]);
1843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_u2f:
1846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (native_integers) {
1847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_U2F, result_dst, op[0]);
1848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_lshift:
1851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (native_integers) {
1852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_SHL, result_dst, op[0], op[1]);
1853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_rshift:
1856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (native_integers) {
1857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_ISHR, result_dst, op[0], op[1]);
1858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_bit_and:
1861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (native_integers) {
1862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_AND, result_dst, op[0], op[1]);
1863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_bit_xor:
1866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (native_integers) {
1867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_XOR, result_dst, op[0], op[1]);
1868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_bit_or:
1871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (native_integers) {
1872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_OR, result_dst, op[0], op[1]);
1873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(!"GLSL 1.30 features unsupported");
1877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_ubo_load:
1880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(!"not yet supported");
1881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_quadop_vector:
1884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* This operation should have already been handled.
1885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(!"Should not get here.");
1887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->result = result_src;
1891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
1895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_swizzle *ir)
1896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_src_reg src;
1898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
1899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int swizzle[4];
1900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Note that this is only swizzles in expressions, not those on the left
1902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * hand side of an assignment, which do write masking.  See ir_assignment
1903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * for that.
1904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir->val->accept(this);
1907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src = this->result;
1908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(src.file != PROGRAM_UNDEFINED);
1909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < 4; i++) {
1911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (i < ir->type->vector_elements) {
1912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         switch (i) {
1913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         case 0:
1914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            swizzle[i] = GET_SWZ(src.swizzle, ir->mask.x);
1915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
1916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         case 1:
1917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            swizzle[i] = GET_SWZ(src.swizzle, ir->mask.y);
1918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
1919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         case 2:
1920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            swizzle[i] = GET_SWZ(src.swizzle, ir->mask.z);
1921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
1922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         case 3:
1923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            swizzle[i] = GET_SWZ(src.swizzle, ir->mask.w);
1924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
1925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
1927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* If the type is smaller than a vec4, replicate the last
1928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * channel out.
1929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
1930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         swizzle[i] = swizzle[ir->type->vector_elements - 1];
1931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], swizzle[2], swizzle[3]);
1935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->result = src;
1937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
1940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_dereference_variable *ir)
1941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   variable_storage *entry = find_variable_storage(ir->var);
1943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_variable *var = ir->var;
1944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!entry) {
1946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (var->mode) {
1947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case ir_var_uniform:
1948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         entry = new(mem_ctx) variable_storage(var, PROGRAM_UNIFORM,
1949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        				       var->location);
1950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         this->variables.push_tail(entry);
1951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case ir_var_in:
1953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case ir_var_inout:
1954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* The linker assigns locations for varyings and attributes,
1955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * including deprecated builtins (like gl_Color), user-assign
1956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * generic attributes (glBindVertexLocation), and
1957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * user-defined varyings.
1958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          *
1959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * FINISHME: We would hit this path for function arguments.  Fix!
1960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
1961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(var->location != -1);
1962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         entry = new(mem_ctx) variable_storage(var,
1963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               PROGRAM_INPUT,
1964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               var->location);
1965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case ir_var_out:
1967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(var->location != -1);
1968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         entry = new(mem_ctx) variable_storage(var,
1969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               PROGRAM_OUTPUT,
1970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               var->location + var->index);
1971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case ir_var_system_value:
1973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         entry = new(mem_ctx) variable_storage(var,
1974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               PROGRAM_SYSTEM_VALUE,
1975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               var->location);
1976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case ir_var_auto:
1978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case ir_var_temporary:
1979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         entry = new(mem_ctx) variable_storage(var, PROGRAM_TEMPORARY,
1980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        				       this->next_temp);
1981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         this->variables.push_tail(entry);
1982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         next_temp += type_size(var->type);
1984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!entry) {
1988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         printf("Failed to make storage for %s\n", var->name);
1989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         exit(1);
1990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->result = st_src_reg(entry->file, entry->index, var->type);
1994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!native_integers)
1995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->result.type = GLSL_TYPE_FLOAT;
1996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
1999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_dereference_array *ir)
2000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_constant *index;
2002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_src_reg src;
2003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int element_size = type_size(ir->type);
2004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   index = ir->array_index->constant_expression_value();
2006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir->array->accept(this);
2008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src = this->result;
2009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (index) {
2011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src.index += index->value.i[0] * element_size;
2012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
2013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Variable index array dereference.  It eats the "vec4" of the
2014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * base of the array and an index that offsets the TGSI register
2015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * index.
2016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir->array_index->accept(this);
2018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      st_src_reg index_reg;
2020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (element_size == 1) {
2022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         index_reg = this->result;
2023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
2024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         index_reg = get_temp(native_integers ?
2025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              glsl_type::int_type : glsl_type::float_type);
2026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_MUL, st_dst_reg(index_reg),
2028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              this->result, st_src_reg_for_type(index_reg.type, element_size));
2029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* If there was already a relative address register involved, add the
2032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * new and the old together to get the new offset.
2033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (src.reladdr != NULL) {
2035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         st_src_reg accum_reg = get_temp(native_integers ?
2036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                glsl_type::int_type : glsl_type::float_type);
2037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_ADD, st_dst_reg(accum_reg),
2039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              index_reg, *src.reladdr);
2040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         index_reg = accum_reg;
2042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src.reladdr = ralloc(mem_ctx, st_src_reg);
2045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      memcpy(src.reladdr, &index_reg, sizeof(index_reg));
2046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* If the type is smaller than a vec4, replicate the last channel out. */
2049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->type->is_scalar() || ir->type->is_vector())
2050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src.swizzle = swizzle_for_size(ir->type->vector_elements);
2051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
2052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src.swizzle = SWIZZLE_NOOP;
2053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Change the register type to the element type of the array. */
2055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src.type = ir->type->base_type;
2056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->result = src;
2058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
2061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_dereference_record *ir)
2062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned int i;
2064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const glsl_type *struct_type = ir->record->type;
2065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int offset = 0;
2066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir->record->accept(this);
2068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < struct_type->length; i++) {
2070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0)
2071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
2072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      offset += type_size(struct_type->fields.structure[i].type);
2073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* If the type is smaller than a vec4, replicate the last channel out. */
2076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->type->is_scalar() || ir->type->is_vector())
2077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->result.swizzle = swizzle_for_size(ir->type->vector_elements);
2078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
2079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->result.swizzle = SWIZZLE_NOOP;
2080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->result.index += offset;
2082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->result.type = ir->type->base_type;
2083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
2086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * We want to be careful in assignment setup to hit the actual storage
2087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * instead of potentially using a temporary like we might with the
2088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ir_dereference handler.
2089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
2090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic st_dst_reg
2091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_assignment_lhs(ir_dereference *ir, glsl_to_tgsi_visitor *v)
2092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* The LHS must be a dereference.  If the LHS is a variable indexed array
2094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * access of a vector, it must be separated into a series conditional moves
2095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * before reaching this point (see ir_vec_index_to_cond_assign).
2096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(ir->as_dereference());
2098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_dereference_array *deref_array = ir->as_dereference_array();
2099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (deref_array) {
2100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(!deref_array->array->type->is_vector());
2101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Use the rvalue deref handler for the most part.  We'll ignore
2104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * swizzles in it and write swizzles using writemask, though.
2105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir->accept(v);
2107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return st_dst_reg(v->result);
2108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
2111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Process the condition of a conditional assignment
2112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
2113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Examines the condition of a conditional assignment to generate the optimal
2114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * first operand of a \c CMP instruction.  If the condition is a relational
2115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * operator with 0 (e.g., \c ir_binop_less), the value being compared will be
2116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * used as the source for the \c CMP instruction.  Otherwise the comparison
2117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is processed to a boolean result, and the boolean result is used as the
2118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * operand to the CMP instruction.
2119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
2120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool
2121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::process_move_condition(ir_rvalue *ir)
2122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_rvalue *src_ir = ir;
2124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bool negate = true;
2125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bool switch_order = false;
2126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_expression *const expr = ir->as_expression();
2128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if ((expr != NULL) && (expr->get_num_operands() == 2)) {
2129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      bool zero_on_left = false;
2130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (expr->operands[0]->is_zero()) {
2132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         src_ir = expr->operands[1];
2133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         zero_on_left = true;
2134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else if (expr->operands[1]->is_zero()) {
2135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         src_ir = expr->operands[0];
2136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         zero_on_left = false;
2137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*      a is -  0  +            -  0  +
2140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * (a <  0)  T  F  F  ( a < 0)  T  F  F
2141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * (0 <  a)  F  F  T  (-a < 0)  F  F  T
2142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * (a <= 0)  T  T  F  (-a < 0)  F  F  T  (swap order of other operands)
2143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * (0 <= a)  F  T  T  ( a < 0)  T  F  F  (swap order of other operands)
2144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * (a >  0)  F  F  T  (-a < 0)  F  F  T
2145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * (0 >  a)  T  F  F  ( a < 0)  T  F  F
2146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * (a >= 0)  F  T  T  ( a < 0)  T  F  F  (swap order of other operands)
2147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * (0 >= a)  T  T  F  (-a < 0)  F  F  T  (swap order of other operands)
2148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
2149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Note that exchanging the order of 0 and 'a' in the comparison simply
2150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * means that the value of 'a' should be negated.
2151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (src_ir != ir) {
2153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         switch (expr->operation) {
2154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         case ir_binop_less:
2155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            switch_order = false;
2156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            negate = zero_on_left;
2157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
2158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         case ir_binop_greater:
2160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            switch_order = false;
2161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            negate = !zero_on_left;
2162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
2163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         case ir_binop_lequal:
2165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            switch_order = true;
2166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            negate = !zero_on_left;
2167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
2168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         case ir_binop_gequal:
2170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            switch_order = true;
2171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            negate = zero_on_left;
2172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
2173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         default:
2175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* This isn't the right kind of comparison afterall, so make sure
2176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * the whole condition is visited.
2177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             */
2178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            src_ir = ir;
2179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
2180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
2181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src_ir->accept(this);
2185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* We use the TGSI_OPCODE_CMP (a < 0 ? b : c) for conditional moves, and the
2187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * condition we produced is 0.0 or 1.0.  By flipping the sign, we can
2188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * choose which value TGSI_OPCODE_CMP produces without an extra instruction
2189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * computing the condition.
2190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (negate)
2192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->result.negate = ~this->result.negate;
2193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return switch_order;
2195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
2198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_assignment *ir)
2199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_dst_reg l;
2201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_src_reg r;
2202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
2203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir->rhs->accept(this);
2205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   r = this->result;
2206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   l = get_assignment_lhs(ir->lhs, this);
2208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* FINISHME: This should really set to the correct maximal writemask for each
2210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * FINISHME: component written (in the loops below).  This case can only
2211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * FINISHME: occur for matrices, arrays, and structures.
2212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->write_mask == 0) {
2214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(!ir->lhs->type->is_scalar() && !ir->lhs->type->is_vector());
2215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      l.writemask = WRITEMASK_XYZW;
2216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else if (ir->lhs->type->is_scalar() &&
2217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              ir->lhs->variable_referenced()->mode == ir_var_out) {
2218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* FINISHME: This hack makes writing to gl_FragDepth, which lives in the
2219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * FINISHME: W component of fragment shader output zero, work correctly.
2220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      l.writemask = WRITEMASK_XYZW;
2222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
2223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int swizzles[4];
2224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int first_enabled_chan = 0;
2225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int rhs_chan = 0;
2226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      l.writemask = ir->write_mask;
2228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (int i = 0; i < 4; i++) {
2230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (l.writemask & (1 << i)) {
2231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            first_enabled_chan = GET_SWZ(r.swizzle, i);
2232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
2233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
2234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Swizzle a small RHS vector into the channels being written.
2237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
2238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * glsl ir treats write_mask as dictating how many channels are
2239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * present on the RHS while TGSI treats write_mask as just
2240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * showing which channels of the vec4 RHS get written.
2241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (int i = 0; i < 4; i++) {
2243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (l.writemask & (1 << i))
2244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            swizzles[i] = GET_SWZ(r.swizzle, rhs_chan++);
2245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else
2246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            swizzles[i] = first_enabled_chan;
2247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      r.swizzle = MAKE_SWIZZLE4(swizzles[0], swizzles[1],
2249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        			swizzles[2], swizzles[3]);
2250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(l.file != PROGRAM_UNDEFINED);
2253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(r.file != PROGRAM_UNDEFINED);
2254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->condition) {
2256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const bool switch_order = this->process_move_condition(ir->condition);
2257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      st_src_reg condition = this->result;
2258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < type_size(ir->lhs->type); i++) {
2260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         st_src_reg l_src = st_src_reg(l);
2261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         st_src_reg condition_temp = condition;
2262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         l_src.swizzle = swizzle_for_size(ir->lhs->type->vector_elements);
2263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (native_integers) {
2265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* This is necessary because TGSI's CMP instruction expects the
2266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * condition to be a float, and we store booleans as integers.
2267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * If TGSI had a UCMP instruction or similar, this extra
2268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * instruction would not be necessary.
2269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             */
2270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            condition_temp = get_temp(glsl_type::vec4_type);
2271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            condition.negate = 0;
2272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            emit(ir, TGSI_OPCODE_I2F, st_dst_reg(condition_temp), condition);
2273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            condition_temp.swizzle = condition.swizzle;
2274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
2275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (switch_order) {
2277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            emit(ir, TGSI_OPCODE_CMP, l, condition_temp, l_src, r);
2278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         } else {
2279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            emit(ir, TGSI_OPCODE_CMP, l, condition_temp, r, l_src);
2280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
2281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         l.index++;
2283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         r.index++;
2284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else if (ir->rhs->as_expression() &&
2286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              this->instructions.get_tail() &&
2287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              ir->rhs == ((glsl_to_tgsi_instruction *)this->instructions.get_tail())->ir &&
2288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              type_size(ir->lhs->type) == 1 &&
2289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              l.writemask == ((glsl_to_tgsi_instruction *)this->instructions.get_tail())->dst.writemask) {
2290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* To avoid emitting an extra MOV when assigning an expression to a
2291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * variable, emit the last instruction of the expression again, but
2292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * replace the destination register with the target of the assignment.
2293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Dead code elimination will remove the original instruction.
2294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      glsl_to_tgsi_instruction *inst, *new_inst;
2296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst = (glsl_to_tgsi_instruction *)this->instructions.get_tail();
2297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      new_inst = emit(ir, inst->op, l, inst->src[0], inst->src[1], inst->src[2]);
2298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      new_inst->saturate = inst->saturate;
2299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst->dead_mask = inst->dst.writemask;
2300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
2301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < type_size(ir->lhs->type); i++) {
2302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (ir->rhs->type->is_array())
2303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         	r.type = ir->rhs->type->element_type()->base_type;
2304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else if (ir->rhs->type->is_record())
2305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         	r.type = ir->rhs->type->fields.structure[i].type->base_type;
2306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_MOV, l, r);
2307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         l.index++;
2308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         r.index++;
2309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
2315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_constant *ir)
2316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_src_reg src;
2318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat stack_vals[4] = { 0 };
2319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gl_constant_value *values = (gl_constant_value *) stack_vals;
2320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLenum gl_type = GL_NONE;
2321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned int i;
2322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   static int in_array = 0;
2323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gl_register_file file = in_array ? PROGRAM_CONSTANT : PROGRAM_IMMEDIATE;
2324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Unfortunately, 4 floats is all we can get into
2326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * _mesa_add_typed_unnamed_constant.  So, make a temp to store an
2327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * aggregate constant and move each constant value into it.  If we
2328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * get lucky, copy propagation will eliminate the extra moves.
2329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->type->base_type == GLSL_TYPE_STRUCT) {
2331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      st_src_reg temp_base = get_temp(ir->type);
2332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      st_dst_reg temp = st_dst_reg(temp_base);
2333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      foreach_iter(exec_list_iterator, iter, ir->components) {
2335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ir_constant *field_value = (ir_constant *)iter.get();
2336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         int size = type_size(field_value->type);
2337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(size > 0);
2339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         field_value->accept(this);
2341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         src = this->result;
2342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 0; i < (unsigned int)size; i++) {
2344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            emit(ir, TGSI_OPCODE_MOV, temp, src);
2345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            src.index++;
2347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            temp.index++;
2348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
2349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->result = temp_base;
2351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
2352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->type->is_array()) {
2355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      st_src_reg temp_base = get_temp(ir->type);
2356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      st_dst_reg temp = st_dst_reg(temp_base);
2357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int size = type_size(ir->type->fields.array);
2358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(size > 0);
2360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      in_array++;
2361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < ir->type->length; i++) {
2363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ir->array_elements[i]->accept(this);
2364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         src = this->result;
2365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (int j = 0; j < size; j++) {
2366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            emit(ir, TGSI_OPCODE_MOV, temp, src);
2367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            src.index++;
2369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            temp.index++;
2370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
2371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->result = temp_base;
2373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      in_array--;
2374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
2375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->type->is_matrix()) {
2378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      st_src_reg mat = get_temp(ir->type);
2379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      st_dst_reg mat_column = st_dst_reg(mat);
2380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < ir->type->matrix_columns; i++) {
2382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(ir->type->base_type == GLSL_TYPE_FLOAT);
2383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         values = (gl_constant_value *) &ir->value.f[i * ir->type->vector_elements];
2384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         src = st_src_reg(file, -1, ir->type->base_type);
2386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         src.index = add_constant(file,
2387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  values,
2388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  ir->type->vector_elements,
2389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  GL_FLOAT,
2390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  &src.swizzle);
2391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_MOV, mat_column, src);
2392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         mat_column.index++;
2394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->result = mat;
2397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
2398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (ir->type->base_type) {
2401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_TYPE_FLOAT:
2402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      gl_type = GL_FLOAT;
2403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < ir->type->vector_elements; i++) {
2404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         values[i].f = ir->value.f[i];
2405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_TYPE_UINT:
2408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      gl_type = native_integers ? GL_UNSIGNED_INT : GL_FLOAT;
2409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < ir->type->vector_elements; i++) {
2410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (native_integers)
2411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            values[i].u = ir->value.u[i];
2412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else
2413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            values[i].f = ir->value.u[i];
2414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_TYPE_INT:
2417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      gl_type = native_integers ? GL_INT : GL_FLOAT;
2418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < ir->type->vector_elements; i++) {
2419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (native_integers)
2420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            values[i].i = ir->value.i[i];
2421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else
2422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            values[i].f = ir->value.i[i];
2423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_TYPE_BOOL:
2426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      gl_type = native_integers ? GL_BOOL : GL_FLOAT;
2427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < ir->type->vector_elements; i++) {
2428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (native_integers)
2429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            values[i].u = ir->value.b[i] ? ~0 : 0;
2430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else
2431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            values[i].f = ir->value.b[i];
2432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
2435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(!"Non-float/uint/int/bool constant");
2436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->result = st_src_reg(file, -1, ir->type);
2439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->result.index = add_constant(file,
2440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     values,
2441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     ir->type->vector_elements,
2442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     gl_type,
2443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     &this->result.swizzle);
2444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfunction_entry *
2447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::get_function_signature(ir_function_signature *sig)
2448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   function_entry *entry;
2450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_iter(exec_list_iterator, iter, this->function_signatures) {
2452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      entry = (function_entry *)iter.get();
2453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (entry->sig == sig)
2455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return entry;
2456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   entry = ralloc(mem_ctx, function_entry);
2459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   entry->sig = sig;
2460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   entry->sig_id = this->next_signature_id++;
2461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   entry->bgn_inst = NULL;
2462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Allocate storage for all the parameters. */
2464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_iter(exec_list_iterator, iter, sig->parameters) {
2465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_variable *param = (ir_variable *)iter.get();
2466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      variable_storage *storage;
2467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      storage = find_variable_storage(param);
2469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(!storage);
2470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      storage = new(mem_ctx) variable_storage(param, PROGRAM_TEMPORARY,
2472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        				      this->next_temp);
2473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->variables.push_tail(storage);
2474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->next_temp += type_size(param->type);
2476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!sig->return_type->is_void()) {
2479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      entry->return_reg = get_temp(sig->return_type);
2480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
2481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      entry->return_reg = undef_src;
2482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->function_signatures.push_tail(entry);
2485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return entry;
2486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
2489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_call *ir)
2490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glsl_to_tgsi_instruction *call_inst;
2492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_function_signature *sig = ir->callee;
2493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   function_entry *entry = get_function_signature(sig);
2494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
2495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Process in parameters. */
2497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   exec_list_iterator sig_iter = sig->parameters.iterator();
2498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_iter(exec_list_iterator, iter, *ir) {
2499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_rvalue *param_rval = (ir_rvalue *)iter.get();
2500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_variable *param = (ir_variable *)sig_iter.get();
2501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (param->mode == ir_var_in ||
2503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          param->mode == ir_var_inout) {
2504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         variable_storage *storage = find_variable_storage(param);
2505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(storage);
2506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         param_rval->accept(this);
2508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         st_src_reg r = this->result;
2509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         st_dst_reg l;
2511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         l.file = storage->file;
2512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         l.index = storage->index;
2513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         l.reladdr = NULL;
2514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         l.writemask = WRITEMASK_XYZW;
2515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         l.cond_mask = COND_TR;
2516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 0; i < type_size(param->type); i++) {
2518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            emit(ir, TGSI_OPCODE_MOV, l, r);
2519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            l.index++;
2520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            r.index++;
2521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
2522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sig_iter.next();
2525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(!sig_iter.has_next());
2527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Emit call instruction */
2529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   call_inst = emit(ir, TGSI_OPCODE_CAL);
2530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   call_inst->function = entry;
2531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Process out parameters. */
2533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sig_iter = sig->parameters.iterator();
2534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_iter(exec_list_iterator, iter, *ir) {
2535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_rvalue *param_rval = (ir_rvalue *)iter.get();
2536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_variable *param = (ir_variable *)sig_iter.get();
2537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (param->mode == ir_var_out ||
2539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          param->mode == ir_var_inout) {
2540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         variable_storage *storage = find_variable_storage(param);
2541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(storage);
2542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         st_src_reg r;
2544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         r.file = storage->file;
2545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         r.index = storage->index;
2546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         r.reladdr = NULL;
2547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         r.swizzle = SWIZZLE_NOOP;
2548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         r.negate = 0;
2549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         param_rval->accept(this);
2551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         st_dst_reg l = st_dst_reg(this->result);
2552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 0; i < type_size(param->type); i++) {
2554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            emit(ir, TGSI_OPCODE_MOV, l, r);
2555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            l.index++;
2556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            r.index++;
2557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
2558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sig_iter.next();
2561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(!sig_iter.has_next());
2563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Process return value. */
2565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->result = entry->return_reg;
2566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
2569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_texture *ir)
2570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_src_reg result_src, coord, lod_info, projector, dx, dy, offset;
2572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_dst_reg result_dst, coord_dst;
2573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glsl_to_tgsi_instruction *inst = NULL;
2574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned opcode = TGSI_OPCODE_NOP;
2575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->coordinate) {
2577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir->coordinate->accept(this);
2578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Put our coords in a temp.  We'll need to modify them for shadow,
2580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * projection, or LOD, so the only case we'd use it as is is if
2581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * we're doing plain old texturing.  The optimization passes on
2582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * glsl_to_tgsi_visitor should handle cleaning up our mess in that case.
2583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      coord = get_temp(glsl_type::vec4_type);
2585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      coord_dst = st_dst_reg(coord);
2586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_MOV, coord_dst, this->result);
2587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->projector) {
2590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir->projector->accept(this);
2591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      projector = this->result;
2592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Storage for our result.  Ideally for an assignment we'd be using
2595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * the actual storage for the result here, instead.
2596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   result_src = get_temp(ir->type);
2598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   result_dst = st_dst_reg(result_src);
2599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (ir->op) {
2601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_tex:
2602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      opcode = TGSI_OPCODE_TEX;
2603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_txb:
2605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      opcode = TGSI_OPCODE_TXB;
2606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir->lod_info.bias->accept(this);
2607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lod_info = this->result;
2608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_txl:
2610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      opcode = TGSI_OPCODE_TXL;
2611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir->lod_info.lod->accept(this);
2612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lod_info = this->result;
2613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_txd:
2615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      opcode = TGSI_OPCODE_TXD;
2616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir->lod_info.grad.dPdx->accept(this);
2617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dx = this->result;
2618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir->lod_info.grad.dPdy->accept(this);
2619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dy = this->result;
2620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_txs:
2622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      opcode = TGSI_OPCODE_TXQ;
2623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir->lod_info.lod->accept(this);
2624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lod_info = this->result;
2625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_txf:
2627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      opcode = TGSI_OPCODE_TXF;
2628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir->lod_info.lod->accept(this);
2629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lod_info = this->result;
2630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ir->offset) {
2631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir->offset->accept(this);
2632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 offset = this->result;
2633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const glsl_type *sampler_type = ir->sampler->type;
2638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->projector) {
2640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (opcode == TGSI_OPCODE_TEX) {
2641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Slot the projector in as the last component of the coord. */
2642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         coord_dst.writemask = WRITEMASK_W;
2643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_MOV, coord_dst, projector);
2644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         coord_dst.writemask = WRITEMASK_XYZW;
2645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         opcode = TGSI_OPCODE_TXP;
2646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
2647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         st_src_reg coord_w = coord;
2648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         coord_w.swizzle = SWIZZLE_WWWW;
2649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* For the other TEX opcodes there's no projective version
2651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * since the last slot is taken up by LOD info.  Do the
2652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * projective divide now.
2653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
2654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         coord_dst.writemask = WRITEMASK_W;
2655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_RCP, coord_dst, projector);
2656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* In the case where we have to project the coordinates "by hand,"
2658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * the shadow comparator value must also be projected.
2659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
2660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         st_src_reg tmp_src = coord;
2661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (ir->shadow_comparitor) {
2662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* Slot the shadow value in as the second to last component of the
2663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * coord.
2664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             */
2665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            ir->shadow_comparitor->accept(this);
2666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            tmp_src = get_temp(glsl_type::vec4_type);
2668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            st_dst_reg tmp_dst = st_dst_reg(tmp_src);
2669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    /* Projective division not allowed for array samplers. */
2671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    assert(!sampler_type->sampler_array);
2672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            tmp_dst.writemask = WRITEMASK_Z;
2674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            emit(ir, TGSI_OPCODE_MOV, tmp_dst, this->result);
2675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            tmp_dst.writemask = WRITEMASK_XY;
2677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            emit(ir, TGSI_OPCODE_MOV, tmp_dst, coord);
2678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
2679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         coord_dst.writemask = WRITEMASK_XYZ;
2681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_MUL, coord_dst, tmp_src, coord_w);
2682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         coord_dst.writemask = WRITEMASK_XYZW;
2684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         coord.swizzle = SWIZZLE_XYZW;
2685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* If projection is done and the opcode is not TGSI_OPCODE_TXP, then the shadow
2689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * comparator was put in the correct place (and projected) by the code,
2690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * above, that handles by-hand projection.
2691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->shadow_comparitor && (!ir->projector || opcode == TGSI_OPCODE_TXP)) {
2693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Slot the shadow value in as the second to last component of the
2694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * coord.
2695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir->shadow_comparitor->accept(this);
2697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* XXX This will need to be updated for cubemap array samplers. */
2699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if ((sampler_type->sampler_dimensionality == GLSL_SAMPLER_DIM_2D &&
2700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   sampler_type->sampler_array) ||
2701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  sampler_type->sampler_dimensionality == GLSL_SAMPLER_DIM_CUBE) {
2702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         coord_dst.writemask = WRITEMASK_W;
2703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
2704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         coord_dst.writemask = WRITEMASK_Z;
2705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_MOV, coord_dst, this->result);
2708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      coord_dst.writemask = WRITEMASK_XYZW;
2709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (opcode == TGSI_OPCODE_TXL || opcode == TGSI_OPCODE_TXB ||
2712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       opcode == TGSI_OPCODE_TXF) {
2713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* TGSI stores LOD or LOD bias in the last channel of the coords. */
2714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      coord_dst.writemask = WRITEMASK_W;
2715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_MOV, coord_dst, lod_info);
2716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      coord_dst.writemask = WRITEMASK_XYZW;
2717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (opcode == TGSI_OPCODE_TXD)
2720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst = emit(ir, opcode, result_dst, coord, dx, dy);
2721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (opcode == TGSI_OPCODE_TXQ)
2722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst = emit(ir, opcode, result_dst, lod_info);
2723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (opcode == TGSI_OPCODE_TXF) {
2724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst = emit(ir, opcode, result_dst, coord);
2725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else
2726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst = emit(ir, opcode, result_dst, coord);
2727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->shadow_comparitor)
2729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst->tex_shadow = GL_TRUE;
2730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   inst->sampler = _mesa_get_sampler_uniform_value(ir->sampler,
2732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        					   this->shader_program,
2733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        					   this->prog);
2734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->offset) {
2736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       inst->tex_offset_num_offset = 1;
2737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       inst->tex_offsets[0].Index = offset.index;
2738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       inst->tex_offsets[0].File = offset.file;
2739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       inst->tex_offsets[0].SwizzleX = GET_SWZ(offset.swizzle, 0);
2740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       inst->tex_offsets[0].SwizzleY = GET_SWZ(offset.swizzle, 1);
2741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       inst->tex_offsets[0].SwizzleZ = GET_SWZ(offset.swizzle, 2);
2742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (sampler_type->sampler_dimensionality) {
2745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_SAMPLER_DIM_1D:
2746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst->tex_target = (sampler_type->sampler_array)
2747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ? TEXTURE_1D_ARRAY_INDEX : TEXTURE_1D_INDEX;
2748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_SAMPLER_DIM_2D:
2750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst->tex_target = (sampler_type->sampler_array)
2751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ? TEXTURE_2D_ARRAY_INDEX : TEXTURE_2D_INDEX;
2752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_SAMPLER_DIM_3D:
2754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst->tex_target = TEXTURE_3D_INDEX;
2755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_SAMPLER_DIM_CUBE:
2757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst->tex_target = TEXTURE_CUBE_INDEX;
2758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_SAMPLER_DIM_RECT:
2760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst->tex_target = TEXTURE_RECT_INDEX;
2761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_SAMPLER_DIM_BUF:
2763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(!"FINISHME: Implement ARB_texture_buffer_object");
2764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GLSL_SAMPLER_DIM_EXTERNAL:
2766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst->tex_target = TEXTURE_EXTERNAL_INDEX;
2767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
2769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(!"Should not get here.");
2770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->result = result_src;
2773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
2776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_return *ir)
2777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->get_value()) {
2779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      st_dst_reg l;
2780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int i;
2781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(current_function);
2783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir->get_value()->accept(this);
2785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      st_src_reg r = this->result;
2786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      l = st_dst_reg(current_function->return_reg);
2788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < type_size(current_function->sig->return_type); i++) {
2790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit(ir, TGSI_OPCODE_MOV, l, r);
2791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         l.index++;
2792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         r.index++;
2793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit(ir, TGSI_OPCODE_RET);
2797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
2800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_discard *ir)
2801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->condition) {
2803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir->condition->accept(this);
2804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->result.negate = ~this->result.negate;
2805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_KIL, undef_dst, this->result);
2806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
2807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir, TGSI_OPCODE_KILP);
2808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
2812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_if *ir)
2813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glsl_to_tgsi_instruction *cond_inst, *if_inst;
2815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glsl_to_tgsi_instruction *prev_inst;
2816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   prev_inst = (glsl_to_tgsi_instruction *)this->instructions.get_tail();
2818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir->condition->accept(this);
2820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(this->result.file != PROGRAM_UNDEFINED);
2821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (this->options->EmitCondCodes) {
2823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      cond_inst = (glsl_to_tgsi_instruction *)this->instructions.get_tail();
2824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* See if we actually generated any instruction for generating
2826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * the condition.  If not, then cook up a move to a temp so we
2827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * have something to set cond_update on.
2828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
2829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (cond_inst == prev_inst) {
2830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         st_src_reg temp = get_temp(glsl_type::bool_type);
2831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         cond_inst = emit(ir->condition, TGSI_OPCODE_MOV, st_dst_reg(temp), result);
2832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      cond_inst->cond_update = GL_TRUE;
2834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if_inst = emit(ir->condition, TGSI_OPCODE_IF);
2836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if_inst->dst.cond_mask = COND_NE;
2837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
2838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if_inst = emit(ir->condition, TGSI_OPCODE_IF, undef_dst, this->result);
2839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->instructions.push_tail(if_inst);
2842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   visit_exec_list(&ir->then_instructions, this);
2844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!ir->else_instructions.is_empty()) {
2846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      emit(ir->condition, TGSI_OPCODE_ELSE);
2847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      visit_exec_list(&ir->else_instructions, this);
2848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if_inst = emit(ir->condition, TGSI_OPCODE_ENDIF);
2851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::glsl_to_tgsi_visitor()
2854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   result.file = PROGRAM_UNDEFINED;
2856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   next_temp = 1;
2857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   next_signature_id = 1;
2858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   num_immediates = 0;
2859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   current_function = NULL;
2860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   num_address_regs = 0;
2861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   samplers_used = 0;
2862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   indirect_addr_temps = false;
2863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   indirect_addr_consts = false;
2864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glsl_version = 0;
2865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   native_integers = false;
2866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mem_ctx = ralloc_context(NULL);
2867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx = NULL;
2868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   prog = NULL;
2869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   shader_program = NULL;
2870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   options = NULL;
2871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::~glsl_to_tgsi_visitor()
2874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ralloc_free(mem_ctx);
2876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern "C" void free_glsl_to_tgsi_visitor(glsl_to_tgsi_visitor *v)
2879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   delete v;
2881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
2885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Count resources used by the given gpu program (number of texture
2886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * samplers, etc).
2887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
2888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
2889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcount_resources(glsl_to_tgsi_visitor *v, gl_program *prog)
2890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->samplers_used = 0;
2892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_iter(exec_list_iterator, iter, v->instructions) {
2894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get();
2895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (is_tex_instruction(inst->op)) {
2897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         v->samplers_used |= 1 << inst->sampler;
2898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (inst->tex_shadow) {
2900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            prog->ShadowSamplers |= 1 << inst->sampler;
2901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
2902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   prog->SamplersUsed = v->samplers_used;
2906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (v->shader_program != NULL)
2908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_update_shader_textures_used(v->shader_program, prog);
2909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
2912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgset_uniform_initializer(struct gl_context *ctx, void *mem_ctx,
2913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		struct gl_shader_program *shader_program,
2914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		const char *name, const glsl_type *type,
2915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		ir_constant *val)
2916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (type->is_record()) {
2918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_constant *field_constant;
2919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      field_constant = (ir_constant *)val->components.get_head();
2921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned int i = 0; i < type->length; i++) {
2923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const glsl_type *field_type = type->fields.structure[i].type;
2924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const char *field_name = ralloc_asprintf(mem_ctx, "%s.%s", name,
2925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        				    type->fields.structure[i].name);
2926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         set_uniform_initializer(ctx, mem_ctx, shader_program, field_name,
2927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        			 field_type, field_constant);
2928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         field_constant = (ir_constant *)field_constant->next;
2929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
2931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned offset;
2934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned index = _mesa_get_uniform_location(ctx, shader_program, name,
2935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					       &offset);
2936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (offset == GL_INVALID_INDEX) {
2937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fail_link(shader_program,
2938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	"Couldn't find uniform for initializer %s\n", name);
2939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
2940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int loc = _mesa_uniform_merge_location_offset(index, offset);
2942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (unsigned int i = 0; i < (type->is_array() ? type->length : 1); i++) {
2944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_constant *element;
2945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const glsl_type *element_type;
2946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (type->is_array()) {
2947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         element = val->array_elements[i];
2948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         element_type = type->fields.array;
2949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
2950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         element = val;
2951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         element_type = type;
2952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      void *values;
2955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (element_type->base_type == GLSL_TYPE_BOOL) {
2957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         int *conv = ralloc_array(mem_ctx, int, element_type->components());
2958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (unsigned int j = 0; j < element_type->components(); j++) {
2959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            conv[j] = element->value.b[j];
2960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
2961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         values = (void *)conv;
2962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         element_type = glsl_type::get_instance(GLSL_TYPE_INT,
2963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        					element_type->vector_elements,
2964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        					1);
2965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
2966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         values = &element->value;
2967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (element_type->is_matrix()) {
2970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_uniform_matrix(ctx, shader_program,
2971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		      element_type->matrix_columns,
2972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		      element_type->vector_elements,
2973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		      loc, 1, GL_FALSE, (GLfloat *)values);
2974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
2975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_uniform(ctx, shader_program, loc, element_type->matrix_columns,
2976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	       values, element_type->gl_type);
2977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      loc++;
2980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
2984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Returns the mask of channels (bitmask of WRITEMASK_X,Y,Z,W) which
2985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * are read from the given src in this instruction
2986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
2987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int
2988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_src_arg_mask(st_dst_reg dst, st_src_reg src)
2989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int read_mask = 0, comp;
2991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Now, given the src swizzle and the written channels, find which
2993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * components are actually read
2994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (comp = 0; comp < 4; ++comp) {
2996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const unsigned coord = GET_SWZ(src.swizzle, comp);
2997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ASSERT(coord < 4);
2998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dst.writemask & (1 << comp) && coord <= SWIZZLE_W)
2999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         read_mask |= 1 << coord;
3000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return read_mask;
3003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
3006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This pass replaces CMP T0, T1 T2 T0 with MOV T0, T2 when the CMP
3007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * instruction is the first instruction to write to register T0.  There are
3008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * several lowering passes done in GLSL IR (e.g. branches and
3009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * relative addressing) that create a large number of conditional assignments
3010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * that ir_to_mesa converts to CMP instructions like the one mentioned above.
3011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Here is why this conversion is safe:
3013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * CMP T0, T1 T2 T0 can be expanded to:
3014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * if (T1 < 0.0)
3015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 	MOV T0, T2;
3016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * else
3017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 	MOV T0, T0;
3018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If (T1 < 0.0) evaluates to true then our replacement MOV T0, T2 is the same
3020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * as the original program.  If (T1 < 0.0) evaluates to false, executing
3021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MOV T0, T0 will store a garbage value in T0 since T0 is uninitialized.
3022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Therefore, it doesn't matter that we are replacing MOV T0, T0 with MOV T0, T2
3023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * because any instruction that was going to read from T0 after this was going
3024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to read a garbage value anyway.
3025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
3026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
3027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::simplify_cmp(void)
3028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned *tempWrites;
3030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned outputWrites[MAX_PROGRAM_OUTPUTS];
3031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tempWrites = new unsigned[MAX_TEMPS];
3033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!tempWrites) {
3034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
3035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(tempWrites, 0, sizeof(unsigned) * MAX_TEMPS);
3037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(outputWrites, 0, sizeof(outputWrites));
3038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_iter(exec_list_iterator, iter, this->instructions) {
3040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get();
3041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned prevWriteMask = 0;
3042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Give up if we encounter relative addressing or flow control. */
3044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (inst->dst.reladdr ||
3045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          tgsi_get_opcode_info(inst->op)->is_branch ||
3046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          inst->op == TGSI_OPCODE_BGNSUB ||
3047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          inst->op == TGSI_OPCODE_CONT ||
3048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          inst->op == TGSI_OPCODE_END ||
3049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          inst->op == TGSI_OPCODE_ENDSUB ||
3050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          inst->op == TGSI_OPCODE_RET) {
3051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (inst->dst.file == PROGRAM_OUTPUT) {
3055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(inst->dst.index < MAX_PROGRAM_OUTPUTS);
3056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         prevWriteMask = outputWrites[inst->dst.index];
3057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         outputWrites[inst->dst.index] |= inst->dst.writemask;
3058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else if (inst->dst.file == PROGRAM_TEMPORARY) {
3059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(inst->dst.index < MAX_TEMPS);
3060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         prevWriteMask = tempWrites[inst->dst.index];
3061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         tempWrites[inst->dst.index] |= inst->dst.writemask;
3062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* For a CMP to be considered a conditional write, the destination
3065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * register and source register two must be the same. */
3066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (inst->op == TGSI_OPCODE_CMP
3067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          && !(inst->dst.writemask & prevWriteMask)
3068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          && inst->src[2].file == inst->dst.file
3069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          && inst->src[2].index == inst->dst.index
3070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          && inst->dst.writemask == get_src_arg_mask(inst->dst, inst->src[2])) {
3071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         inst->op = TGSI_OPCODE_MOV;
3073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         inst->src[0] = inst->src[1];
3074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   delete [] tempWrites;
3078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Replaces all references to a temporary register index with another index. */
3081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
3082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::rename_temp_register(int index, int new_index)
3083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_iter(exec_list_iterator, iter, this->instructions) {
3085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get();
3086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned j;
3087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (j=0; j < num_inst_src_regs(inst->op); j++) {
3089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (inst->src[j].file == PROGRAM_TEMPORARY &&
3090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             inst->src[j].index == index) {
3091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            inst->src[j].index = new_index;
3092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == index) {
3096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         inst->dst.index = new_index;
3097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint
3102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::get_first_temp_read(int index)
3103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int depth = 0; /* loop depth */
3105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int loop_start = -1; /* index of the first active BGNLOOP (if any) */
3106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i = 0, j;
3107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_iter(exec_list_iterator, iter, this->instructions) {
3109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get();
3110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (j=0; j < num_inst_src_regs(inst->op); j++) {
3112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (inst->src[j].file == PROGRAM_TEMPORARY &&
3113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             inst->src[j].index == index) {
3114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return (depth == 0) ? i : loop_start;
3115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (inst->op == TGSI_OPCODE_BGNLOOP) {
3119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if(depth++ == 0)
3120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            loop_start = i;
3121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else if (inst->op == TGSI_OPCODE_ENDLOOP) {
3122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (--depth == 0)
3123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            loop_start = -1;
3124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(depth >= 0);
3126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      i++;
3128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return -1;
3131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint
3134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::get_first_temp_write(int index)
3135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int depth = 0; /* loop depth */
3137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int loop_start = -1; /* index of the first active BGNLOOP (if any) */
3138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i = 0;
3139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_iter(exec_list_iterator, iter, this->instructions) {
3141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get();
3142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == index) {
3144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return (depth == 0) ? i : loop_start;
3145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (inst->op == TGSI_OPCODE_BGNLOOP) {
3148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if(depth++ == 0)
3149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            loop_start = i;
3150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else if (inst->op == TGSI_OPCODE_ENDLOOP) {
3151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (--depth == 0)
3152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            loop_start = -1;
3153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(depth >= 0);
3155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      i++;
3157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return -1;
3160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint
3163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::get_last_temp_read(int index)
3164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int depth = 0; /* loop depth */
3166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int last = -1; /* index of last instruction that reads the temporary */
3167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i = 0, j;
3168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_iter(exec_list_iterator, iter, this->instructions) {
3170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get();
3171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (j=0; j < num_inst_src_regs(inst->op); j++) {
3173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (inst->src[j].file == PROGRAM_TEMPORARY &&
3174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             inst->src[j].index == index) {
3175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            last = (depth == 0) ? i : -2;
3176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (inst->op == TGSI_OPCODE_BGNLOOP)
3180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         depth++;
3181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if (inst->op == TGSI_OPCODE_ENDLOOP)
3182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (--depth == 0 && last == -2)
3183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            last = i;
3184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(depth >= 0);
3185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      i++;
3187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(last >= -1);
3190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return last;
3191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint
3194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::get_last_temp_write(int index)
3195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int depth = 0; /* loop depth */
3197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int last = -1; /* index of last instruction that writes to the temporary */
3198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i = 0;
3199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_iter(exec_list_iterator, iter, this->instructions) {
3201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get();
3202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == index)
3204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         last = (depth == 0) ? i : -2;
3205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (inst->op == TGSI_OPCODE_BGNLOOP)
3207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         depth++;
3208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if (inst->op == TGSI_OPCODE_ENDLOOP)
3209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (--depth == 0 && last == -2)
3210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            last = i;
3211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(depth >= 0);
3212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      i++;
3214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(last >= -1);
3217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return last;
3218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
3221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * On a basic block basis, tracks available PROGRAM_TEMPORARY register
3222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * channels for copy propagation and updates following instructions to
3223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * use the original versions.
3224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The glsl_to_tgsi_visitor lazily produces code assuming that this pass
3226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * will occur.  As an example, a TXP production before this pass:
3227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 0: MOV TEMP[1], INPUT[4].xyyy;
3229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1: MOV TEMP[1].w, INPUT[4].wwww;
3230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2: TXP TEMP[2], TEMP[1], texture[0], 2D;
3231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and after:
3233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 0: MOV TEMP[1], INPUT[4].xyyy;
3235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1: MOV TEMP[1].w, INPUT[4].wwww;
3236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2: TXP TEMP[2], INPUT[4].xyyw, texture[0], 2D;
3237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * which allows for dead code elimination on TEMP[1]'s writes.
3239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
3240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
3241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::copy_propagate(void)
3242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glsl_to_tgsi_instruction **acp = rzalloc_array(mem_ctx,
3244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        					    glsl_to_tgsi_instruction *,
3245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        					    this->next_temp * 4);
3246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int *acp_level = rzalloc_array(mem_ctx, int, this->next_temp * 4);
3247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int level = 0;
3248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_iter(exec_list_iterator, iter, this->instructions) {
3250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get();
3251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(inst->dst.file != PROGRAM_TEMPORARY
3253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             || inst->dst.index < this->next_temp);
3254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* First, do any copy propagation possible into the src regs. */
3256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (int r = 0; r < 3; r++) {
3257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         glsl_to_tgsi_instruction *first = NULL;
3258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         bool good = true;
3259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         int acp_base = inst->src[r].index * 4;
3260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (inst->src[r].file != PROGRAM_TEMPORARY ||
3262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             inst->src[r].reladdr)
3263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            continue;
3264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* See if we can find entries in the ACP consisting of MOVs
3266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * from the same src register for all the swizzled channels
3267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * of this src register reference.
3268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
3269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (int i = 0; i < 4; i++) {
3270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            int src_chan = GET_SWZ(inst->src[r].swizzle, i);
3271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            glsl_to_tgsi_instruction *copy_chan = acp[acp_base + src_chan];
3272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (!copy_chan) {
3274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               good = false;
3275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               break;
3276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
3277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            assert(acp_level[acp_base + src_chan] <= level);
3279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (!first) {
3281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               first = copy_chan;
3282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            } else {
3283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               if (first->src[0].file != copy_chan->src[0].file ||
3284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	   first->src[0].index != copy_chan->src[0].index) {
3285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	  good = false;
3286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	  break;
3287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               }
3288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
3289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (good) {
3292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* We've now validated that we can copy-propagate to
3293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * replace this src register reference.  Do it.
3294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             */
3295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            inst->src[r].file = first->src[0].file;
3296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            inst->src[r].index = first->src[0].index;
3297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            int swizzle = 0;
3299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            for (int i = 0; i < 4; i++) {
3300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               int src_chan = GET_SWZ(inst->src[r].swizzle, i);
3301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               glsl_to_tgsi_instruction *copy_inst = acp[acp_base + src_chan];
3302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               swizzle |= (GET_SWZ(copy_inst->src[0].swizzle, src_chan) <<
3303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        		   (3 * i));
3304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
3305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            inst->src[r].swizzle = swizzle;
3306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (inst->op) {
3310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case TGSI_OPCODE_BGNLOOP:
3311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case TGSI_OPCODE_ENDLOOP:
3312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* End of a basic block, clear the ACP entirely. */
3313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         memset(acp, 0, sizeof(*acp) * this->next_temp * 4);
3314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case TGSI_OPCODE_IF:
3317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ++level;
3318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case TGSI_OPCODE_ENDIF:
3321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case TGSI_OPCODE_ELSE:
3322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Clear all channels written inside the block from the ACP, but
3323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * leaving those that were not touched.
3324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
3325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (int r = 0; r < this->next_temp; r++) {
3326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            for (int c = 0; c < 4; c++) {
3327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               if (!acp[4 * r + c])
3328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	  continue;
3329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               if (acp_level[4 * r + c] >= level)
3331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	  acp[4 * r + c] = NULL;
3332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
3333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (inst->op == TGSI_OPCODE_ENDIF)
3335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            --level;
3336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
3339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Continuing the block, clear any written channels from
3340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * the ACP.
3341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
3342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.reladdr) {
3343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* Any temporary might be written, so no copy propagation
3344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * across this instruction.
3345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             */
3346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            memset(acp, 0, sizeof(*acp) * this->next_temp * 4);
3347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         } else if (inst->dst.file == PROGRAM_OUTPUT &&
3348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	    inst->dst.reladdr) {
3349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* Any output might be written, so no copy propagation
3350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * from outputs across this instruction.
3351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             */
3352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            for (int r = 0; r < this->next_temp; r++) {
3353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               for (int c = 0; c < 4; c++) {
3354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	  if (!acp[4 * r + c])
3355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	     continue;
3356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	  if (acp[4 * r + c]->src[0].file == PROGRAM_OUTPUT)
3358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	     acp[4 * r + c] = NULL;
3359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               }
3360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
3361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         } else if (inst->dst.file == PROGRAM_TEMPORARY ||
3362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	    inst->dst.file == PROGRAM_OUTPUT) {
3363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* Clear where it's used as dst. */
3364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (inst->dst.file == PROGRAM_TEMPORARY) {
3365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               for (int c = 0; c < 4; c++) {
3366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	  if (inst->dst.writemask & (1 << c)) {
3367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	     acp[4 * inst->dst.index + c] = NULL;
3368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	  }
3369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               }
3370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
3371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* Clear where it's used as src. */
3373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            for (int r = 0; r < this->next_temp; r++) {
3374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               for (int c = 0; c < 4; c++) {
3375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	  if (!acp[4 * r + c])
3376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	     continue;
3377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	  int src_chan = GET_SWZ(acp[4 * r + c]->src[0].swizzle, c);
3379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	  if (acp[4 * r + c]->src[0].file == inst->dst.file &&
3381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	      acp[4 * r + c]->src[0].index == inst->dst.index &&
3382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	      inst->dst.writemask & (1 << src_chan))
3383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	  {
3384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	     acp[4 * r + c] = NULL;
3385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	  }
3386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               }
3387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
3388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* If this is a copy, add it to the ACP. */
3393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (inst->op == TGSI_OPCODE_MOV &&
3394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          inst->dst.file == PROGRAM_TEMPORARY &&
3395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          !inst->dst.reladdr &&
3396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          !inst->saturate &&
3397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          !inst->src[0].reladdr &&
3398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          !inst->src[0].negate) {
3399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (int i = 0; i < 4; i++) {
3400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (inst->dst.writemask & (1 << i)) {
3401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               acp[4 * inst->dst.index + i] = inst;
3402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               acp_level[4 * inst->dst.index + i] = level;
3403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
3404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ralloc_free(acp_level);
3409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ralloc_free(acp);
3410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
3413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Tracks available PROGRAM_TEMPORARY registers for dead code elimination.
3414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The glsl_to_tgsi_visitor lazily produces code assuming that this pass
3416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * will occur.  As an example, a TXP production after copy propagation but
3417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * before this pass:
3418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 0: MOV TEMP[1], INPUT[4].xyyy;
3420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1: MOV TEMP[1].w, INPUT[4].wwww;
3421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2: TXP TEMP[2], INPUT[4].xyyw, texture[0], 2D;
3422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and after this pass:
3424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 0: TXP TEMP[2], INPUT[4].xyyw, texture[0], 2D;
3426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FIXME: assumes that all functions are inlined (no support for BGNSUB/ENDSUB)
3428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FIXME: doesn't eliminate all dead code inside of loops; it steps around them
3429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
3430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
3431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::eliminate_dead_code(void)
3432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
3434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i=0; i < this->next_temp; i++) {
3436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int last_read = get_last_temp_read(i);
3437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int j = 0;
3438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      foreach_iter(exec_list_iterator, iter, this->instructions) {
3440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get();
3441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == i &&
3443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             j > last_read)
3444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
3445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            iter.remove();
3446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            delete inst;
3447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         j++;
3450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
3455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * On a basic block basis, tracks available PROGRAM_TEMPORARY registers for dead
3456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * code elimination.  This is less primitive than eliminate_dead_code(), as it
3457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is per-channel and can detect consecutive writes without a read between them
3458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * as dead code.  However, there is some dead code that can be eliminated by
3459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * eliminate_dead_code() but not this function - for example, this function
3460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * cannot eliminate an instruction writing to a register that is never read and
3461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is the only instruction writing to that register.
3462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The glsl_to_tgsi_visitor lazily produces code assuming that this pass
3464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * will occur.
3465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
3466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint
3467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::eliminate_dead_code_advanced(void)
3468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glsl_to_tgsi_instruction **writes = rzalloc_array(mem_ctx,
3470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                     glsl_to_tgsi_instruction *,
3471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                     this->next_temp * 4);
3472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int *write_level = rzalloc_array(mem_ctx, int, this->next_temp * 4);
3473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int level = 0;
3474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int removed = 0;
3475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_iter(exec_list_iterator, iter, this->instructions) {
3477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get();
3478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(inst->dst.file != PROGRAM_TEMPORARY
3480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             || inst->dst.index < this->next_temp);
3481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (inst->op) {
3483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case TGSI_OPCODE_BGNLOOP:
3484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case TGSI_OPCODE_ENDLOOP:
3485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case TGSI_OPCODE_CONT:
3486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case TGSI_OPCODE_BRK:
3487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* End of a basic block, clear the write array entirely.
3488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          *
3489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * This keeps us from killing dead code when the writes are
3490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * on either side of a loop, even when the register isn't touched
3491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * inside the loop.  However, glsl_to_tgsi_visitor doesn't seem to emit
3492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * dead code of this type, so it shouldn't make a difference as long as
3493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * the dead code elimination pass in the GLSL compiler does its job.
3494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
3495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         memset(writes, 0, sizeof(*writes) * this->next_temp * 4);
3496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case TGSI_OPCODE_ENDIF:
3499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case TGSI_OPCODE_ELSE:
3500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Promote the recorded level of all channels written inside the
3501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * preceding if or else block to the level above the if/else block.
3502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
3503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (int r = 0; r < this->next_temp; r++) {
3504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            for (int c = 0; c < 4; c++) {
3505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               if (!writes[4 * r + c])
3506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	         continue;
3507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               if (write_level[4 * r + c] == level)
3509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        	         write_level[4 * r + c] = level-1;
3510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
3511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if(inst->op == TGSI_OPCODE_ENDIF)
3514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            --level;
3515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case TGSI_OPCODE_IF:
3519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ++level;
3520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* fallthrough to default case to mark the condition as read */
3521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
3523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Continuing the block, clear any channels from the write array that
3524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * are read by this instruction.
3525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
3526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (unsigned i = 0; i < Elements(inst->src); i++) {
3527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (inst->src[i].file == PROGRAM_TEMPORARY && inst->src[i].reladdr){
3528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               /* Any temporary might be read, so no dead code elimination
3529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                * across this instruction.
3530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                */
3531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               memset(writes, 0, sizeof(*writes) * this->next_temp * 4);
3532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            } else if (inst->src[i].file == PROGRAM_TEMPORARY) {
3533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               /* Clear where it's used as src. */
3534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               int src_chans = 1 << GET_SWZ(inst->src[i].swizzle, 0);
3535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               src_chans |= 1 << GET_SWZ(inst->src[i].swizzle, 1);
3536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               src_chans |= 1 << GET_SWZ(inst->src[i].swizzle, 2);
3537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               src_chans |= 1 << GET_SWZ(inst->src[i].swizzle, 3);
3538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               for (int c = 0; c < 4; c++) {
3540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              	   if (src_chans & (1 << c)) {
3541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              	      writes[4 * inst->src[i].index + c] = NULL;
3542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              	   }
3543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               }
3544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
3545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* If this instruction writes to a temporary, add it to the write array.
3550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * If there is already an instruction in the write array for one or more
3551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * of the channels, flag that channel write as dead.
3552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
3553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (inst->dst.file == PROGRAM_TEMPORARY &&
3554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          !inst->dst.reladdr &&
3555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          !inst->saturate) {
3556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (int c = 0; c < 4; c++) {
3557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (inst->dst.writemask & (1 << c)) {
3558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               if (writes[4 * inst->dst.index + c]) {
3559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  if (write_level[4 * inst->dst.index + c] < level)
3560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     continue;
3561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  else
3562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     writes[4 * inst->dst.index + c]->dead_mask |= (1 << c);
3563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               }
3564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               writes[4 * inst->dst.index + c] = inst;
3565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               write_level[4 * inst->dst.index + c] = level;
3566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
3567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Anything still in the write array at this point is dead code. */
3572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (int r = 0; r < this->next_temp; r++) {
3573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (int c = 0; c < 4; c++) {
3574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         glsl_to_tgsi_instruction *inst = writes[4 * r + c];
3575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (inst)
3576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            inst->dead_mask |= (1 << c);
3577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Now actually remove the instructions that are completely dead and update
3581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * the writemask of other instructions with dead channels.
3582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_iter(exec_list_iterator, iter, this->instructions) {
3584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get();
3585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!inst->dead_mask || !inst->dst.writemask)
3587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         continue;
3588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if ((inst->dst.writemask & ~inst->dead_mask) == 0) {
3589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         iter.remove();
3590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         delete inst;
3591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         removed++;
3592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else
3593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         inst->dst.writemask &= ~(inst->dead_mask);
3594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ralloc_free(write_level);
3597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ralloc_free(writes);
3598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return removed;
3600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Merges temporary registers together where possible to reduce the number of
3603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * registers needed to run a program.
3604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Produces optimal code only after copy propagation and dead code elimination
3606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * have been run. */
3607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
3608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::merge_registers(void)
3609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int *last_reads = rzalloc_array(mem_ctx, int, this->next_temp);
3611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int *first_writes = rzalloc_array(mem_ctx, int, this->next_temp);
3612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i, j;
3613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Read the indices of the last read and first write to each temp register
3615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * into an array so that we don't have to traverse the instruction list as
3616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * much. */
3617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i=0; i < this->next_temp; i++) {
3618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      last_reads[i] = get_last_temp_read(i);
3619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      first_writes[i] = get_first_temp_write(i);
3620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Start looking for registers with non-overlapping usages that can be
3623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * merged together. */
3624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i=0; i < this->next_temp; i++) {
3625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Don't touch unused registers. */
3626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (last_reads[i] < 0 || first_writes[i] < 0) continue;
3627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (j=0; j < this->next_temp; j++) {
3629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Don't touch unused registers. */
3630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (last_reads[j] < 0 || first_writes[j] < 0) continue;
3631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* We can merge the two registers if the first write to j is after or
3633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * in the same instruction as the last read from i.  Note that the
3634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * register at index i will always be used earlier or at the same time
3635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * as the register at index j. */
3636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (first_writes[i] <= first_writes[j] &&
3637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             last_reads[i] <= first_writes[j])
3638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
3639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            rename_temp_register(j, i); /* Replace all references to j with i.*/
3640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* Update the first_writes and last_reads arrays with the new
3642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * values for the merged register index, and mark the newly unused
3643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * register index as such. */
3644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            last_reads[i] = last_reads[j];
3645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            first_writes[j] = -1;
3646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            last_reads[j] = -1;
3647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ralloc_free(last_reads);
3652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ralloc_free(first_writes);
3653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Reassign indices to temporary registers by reusing unused indices created
3656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * by optimization passes. */
3657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
3658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::renumber_registers(void)
3659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i = 0;
3661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int new_index = 0;
3662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i=0; i < this->next_temp; i++) {
3664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (get_first_temp_read(i) < 0) continue;
3665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (i != new_index)
3666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         rename_temp_register(i, new_index);
3667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      new_index++;
3668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->next_temp = new_index;
3671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
3674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Returns a fragment program which implements the current pixel transfer ops.
3675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Based on get_pixel_transfer_program in st_atom_pixeltransfer.c.
3676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
3677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern "C" void
3678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_pixel_transfer_visitor(struct st_fragment_program *fp,
3679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           glsl_to_tgsi_visitor *original,
3680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           int scale_and_bias, int pixel_maps)
3681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glsl_to_tgsi_visitor *v = new glsl_to_tgsi_visitor();
3683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct st_context *st = st_context(original->ctx);
3684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_program *prog = &fp->Base.Base;
3685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_program_parameter_list *params = _mesa_new_parameter_list();
3686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_src_reg coord, src0;
3687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_dst_reg dst0;
3688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glsl_to_tgsi_instruction *inst;
3689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Copy attributes of the glsl_to_tgsi_visitor in the original shader. */
3691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->ctx = original->ctx;
3692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->prog = prog;
3693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->shader_program = NULL;
3694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->glsl_version = original->glsl_version;
3695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->native_integers = original->native_integers;
3696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->options = original->options;
3697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->next_temp = original->next_temp;
3698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->num_address_regs = original->num_address_regs;
3699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->samplers_used = prog->SamplersUsed = original->samplers_used;
3700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->indirect_addr_temps = original->indirect_addr_temps;
3701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->indirect_addr_consts = original->indirect_addr_consts;
3702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memcpy(&v->immediates, &original->immediates, sizeof(v->immediates));
3703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->num_immediates = original->num_immediates;
3704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
3706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Get initial pixel color from the texture.
3707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * TEX colorTemp, fragment.texcoord[0], texture[0], 2D;
3708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   coord = st_src_reg(PROGRAM_INPUT, FRAG_ATTRIB_TEX0, glsl_type::vec2_type);
3710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src0 = v->get_temp(glsl_type::vec4_type);
3711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dst0 = st_dst_reg(src0);
3712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   inst = v->emit(NULL, TGSI_OPCODE_TEX, dst0, coord);
3713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   inst->sampler = 0;
3714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   inst->tex_target = TEXTURE_2D_INDEX;
3715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   prog->InputsRead |= FRAG_BIT_TEX0;
3717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   prog->SamplersUsed |= (1 << 0); /* mark sampler 0 as used */
3718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->samplers_used |= (1 << 0);
3719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (scale_and_bias) {
3721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      static const gl_state_index scale_state[STATE_LENGTH] =
3722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         { STATE_INTERNAL, STATE_PT_SCALE,
3723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           (gl_state_index) 0, (gl_state_index) 0, (gl_state_index) 0 };
3724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      static const gl_state_index bias_state[STATE_LENGTH] =
3725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         { STATE_INTERNAL, STATE_PT_BIAS,
3726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           (gl_state_index) 0, (gl_state_index) 0, (gl_state_index) 0 };
3727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint scale_p, bias_p;
3728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      st_src_reg scale, bias;
3729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      scale_p = _mesa_add_state_reference(params, scale_state);
3731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      bias_p = _mesa_add_state_reference(params, bias_state);
3732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* MAD colorTemp, colorTemp, scale, bias; */
3734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      scale = st_src_reg(PROGRAM_STATE_VAR, scale_p, GLSL_TYPE_FLOAT);
3735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      bias = st_src_reg(PROGRAM_STATE_VAR, bias_p, GLSL_TYPE_FLOAT);
3736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst = v->emit(NULL, TGSI_OPCODE_MAD, dst0, src0, scale, bias);
3737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (pixel_maps) {
3740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      st_src_reg temp = v->get_temp(glsl_type::vec4_type);
3741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      st_dst_reg temp_dst = st_dst_reg(temp);
3742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(st->pixel_xfer.pixelmap_texture);
3744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* With a little effort, we can do four pixel map look-ups with
3746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * two TEX instructions:
3747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
3748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* TEX temp.rg, colorTemp.rgba, texture[1], 2D; */
3750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      temp_dst.writemask = WRITEMASK_XY; /* write R,G */
3751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst = v->emit(NULL, TGSI_OPCODE_TEX, temp_dst, src0);
3752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst->sampler = 1;
3753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst->tex_target = TEXTURE_2D_INDEX;
3754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* TEX temp.ba, colorTemp.baba, texture[1], 2D; */
3756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src0.swizzle = MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W, SWIZZLE_Z, SWIZZLE_W);
3757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      temp_dst.writemask = WRITEMASK_ZW; /* write B,A */
3758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst = v->emit(NULL, TGSI_OPCODE_TEX, temp_dst, src0);
3759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst->sampler = 1;
3760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst->tex_target = TEXTURE_2D_INDEX;
3761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      prog->SamplersUsed |= (1 << 1); /* mark sampler 1 as used */
3763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      v->samplers_used |= (1 << 1);
3764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* MOV colorTemp, temp; */
3766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inst = v->emit(NULL, TGSI_OPCODE_MOV, dst0, temp);
3767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Now copy the instructions from the original glsl_to_tgsi_visitor into the
3770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * new visitor. */
3771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_iter(exec_list_iterator, iter, original->instructions) {
3772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get();
3773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      glsl_to_tgsi_instruction *newinst;
3774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      st_src_reg src_regs[3];
3775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (inst->dst.file == PROGRAM_OUTPUT)
3777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         prog->OutputsWritten |= BITFIELD64_BIT(inst->dst.index);
3778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (int i=0; i<3; i++) {
3780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         src_regs[i] = inst->src[i];
3781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (src_regs[i].file == PROGRAM_INPUT &&
3782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             src_regs[i].index == FRAG_ATTRIB_COL0)
3783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {
3784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            src_regs[i].file = PROGRAM_TEMPORARY;
3785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            src_regs[i].index = src0.index;
3786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else if (src_regs[i].file == PROGRAM_INPUT)
3788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            prog->InputsRead |= BITFIELD64_BIT(src_regs[i].index);
3789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      newinst = v->emit(NULL, inst->op, inst->dst, src_regs[0], src_regs[1], src_regs[2]);
3792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      newinst->tex_target = inst->tex_target;
3793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Make modifications to fragment program info. */
3796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   prog->Parameters = _mesa_combine_parameter_lists(params,
3797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                    original->prog->Parameters);
3798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _mesa_free_parameter_list(params);
3799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   count_resources(v, prog);
3800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fp->glsl_to_tgsi = v;
3801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
3804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Make fragment program for glBitmap:
3805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *   Sample the texture and kill the fragment if the bit is 0.
3806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This program will be combined with the user's fragment program.
3807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Based on make_bitmap_fragment_program in st_cb_bitmap.c.
3809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
3810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern "C" void
3811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_bitmap_visitor(struct st_fragment_program *fp,
3812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   glsl_to_tgsi_visitor *original, int samplerIndex)
3813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glsl_to_tgsi_visitor *v = new glsl_to_tgsi_visitor();
3815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct st_context *st = st_context(original->ctx);
3816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_program *prog = &fp->Base.Base;
3817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_src_reg coord, src0;
3818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   st_dst_reg dst0;
3819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glsl_to_tgsi_instruction *inst;
3820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Copy attributes of the glsl_to_tgsi_visitor in the original shader. */
3822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->ctx = original->ctx;
3823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->prog = prog;
3824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->shader_program = NULL;
3825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->glsl_version = original->glsl_version;
3826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->native_integers = original->native_integers;
3827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->options = original->options;
3828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->next_temp = original->next_temp;
3829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->num_address_regs = original->num_address_regs;
3830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->samplers_used = prog->SamplersUsed = original->samplers_used;
3831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->indirect_addr_temps = original->indirect_addr_temps;
3832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->indirect_addr_consts = original->indirect_addr_consts;
3833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memcpy(&v->immediates, &original->immediates, sizeof(v->immediates));
3834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->num_immediates = original->num_immediates;
3835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* TEX tmp0, fragment.texcoord[0], texture[0], 2D; */
3837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   coord = st_src_reg(PROGRAM_INPUT, FRAG_ATTRIB_TEX0, glsl_type::vec2_type);
3838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src0 = v->get_temp(glsl_type::vec4_type);
3839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dst0 = st_dst_reg(src0);
3840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   inst = v->emit(NULL, TGSI_OPCODE_TEX, dst0, coord);
3841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   inst->sampler = samplerIndex;
3842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   inst->tex_target = TEXTURE_2D_INDEX;
3843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   prog->InputsRead |= FRAG_BIT_TEX0;
3845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   prog->SamplersUsed |= (1 << samplerIndex); /* mark sampler as used */
3846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->samplers_used |= (1 << samplerIndex);
3847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* KIL if -tmp0 < 0 # texel=0 -> keep / texel=0 -> discard */
3849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src0.negate = NEGATE_XYZW;
3850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (st->bitmap.tex_format == PIPE_FORMAT_L8_UNORM)
3851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src0.swizzle = SWIZZLE_XXXX;
3852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   inst = v->emit(NULL, TGSI_OPCODE_KIL, undef_dst, src0);
3853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Now copy the instructions from the original glsl_to_tgsi_visitor into the
3855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * new visitor. */
3856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_iter(exec_list_iterator, iter, original->instructions) {
3857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get();
3858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      glsl_to_tgsi_instruction *newinst;
3859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      st_src_reg src_regs[3];
3860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (inst->dst.file == PROGRAM_OUTPUT)
3862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         prog->OutputsWritten |= BITFIELD64_BIT(inst->dst.index);
3863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (int i=0; i<3; i++) {
3865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         src_regs[i] = inst->src[i];
3866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (src_regs[i].file == PROGRAM_INPUT)
3867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            prog->InputsRead |= BITFIELD64_BIT(src_regs[i].index);
3868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      newinst = v->emit(NULL, inst->op, inst->dst, src_regs[0], src_regs[1], src_regs[2]);
3871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      newinst->tex_target = inst->tex_target;
3872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Make modifications to fragment program info. */
3875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   prog->Parameters = _mesa_clone_parameter_list(original->prog->Parameters);
3876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   count_resources(v, prog);
3877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fp->glsl_to_tgsi = v;
3878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* ------------------------- TGSI conversion stuff -------------------------- */
3881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct label {
3882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned branch_target;
3883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned token;
3884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
3885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
3887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Intermediate state used during shader translation.
3888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
3889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct st_translate {
3890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_program *ureg;
3891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_dst temps[MAX_TEMPS];
3893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_src *constants;
3894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_src *immediates;
3895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_dst outputs[PIPE_MAX_SHADER_OUTPUTS];
3896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_src inputs[PIPE_MAX_SHADER_INPUTS];
3897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_dst address[1];
3898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_src samplers[PIPE_MAX_SAMPLERS];
3899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_src systemValues[SYSTEM_VALUE_MAX];
3900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLuint *inputMapping;
3902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLuint *outputMapping;
3903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* For every instruction that contains a label (eg CALL), keep
3905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * details so that we can go back afterwards and emit the correct
3906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * tgsi instruction number for each label.
3907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct label *labels;
3909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned labels_size;
3910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned labels_count;
3911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Keep a record of the tgsi instruction number that each mesa
3913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * instruction starts at, will be used to fix up labels after
3914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * translation.
3915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
3916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned *insn;
3917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned insn_size;
3918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned insn_count;
3919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned procType;  /**< TGSI_PROCESSOR_VERTEX/FRAGMENT */
3921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean error;
3923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
3924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Map Mesa's SYSTEM_VALUE_x to TGSI_SEMANTIC_x */
3926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned mesa_sysval_to_semantic[SYSTEM_VALUE_MAX] = {
3927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   TGSI_SEMANTIC_FACE,
3928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   TGSI_SEMANTIC_VERTEXID,
3929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   TGSI_SEMANTIC_INSTANCEID
3930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
3931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
3933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Make note of a branch to a label in the TGSI code.
3934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * After we've emitted all instructions, we'll go over the list
3935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of labels built here and patch the TGSI code with the actual
3936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * location of each label.
3937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
3938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned *get_label(struct st_translate *t, unsigned branch_target)
3939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i;
3941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (t->labels_count + 1 >= t->labels_size) {
3943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      t->labels_size = 1 << (util_logbase2(t->labels_size) + 1);
3944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      t->labels = (struct label *)realloc(t->labels,
3945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          t->labels_size * sizeof(struct label));
3946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (t->labels == NULL) {
3947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         static unsigned dummy;
3948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         t->error = TRUE;
3949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return &dummy;
3950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i = t->labels_count++;
3954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   t->labels[i].branch_target = branch_target;
3955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return &t->labels[i].token;
3956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
3959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Called prior to emitting the TGSI code for each instruction.
3960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Allocate additional space for instructions if needed.
3961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Update the insn[] array so the next glsl_to_tgsi_instruction points to
3962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the next TGSI instruction.
3963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
3964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void set_insn_start(struct st_translate *t, unsigned start)
3965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (t->insn_count + 1 >= t->insn_size) {
3967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      t->insn_size = 1 << (util_logbase2(t->insn_size) + 1);
3968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      t->insn = (unsigned *)realloc(t->insn, t->insn_size * sizeof(t->insn[0]));
3969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (t->insn == NULL) {
3970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         t->error = TRUE;
3971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return;
3972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   t->insn[t->insn_count++] = start;
3976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
3979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Map a glsl_to_tgsi constant/immediate to a TGSI immediate.
3980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
3981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct ureg_src
3982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgemit_immediate(struct st_translate *t,
3983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               gl_constant_value values[4],
3984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               int type, int size)
3985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_program *ureg = t->ureg;
3987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch(type)
3989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
3990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_FLOAT:
3991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return ureg_DECL_immediate(ureg, &values[0].f, size);
3992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_INT:
3993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return ureg_DECL_immediate_int(ureg, &values[0].i, size);
3994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_UNSIGNED_INT:
3995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_BOOL:
3996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return ureg_DECL_immediate_uint(ureg, &values[0].u, size);
3997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
3998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(!"should not get here - type must be float, int, uint, or bool");
3999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return ureg_src_undef();
4000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
4004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Map a glsl_to_tgsi dst register to a TGSI ureg_dst register.
4005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
4006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct ureg_dst
4007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdst_register(struct st_translate *t,
4008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             gl_register_file file,
4009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             GLuint index)
4010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
4011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch(file) {
4012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_UNDEFINED:
4013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return ureg_dst_undef();
4014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_TEMPORARY:
4016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ureg_dst_is_undef(t->temps[index]))
4017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         t->temps[index] = ureg_DECL_local_temporary(t->ureg);
4018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return t->temps[index];
4020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_OUTPUT:
4022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (t->procType == TGSI_PROCESSOR_VERTEX)
4023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(index < VERT_RESULT_MAX);
4024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if (t->procType == TGSI_PROCESSOR_FRAGMENT)
4025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(index < FRAG_RESULT_MAX);
4026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
4027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(index < GEOM_RESULT_MAX);
4028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(t->outputMapping[index] < Elements(t->outputs));
4030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return t->outputs[t->outputMapping[index]];
4032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_ADDRESS:
4034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return t->address[index];
4035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
4037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(!"unknown dst register file");
4038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return ureg_dst_undef();
4039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
4043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Map a glsl_to_tgsi src register to a TGSI ureg_src register.
4044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
4045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct ureg_src
4046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsrc_register(struct st_translate *t,
4047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             gl_register_file file,
4048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             GLint index)
4049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
4050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch(file) {
4051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_UNDEFINED:
4052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return ureg_src_undef();
4053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_TEMPORARY:
4055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(index >= 0);
4056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(index < (int) Elements(t->temps));
4057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ureg_dst_is_undef(t->temps[index]))
4058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         t->temps[index] = ureg_DECL_local_temporary(t->ureg);
4059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return ureg_src(t->temps[index]);
4060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_NAMED_PARAM:
4062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_ENV_PARAM:
4063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_LOCAL_PARAM:
4064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_UNIFORM:
4065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(index >= 0);
4066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return t->constants[index];
4067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_STATE_VAR:
4068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_CONSTANT:       /* ie, immediate */
4069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (index < 0)
4070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return ureg_DECL_constant(t->ureg, 0);
4071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
4072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return t->constants[index];
4073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_IMMEDIATE:
4075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return t->immediates[index];
4076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_INPUT:
4078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(t->inputMapping[index] < Elements(t->inputs));
4079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return t->inputs[t->inputMapping[index]];
4080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_OUTPUT:
4082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(t->outputMapping[index] < Elements(t->outputs));
4083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return ureg_src(t->outputs[t->outputMapping[index]]); /* not needed? */
4084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_ADDRESS:
4086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return ureg_src(t->address[index]);
4087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PROGRAM_SYSTEM_VALUE:
4089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(index < (int) Elements(t->systemValues));
4090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return t->systemValues[index];
4091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
4093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(!"unknown src register file");
4094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return ureg_src_undef();
4095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
4099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Create a TGSI ureg_dst register from an st_dst_reg.
4100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
4101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct ureg_dst
4102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtranslate_dst(struct st_translate *t,
4103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              const st_dst_reg *dst_reg,
4104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              bool saturate, bool clamp_color)
4105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
4106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_dst dst = dst_register(t,
4107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      dst_reg->file,
4108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      dst_reg->index);
4109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dst = ureg_writemask(dst, dst_reg->writemask);
4111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (saturate)
4113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dst = ureg_saturate(dst);
4114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (clamp_color && dst_reg->file == PROGRAM_OUTPUT) {
4115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Clamp colors for ARB_color_buffer_float. */
4116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (t->procType) {
4117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case TGSI_PROCESSOR_VERTEX:
4118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* XXX if the geometry shader is present, this must be done there
4119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * instead of here. */
4120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (dst_reg->index == VERT_RESULT_COL0 ||
4121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             dst_reg->index == VERT_RESULT_COL1 ||
4122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             dst_reg->index == VERT_RESULT_BFC0 ||
4123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             dst_reg->index == VERT_RESULT_BFC1) {
4124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            dst = ureg_saturate(dst);
4125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
4126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
4127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case TGSI_PROCESSOR_FRAGMENT:
4129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (dst_reg->index >= FRAG_RESULT_COLOR) {
4130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            dst = ureg_saturate(dst);
4131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
4132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
4133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dst_reg->reladdr != NULL)
4137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dst = ureg_dst_indirect(dst, ureg_src(t->address[0]));
4138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return dst;
4140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
4143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Create a TGSI ureg_src register from an st_src_reg.
4144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
4145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct ureg_src
4146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtranslate_src(struct st_translate *t, const st_src_reg *src_reg)
4147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
4148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_src src = src_register(t, src_reg->file, src_reg->index);
4149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   src = ureg_swizzle(src,
4151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      GET_SWZ(src_reg->swizzle, 0) & 0x3,
4152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      GET_SWZ(src_reg->swizzle, 1) & 0x3,
4153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      GET_SWZ(src_reg->swizzle, 2) & 0x3,
4154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      GET_SWZ(src_reg->swizzle, 3) & 0x3);
4155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if ((src_reg->negate & 0xf) == NEGATE_XYZW)
4157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src = ureg_negate(src);
4158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (src_reg->reladdr != NULL) {
4160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Normally ureg_src_indirect() would be used here, but a stupid compiler
4161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * bug in g++ makes ureg_src_indirect (an inline C function) erroneously
4162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * set the bit for src.Negate.  So we have to do the operation manually
4163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * here to work around the compiler's problems. */
4164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*src = ureg_src_indirect(src, ureg_src(t->address[0]));*/
4165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct ureg_src addr = ureg_src(t->address[0]);
4166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src.Indirect = 1;
4167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src.IndirectFile = addr.File;
4168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src.IndirectIndex = addr.Index;
4169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src.IndirectSwizzle = addr.SwizzleX;
4170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (src_reg->file != PROGRAM_INPUT &&
4172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          src_reg->file != PROGRAM_OUTPUT) {
4173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* If src_reg->index was negative, it was set to zero in
4174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * src_register().  Reassign it now.  But don't do this
4175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * for input/output regs since they get remapped while
4176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * const buffers don't.
4177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
4178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         src.Index = src_reg->index;
4179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return src;
4183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct tgsi_texture_offset
4186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtranslate_tex_offset(struct st_translate *t,
4187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     const struct tgsi_texture_offset *in_offset)
4188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
4189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct tgsi_texture_offset offset;
4190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(in_offset->File == PROGRAM_IMMEDIATE);
4192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   offset.File = TGSI_FILE_IMMEDIATE;
4194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   offset.Index = in_offset->Index;
4195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   offset.SwizzleX = in_offset->SwizzleX;
4196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   offset.SwizzleY = in_offset->SwizzleY;
4197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   offset.SwizzleZ = in_offset->SwizzleZ;
4198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   offset.Padding = 0;
4199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return offset;
4201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
4204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcompile_tgsi_instruction(struct st_translate *t,
4205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         const glsl_to_tgsi_instruction *inst,
4206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         bool clamp_dst_color_output)
4207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
4208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_program *ureg = t->ureg;
4209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
4210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_dst dst[1];
4211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_src src[4];
4212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct tgsi_texture_offset texoffsets[MAX_GLSL_TEXTURE_OFFSET];
4213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned num_dst;
4215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned num_src;
4216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   num_dst = num_inst_dst_regs(inst->op);
4218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   num_src = num_inst_src_regs(inst->op);
4219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (num_dst)
4221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dst[0] = translate_dst(t,
4222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             &inst->dst,
4223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             inst->saturate,
4224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             clamp_dst_color_output);
4225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < num_src; i++)
4227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src[i] = translate_src(t, &inst->src[i]);
4228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch(inst->op) {
4230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_BGNLOOP:
4231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_CAL:
4232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_ELSE:
4233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_ENDLOOP:
4234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_IF:
4235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(num_dst == 0);
4236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ureg_label_insn(ureg,
4237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      inst->op,
4238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      src, num_src,
4239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      get_label(t,
4240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                inst->op == TGSI_OPCODE_CAL ? inst->function->sig_id : 0));
4241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
4242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_TEX:
4244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_TXB:
4245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_TXD:
4246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_TXL:
4247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_TXP:
4248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_TXQ:
4249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_TXF:
4250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src[num_src++] = t->samplers[inst->sampler];
4251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < inst->tex_offset_num_offset; i++) {
4252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         texoffsets[i] = translate_tex_offset(t, &inst->tex_offsets[i]);
4253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ureg_tex_insn(ureg,
4255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    inst->op,
4256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    dst, num_dst,
4257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    st_translate_texture_target(inst->tex_target, inst->tex_shadow),
4258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    texoffsets, inst->tex_offset_num_offset,
4259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    src, num_src);
4260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
4261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case TGSI_OPCODE_SCS:
4263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dst[0] = ureg_writemask(dst[0], TGSI_WRITEMASK_XY);
4264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ureg_insn(ureg, inst->op, dst, num_dst, src, num_src);
4265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
4266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
4268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ureg_insn(ureg,
4269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                inst->op,
4270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                dst, num_dst,
4271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                src, num_src);
4272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
4273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
4277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Emit the TGSI instructions for inverting and adjusting WPOS.
4278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This code is unavoidable because it also depends on whether
4279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * a FBO is bound (STATE_FB_WPOS_Y_TRANSFORM).
4280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
4281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
4282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgemit_wpos_adjustment( struct st_translate *t,
4283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      const struct gl_program *program,
4284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      boolean invert,
4285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      GLfloat adjX, GLfloat adjY[2])
4286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
4287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_program *ureg = t->ureg;
4288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Fragment program uses fragment position input.
4290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Need to replace instances of INPUT[WPOS] with temp T
4291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * where T = INPUT[WPOS] by y is inverted.
4292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
4293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   static const gl_state_index wposTransformState[STATE_LENGTH]
4294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      = { STATE_INTERNAL, STATE_FB_WPOS_Y_TRANSFORM,
4295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          (gl_state_index)0, (gl_state_index)0, (gl_state_index)0 };
4296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* XXX: note we are modifying the incoming shader here!  Need to
4298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * do this before emitting the constant decls below, or this
4299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * will be missed:
4300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
4301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned wposTransConst = _mesa_add_state_reference(program->Parameters,
4302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                       wposTransformState);
4303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_src wpostrans = ureg_DECL_constant( ureg, wposTransConst );
4305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_dst wpos_temp = ureg_DECL_temporary( ureg );
4306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]];
4307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* First, apply the coordinate shift: */
4309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (adjX || adjY[0] || adjY[1]) {
4310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (adjY[0] != adjY[1]) {
4311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Adjust the y coordinate by adjY[1] or adjY[0] respectively
4312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * depending on whether inversion is actually going to be applied
4313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * or not, which is determined by testing against the inversion
4314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * state variable used below, which will be either +1 or -1.
4315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
4316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         struct ureg_dst adj_temp = ureg_DECL_local_temporary(ureg);
4317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ureg_CMP(ureg, adj_temp,
4319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  ureg_scalar(wpostrans, invert ? 2 : 0),
4320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  ureg_imm4f(ureg, adjX, adjY[0], 0.0f, 0.0f),
4321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  ureg_imm4f(ureg, adjX, adjY[1], 0.0f, 0.0f));
4322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ureg_ADD(ureg, wpos_temp, wpos_input, ureg_src(adj_temp));
4323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
4324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ureg_ADD(ureg, wpos_temp, wpos_input,
4325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  ureg_imm4f(ureg, adjX, adjY[0], 0.0f, 0.0f));
4326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      wpos_input = ureg_src(wpos_temp);
4328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
4329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* MOV wpos_temp, input[wpos]
4330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
4331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ureg_MOV( ureg, wpos_temp, wpos_input );
4332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Now the conditional y flip: STATE_FB_WPOS_Y_TRANSFORM.xy/zw will be
4335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * inversion/identity, or the other way around if we're drawing to an FBO.
4336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
4337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (invert) {
4338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* MAD wpos_temp.y, wpos_input, wpostrans.xxxx, wpostrans.yyyy
4339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
4340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ureg_MAD( ureg,
4341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ),
4342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                wpos_input,
4343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                ureg_scalar(wpostrans, 0),
4344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                ureg_scalar(wpostrans, 1));
4345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
4346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* MAD wpos_temp.y, wpos_input, wpostrans.zzzz, wpostrans.wwww
4347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
4348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ureg_MAD( ureg,
4349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ),
4350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                wpos_input,
4351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                ureg_scalar(wpostrans, 2),
4352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                ureg_scalar(wpostrans, 3));
4353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Use wpos_temp as position input from here on:
4356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
4357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]] = ureg_src(wpos_temp);
4358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
4362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Emit fragment position/ooordinate code.
4363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
4364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
4365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgemit_wpos(struct st_context *st,
4366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          struct st_translate *t,
4367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          const struct gl_program *program,
4368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          struct ureg_program *ureg)
4369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
4370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct gl_fragment_program *fp =
4371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (const struct gl_fragment_program *) program;
4372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_screen *pscreen = st->pipe->screen;
4373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat adjX = 0.0f;
4374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat adjY[2] = { 0.0f, 0.0f };
4375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean invert = FALSE;
4376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Query the pixel center conventions supported by the pipe driver and set
4378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * adjX, adjY to help out if it cannot handle the requested one internally.
4379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
4380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * The bias of the y-coordinate depends on whether y-inversion takes place
4381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * (adjY[1]) or not (adjY[0]), which is in turn dependent on whether we are
4382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * drawing to an FBO (causes additional inversion), and whether the the pipe
4383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * driver origin and the requested origin differ (the latter condition is
4384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * stored in the 'invert' variable).
4385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
4386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * For height = 100 (i = integer, h = half-integer, l = lower, u = upper):
4387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
4388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * center shift only:
4389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * i -> h: +0.5
4390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * h -> i: -0.5
4391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
4392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * inversion only:
4393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * l,i -> u,i: ( 0.0 + 1.0) * -1 + 100 = 99
4394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * l,h -> u,h: ( 0.5 + 0.0) * -1 + 100 = 99.5
4395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * u,i -> l,i: (99.0 + 1.0) * -1 + 100 = 0
4396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * u,h -> l,h: (99.5 + 0.0) * -1 + 100 = 0.5
4397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
4398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * inversion and center shift:
4399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * l,i -> u,h: ( 0.0 + 0.5) * -1 + 100 = 99.5
4400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * l,h -> u,i: ( 0.5 + 0.5) * -1 + 100 = 99
4401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * u,i -> l,h: (99.0 + 0.5) * -1 + 100 = 0.5
4402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * u,h -> l,i: (99.5 + 0.5) * -1 + 100 = 0
4403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
4404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (fp->OriginUpperLeft) {
4405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Fragment shader wants origin in upper-left */
4406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT)) {
4407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* the driver supports upper-left origin */
4408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT)) {
4410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* the driver supports lower-left origin, need to invert Y */
4411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ureg_property_fs_coord_origin(ureg, TGSI_FS_COORD_ORIGIN_LOWER_LEFT);
4412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         invert = TRUE;
4413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
4415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(0);
4416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
4418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Fragment shader wants origin in lower-left */
4419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT))
4420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* the driver supports lower-left origin */
4421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ureg_property_fs_coord_origin(ureg, TGSI_FS_COORD_ORIGIN_LOWER_LEFT);
4422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT))
4423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* the driver supports upper-left origin, need to invert Y */
4424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         invert = TRUE;
4425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
4426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(0);
4427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (fp->PixelCenterInteger) {
4430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Fragment shader wants pixel center integer */
4431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) {
4432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* the driver supports pixel center integer */
4433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         adjY[1] = 1.0f;
4434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER);
4435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) {
4437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* the driver supports pixel center half integer, need to bias X,Y */
4438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         adjX = -0.5f;
4439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         adjY[0] = -0.5f;
4440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         adjY[1] = 0.5f;
4441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
4443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(0);
4444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
4446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Fragment shader wants pixel center half integer */
4447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) {
4448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* the driver supports pixel center half integer */
4449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) {
4451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* the driver supports pixel center integer, need to bias X,Y */
4452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         adjX = adjY[0] = adjY[1] = 0.5f;
4453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER);
4454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
4456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(0);
4457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* we invert after adjustment so that we avoid the MOV to temporary,
4460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * and reuse the adjustment ADD instead */
4461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit_wpos_adjustment(t, program, invert, adjX, adjY);
4462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
4465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OpenGL's fragment gl_FrontFace input is 1 for front-facing, 0 for back.
4466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TGSI uses +1 for front, -1 for back.
4467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This function converts the TGSI value to the GL value.  Simply clamping/
4468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * saturating the value to [0,1] does the job.
4469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
4470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
4471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgemit_face_var(struct st_translate *t)
4472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
4473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_program *ureg = t->ureg;
4474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_dst face_temp = ureg_DECL_temporary(ureg);
4475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_src face_input = t->inputs[t->inputMapping[FRAG_ATTRIB_FACE]];
4476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* MOV_SAT face_temp, input[face] */
4478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   face_temp = ureg_saturate(face_temp);
4479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ureg_MOV(ureg, face_temp, face_input);
4480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Use face_temp as face input from here on: */
4482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   t->inputs[t->inputMapping[FRAG_ATTRIB_FACE]] = ureg_src(face_temp);
4483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
4486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgemit_edgeflags(struct st_translate *t)
4487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
4488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_program *ureg = t->ureg;
4489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_dst edge_dst = t->outputs[t->outputMapping[VERT_RESULT_EDGE]];
4490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_src edge_src = t->inputs[t->inputMapping[VERT_ATTRIB_EDGEFLAG]];
4491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ureg_MOV(ureg, edge_dst, edge_src);
4493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
4496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Translate intermediate IR (glsl_to_tgsi_instruction) to TGSI format.
4497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param program  the program to translate
4498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param numInputs  number of input registers used
4499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param inputMapping  maps Mesa fragment program inputs to TGSI generic
4500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *                      input indexes
4501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param inputSemanticName  the TGSI_SEMANTIC flag for each input
4502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param inputSemanticIndex  the semantic index (ex: which texcoord) for
4503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *                            each input
4504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param interpMode  the TGSI_INTERPOLATE_LINEAR/PERSP mode for each input
4505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param numOutputs  number of output registers used
4506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param outputMapping  maps Mesa fragment program outputs to TGSI
4507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *                       generic outputs
4508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param outputSemanticName  the TGSI_SEMANTIC flag for each output
4509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param outputSemanticIndex  the semantic index (ex: which texcoord) for
4510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *                             each output
4511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
4512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \return  PIPE_OK or PIPE_ERROR_OUT_OF_MEMORY
4513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
4514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern "C" enum pipe_error
4515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_translate_program(
4516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_context *ctx,
4517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint procType,
4518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct ureg_program *ureg,
4519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glsl_to_tgsi_visitor *program,
4520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct gl_program *proginfo,
4521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint numInputs,
4522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLuint inputMapping[],
4523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const ubyte inputSemanticName[],
4524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const ubyte inputSemanticIndex[],
4525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLuint interpMode[],
4526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLboolean is_centroid[],
4527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint numOutputs,
4528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLuint outputMapping[],
4529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const ubyte outputSemanticName[],
4530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const ubyte outputSemanticIndex[],
4531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean passthrough_edgeflags,
4532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean clamp_color)
4533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
4534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct st_translate *t;
4535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i;
4536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   enum pipe_error ret = PIPE_OK;
4537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(numInputs <= Elements(t->inputs));
4539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(numOutputs <= Elements(t->outputs));
4540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   t = CALLOC_STRUCT(st_translate);
4542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!t) {
4543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ret = PIPE_ERROR_OUT_OF_MEMORY;
4544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto out;
4545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(t, 0, sizeof *t);
4548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   t->procType = procType;
4550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   t->inputMapping = inputMapping;
4551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   t->outputMapping = outputMapping;
4552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   t->ureg = ureg;
4553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (program->shader_program) {
4555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < program->shader_program->NumUserUniformStorage; i++) {
4556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         struct gl_uniform_storage *const storage =
4557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               &program->shader_program->UniformStorage[i];
4558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_uniform_detach_all_driver_storage(storage);
4560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
4564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Declare input attributes.
4565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
4566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (procType == TGSI_PROCESSOR_FRAGMENT) {
4567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < numInputs; i++) {
4568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         t->inputs[i] = ureg_DECL_fs_input_cyl_centroid(ureg,
4569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                        inputSemanticName[i],
4570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                        inputSemanticIndex[i],
4571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                        interpMode[i], 0,
4572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                        is_centroid[i]);
4573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (proginfo->InputsRead & FRAG_BIT_WPOS) {
4576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Must do this after setting up t->inputs, and before
4577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * emitting constant references, below:
4578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
4579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          emit_wpos(st_context(ctx), t, proginfo, ureg);
4580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (proginfo->InputsRead & FRAG_BIT_FACE)
4583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit_face_var(t);
4584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*
4586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Declare output attributes.
4587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
4588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < numOutputs; i++) {
4589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         switch (outputSemanticName[i]) {
4590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         case TGSI_SEMANTIC_POSITION:
4591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            t->outputs[i] = ureg_DECL_output(ureg,
4592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                             TGSI_SEMANTIC_POSITION, /* Z/Depth */
4593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                             outputSemanticIndex[i]);
4594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            t->outputs[i] = ureg_writemask(t->outputs[i], TGSI_WRITEMASK_Z);
4595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
4596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         case TGSI_SEMANTIC_STENCIL:
4597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            t->outputs[i] = ureg_DECL_output(ureg,
4598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                             TGSI_SEMANTIC_STENCIL, /* Stencil */
4599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                             outputSemanticIndex[i]);
4600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            t->outputs[i] = ureg_writemask(t->outputs[i], TGSI_WRITEMASK_Y);
4601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
4602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         case TGSI_SEMANTIC_COLOR:
4603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            t->outputs[i] = ureg_DECL_output(ureg,
4604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                             TGSI_SEMANTIC_COLOR,
4605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                             outputSemanticIndex[i]);
4606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
4607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         default:
4608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            assert(!"fragment shader outputs must be POSITION/STENCIL/COLOR");
4609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            ret = PIPE_ERROR_BAD_INPUT;
4610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            goto out;
4611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
4612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (procType == TGSI_PROCESSOR_GEOMETRY) {
4615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < numInputs; i++) {
4616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         t->inputs[i] = ureg_DECL_gs_input(ureg,
4617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           i,
4618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           inputSemanticName[i],
4619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           inputSemanticIndex[i]);
4620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < numOutputs; i++) {
4623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         t->outputs[i] = ureg_DECL_output(ureg,
4624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          outputSemanticName[i],
4625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          outputSemanticIndex[i]);
4626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
4629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(procType == TGSI_PROCESSOR_VERTEX);
4630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < numInputs; i++) {
4632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         t->inputs[i] = ureg_DECL_vs_input(ureg, i);
4633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < numOutputs; i++) {
4636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         t->outputs[i] = ureg_DECL_output(ureg,
4637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          outputSemanticName[i],
4638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          outputSemanticIndex[i]);
4639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (passthrough_edgeflags)
4641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         emit_edgeflags(t);
4642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Declare address register.
4645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
4646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (program->num_address_regs > 0) {
4647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(program->num_address_regs == 1);
4648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      t->address[0] = ureg_DECL_address(ureg);
4649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Declare misc input registers
4652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
4653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
4654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLbitfield sysInputs = proginfo->SystemValuesRead;
4655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned numSys = 0;
4656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; sysInputs; i++) {
4657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (sysInputs & (1 << i)) {
4658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            unsigned semName = mesa_sysval_to_semantic[i];
4659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            t->systemValues[i] = ureg_DECL_system_value(ureg, numSys, semName, 0);
4660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (semName == TGSI_SEMANTIC_INSTANCEID ||
4661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                semName == TGSI_SEMANTIC_VERTEXID) {
4662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               /* From Gallium perspective, these system values are always
4663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                * integer, and require native integer support.  However, if
4664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                * native integer is supported on the vertex stage but not the
4665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                * pixel stage (e.g, i915g + draw), Mesa will generate IR that
4666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                * assumes these system values are floats. To resolve the
4667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                * inconsistency, we insert a U2F.
4668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                */
4669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               struct st_context *st = st_context(ctx);
4670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               struct pipe_screen *pscreen = st->pipe->screen;
4671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               assert(procType == TGSI_PROCESSOR_VERTEX);
4672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               assert(pscreen->get_shader_param(pscreen, PIPE_SHADER_VERTEX, PIPE_SHADER_CAP_INTEGERS));
4673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               if (!ctx->Const.NativeIntegers) {
4674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  struct ureg_dst temp = ureg_DECL_local_temporary(t->ureg);
4675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  ureg_U2F( t->ureg, ureg_writemask(temp, TGSI_WRITEMASK_X), t->systemValues[i]);
4676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  t->systemValues[i] = ureg_scalar(ureg_src(temp), 0);
4677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               }
4678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
4679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            numSys++;
4680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sysInputs &= ~(1 << i);
4681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
4682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (program->indirect_addr_temps) {
4686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* If temps are accessed with indirect addressing, declare temporaries
4687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * in sequential order.  Else, we declare them on demand elsewhere.
4688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * (Note: the number of temporaries is equal to program->next_temp)
4689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
4690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < (unsigned)program->next_temp; i++) {
4691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* XXX use TGSI_FILE_TEMPORARY_ARRAY when it's supported by ureg */
4692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         t->temps[i] = ureg_DECL_local_temporary(t->ureg);
4693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Emit constants and uniforms.  TGSI uses a single index space for these,
4697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * so we put all the translated regs in t->constants.
4698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
4699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (proginfo->Parameters) {
4700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      t->constants = (struct ureg_src *)CALLOC(proginfo->Parameters->NumParameters * sizeof(t->constants[0]));
4701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (t->constants == NULL) {
4702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ret = PIPE_ERROR_OUT_OF_MEMORY;
4703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         goto out;
4704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < proginfo->Parameters->NumParameters; i++) {
4707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         switch (proginfo->Parameters->Parameters[i].Type) {
4708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         case PROGRAM_ENV_PARAM:
4709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         case PROGRAM_LOCAL_PARAM:
4710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         case PROGRAM_STATE_VAR:
4711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         case PROGRAM_NAMED_PARAM:
4712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         case PROGRAM_UNIFORM:
4713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            t->constants[i] = ureg_DECL_constant(ureg, i);
4714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
4715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Emit immediates for PROGRAM_CONSTANT only when there's no indirect
4717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * addressing of the const buffer.
4718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * FIXME: Be smarter and recognize param arrays:
4719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * indirect addressing is only valid within the referenced
4720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * array.
4721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
4722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         case PROGRAM_CONSTANT:
4723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (program->indirect_addr_consts)
4724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               t->constants[i] = ureg_DECL_constant(ureg, i);
4725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            else
4726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               t->constants[i] = emit_immediate(t,
4727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                proginfo->Parameters->ParameterValues[i],
4728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                proginfo->Parameters->Parameters[i].DataType,
4729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                4);
4730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
4731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         default:
4732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
4733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
4734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Emit immediate values.
4738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
4739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   t->immediates = (struct ureg_src *)CALLOC(program->num_immediates * sizeof(struct ureg_src));
4740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (t->immediates == NULL) {
4741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ret = PIPE_ERROR_OUT_OF_MEMORY;
4742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto out;
4743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i = 0;
4745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_iter(exec_list_iterator, iter, program->immediates) {
4746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      immediate_storage *imm = (immediate_storage *)iter.get();
4747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(i < program->num_immediates);
4748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      t->immediates[i++] = emit_immediate(t, imm->values, imm->type, imm->size);
4749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(i == program->num_immediates);
4751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* texture samplers */
4753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
4754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (program->samplers_used & (1 << i)) {
4755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         t->samplers[i] = ureg_DECL_sampler(ureg, i);
4756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Emit each instruction in turn:
4760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
4761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_iter(exec_list_iterator, iter, program->instructions) {
4762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      set_insn_start(t, ureg_get_instruction_number(ureg));
4763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      compile_tgsi_instruction(t, (glsl_to_tgsi_instruction *)iter.get(),
4764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               clamp_color);
4765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Fix up all emitted labels:
4768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
4769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < t->labels_count; i++) {
4770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ureg_fixup_label(ureg, t->labels[i].token,
4771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       t->insn[t->labels[i].branch_target]);
4772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (program->shader_program) {
4775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* This has to be done last.  Any operation the can cause
4776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * prog->ParameterValues to get reallocated (e.g., anything that adds a
4777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * program constant) has to happen before creating this linkage.
4778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
4779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
4780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (program->shader_program->_LinkedShaders[i] == NULL)
4781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            continue;
4782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_associate_uniform_storage(ctx, program->shader_program,
4784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               program->shader_program->_LinkedShaders[i]->Program->Parameters);
4785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgout:
4789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (t) {
4790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      FREE(t->insn);
4791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      FREE(t->labels);
4792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      FREE(t->constants);
4793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      FREE(t->immediates);
4794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (t->error) {
4796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         debug_printf("%s: translate error flag set\n", __FUNCTION__);
4797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      FREE(t);
4800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return ret;
4803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* ----------------------------- End TGSI code ------------------------------ */
4805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
4807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Convert a shader's GLSL IR into a Mesa gl_program, although without
4808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * generating Mesa IR.
4809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
4810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct gl_program *
4811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_mesa_program(struct gl_context *ctx,
4812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 struct gl_shader_program *shader_program,
4813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 struct gl_shader *shader)
4814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
4815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glsl_to_tgsi_visitor* v;
4816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_program *prog;
4817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLenum target;
4818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const char *target_string;
4819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bool progress;
4820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_shader_compiler_options *options =
4821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(shader->Type)];
4822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (shader->Type) {
4824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_VERTEX_SHADER:
4825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      target = GL_VERTEX_PROGRAM_ARB;
4826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      target_string = "vertex";
4827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
4828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_FRAGMENT_SHADER:
4829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      target = GL_FRAGMENT_PROGRAM_ARB;
4830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      target_string = "fragment";
4831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
4832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_GEOMETRY_SHADER:
4833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      target = GL_GEOMETRY_PROGRAM_NV;
4834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      target_string = "geometry";
4835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
4836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
4837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(!"should not be reached");
4838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
4839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   validate_ir_tree(shader->ir);
4842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   prog = ctx->Driver.NewProgram(ctx, target, shader_program->Name);
4844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!prog)
4845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
4846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   prog->Parameters = _mesa_new_parameter_list();
4847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v = new glsl_to_tgsi_visitor();
4848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->ctx = ctx;
4849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->prog = prog;
4850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->shader_program = shader_program;
4851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->options = options;
4852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->glsl_version = ctx->Const.GLSLVersion;
4853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->native_integers = ctx->Const.NativeIntegers;
4854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _mesa_generate_parameters_list_for_uniforms(shader_program, shader,
4856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					       prog->Parameters);
4857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Remove reads from output registers. */
4859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lower_output_reads(shader->ir);
4860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Emit intermediate IR for main(). */
4862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   visit_exec_list(shader->ir, v);
4863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Now emit bodies for any functions that were used. */
4865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   do {
4866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      progress = GL_FALSE;
4867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      foreach_iter(exec_list_iterator, iter, v->function_signatures) {
4869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         function_entry *entry = (function_entry *)iter.get();
4870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!entry->bgn_inst) {
4872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            v->current_function = entry;
4873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            entry->bgn_inst = v->emit(NULL, TGSI_OPCODE_BGNSUB);
4875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            entry->bgn_inst->function = entry;
4876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            visit_exec_list(&entry->sig->body, v);
4878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            glsl_to_tgsi_instruction *last;
4880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            last = (glsl_to_tgsi_instruction *)v->instructions.get_tail();
4881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (last->op != TGSI_OPCODE_RET)
4882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               v->emit(NULL, TGSI_OPCODE_RET);
4883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            glsl_to_tgsi_instruction *end;
4885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            end = v->emit(NULL, TGSI_OPCODE_ENDSUB);
4886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            end->function = entry;
4887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            progress = GL_TRUE;
4889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
4890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
4891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } while (progress);
4892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0
4894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Print out some information (for debugging purposes) used by the
4895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * optimization passes. */
4896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i=0; i < v->next_temp; i++) {
4897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int fr = v->get_first_temp_read(i);
4898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int fw = v->get_first_temp_write(i);
4899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int lr = v->get_last_temp_read(i);
4900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int lw = v->get_last_temp_write(i);
4901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("Temp %d: FR=%3d FW=%3d LR=%3d LW=%3d\n", i, fr, fw, lr, lw);
4903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(fw <= fr);
4904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
4906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Perform optimizations on the instructions in the glsl_to_tgsi_visitor. */
4908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->simplify_cmp();
4909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->copy_propagate();
4910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   while (v->eliminate_dead_code_advanced());
4911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* FIXME: These passes to optimize temporary registers don't work when there
4913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * is indirect addressing of the temporary register space.  We need proper
4914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * array support so that we don't have to give up these passes in every
4915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * shader that uses arrays.
4916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
4917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!v->indirect_addr_temps) {
4918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      v->eliminate_dead_code();
4919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      v->merge_registers();
4920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      v->renumber_registers();
4921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Write the END instruction. */
4924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v->emit(NULL, TGSI_OPCODE_END);
4925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ctx->Shader.Flags & GLSL_DUMP) {
4927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("\n");
4928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("GLSL IR for linked %s program %d:\n", target_string,
4929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             shader_program->Name);
4930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_print_ir(shader->ir, NULL);
4931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("\n");
4932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("\n");
4933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fflush(stdout);
4934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   prog->Instructions = NULL;
4937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   prog->NumInstructions = 0;
4938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   do_set_program_inouts(shader->ir, prog, shader->Type == GL_FRAGMENT_SHADER);
4940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   count_resources(v, prog);
4941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _mesa_reference_program(ctx, &shader->Program, prog);
4943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* This has to be done last.  Any operation the can cause
4945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * prog->ParameterValues to get reallocated (e.g., anything that adds a
4946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * program constant) has to happen before creating this linkage.
4947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
4948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _mesa_associate_uniform_storage(ctx, shader_program, prog->Parameters);
4949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!shader_program->LinkStatus) {
4950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
4951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct st_vertex_program *stvp;
4954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct st_fragment_program *stfp;
4955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct st_geometry_program *stgp;
4956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (shader->Type) {
4958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_VERTEX_SHADER:
4959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      stvp = (struct st_vertex_program *)prog;
4960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      stvp->glsl_to_tgsi = v;
4961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
4962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_FRAGMENT_SHADER:
4963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      stfp = (struct st_fragment_program *)prog;
4964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      stfp->glsl_to_tgsi = v;
4965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
4966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_GEOMETRY_SHADER:
4967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      stgp = (struct st_geometry_program *)prog;
4968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      stgp->glsl_to_tgsi = v;
4969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
4970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
4971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(!"should not be reached");
4972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
4973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return prog;
4976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern "C" {
4979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct gl_shader *
4981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_new_shader(struct gl_context *ctx, GLuint name, GLuint type)
4982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
4983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_shader *shader;
4984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER ||
4985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          type == GL_GEOMETRY_SHADER_ARB);
4986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   shader = rzalloc(NULL, struct gl_shader);
4987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (shader) {
4988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shader->Type = type;
4989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shader->Name = name;
4990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_init_shader(ctx, shader);
4991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
4992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return shader;
4993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
4994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct gl_shader_program *
4996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_new_shader_program(struct gl_context *ctx, GLuint name)
4997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
4998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_shader_program *shProg;
4999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   shProg = rzalloc(NULL, struct gl_shader_program);
5000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (shProg) {
5001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shProg->Name = name;
5002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_init_shader_program(ctx, shProg);
5003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
5004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return shProg;
5005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
5006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
5007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
5008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Link a shader.
5009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Called via ctx->Driver.LinkShader()
5010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This actually involves converting GLSL IR into an intermediate TGSI-like IR
5011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * with code lowering and other optimizations.
5012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
5013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgGLboolean
5014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
5015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
5016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(prog->LinkStatus);
5017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
5018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
5019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (prog->_LinkedShaders[i] == NULL)
5020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         continue;
5021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
5022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      bool progress;
5023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      exec_list *ir = prog->_LinkedShaders[i]->ir;
5024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const struct gl_shader_compiler_options *options =
5025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(prog->_LinkedShaders[i]->Type)];
5026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
5027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      do {
5028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         unsigned what_to_lower = MOD_TO_FRACT | DIV_TO_MUL_RCP |
5029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            EXP_TO_EXP2 | LOG_TO_LOG2;
5030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (options->EmitNoPow)
5031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            what_to_lower |= POW_TO_EXP2;
5032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!ctx->Const.NativeIntegers)
5033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            what_to_lower |= INT_DIV_TO_MUL_RCP;
5034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
5035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         progress = false;
5036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
5037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Lowering */
5038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         do_mat_op_to_vec(ir);
5039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lower_instructions(ir, what_to_lower);
5040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
5041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         progress = do_lower_jumps(ir, true, true, options->EmitNoMainReturn, options->EmitNoCont, options->EmitNoLoops) || progress;
5042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
5043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         progress = do_common_optimization(ir, true, true,
5044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					   options->MaxUnrollIterations)
5045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   || progress;
5046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
5047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         progress = lower_quadop_vector(ir, false) || progress;
5048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
5049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (options->MaxIfDepth == 0)
5050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            progress = lower_discard(ir) || progress;
5051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
5052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         progress = lower_if_to_cond_assign(ir, options->MaxIfDepth) || progress;
5053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
5054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (options->EmitNoNoise)
5055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            progress = lower_noise(ir) || progress;
5056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
5057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* If there are forms of indirect addressing that the driver
5058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * cannot handle, perform the lowering pass.
5059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
5060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (options->EmitNoIndirectInput || options->EmitNoIndirectOutput
5061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             || options->EmitNoIndirectTemp || options->EmitNoIndirectUniform)
5062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           progress =
5063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             lower_variable_index_to_cond_assign(ir,
5064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        					 options->EmitNoIndirectInput,
5065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        					 options->EmitNoIndirectOutput,
5066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        					 options->EmitNoIndirectTemp,
5067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        					 options->EmitNoIndirectUniform)
5068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             || progress;
5069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
5070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         progress = do_vec_index_to_cond_assign(ir) || progress;
5071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } while (progress);
5072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
5073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      validate_ir_tree(ir);
5074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
5075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
5076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
5077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct gl_program *linked_prog;
5078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
5079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (prog->_LinkedShaders[i] == NULL)
5080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         continue;
5081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
5082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]);
5083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
5084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (linked_prog) {
5085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 static const GLenum targets[] = {
5086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    GL_VERTEX_PROGRAM_ARB,
5087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    GL_FRAGMENT_PROGRAM_ARB,
5088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    GL_GEOMETRY_PROGRAM_NV
5089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 };
5090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
5091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 _mesa_reference_program(ctx, &prog->_LinkedShaders[i]->Program,
5092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 linked_prog);
5093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!ctx->Driver.ProgramStringNotify(ctx, targets[i], linked_prog)) {
5094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_reference_program(ctx, &prog->_LinkedShaders[i]->Program,
5095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				    NULL);
5096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            _mesa_reference_program(ctx, &linked_prog, NULL);
5097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return GL_FALSE;
5098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
5099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
5100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
5101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_reference_program(ctx, &linked_prog, NULL);
5102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
5103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
5104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return GL_TRUE;
5105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
5106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
5107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
5108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_translate_stream_output_info(glsl_to_tgsi_visitor *glsl_to_tgsi,
5109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                const GLuint outputMapping[],
5110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                struct pipe_stream_output_info *so)
5111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
5112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i;
5113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_transform_feedback_info *info =
5114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      &glsl_to_tgsi->shader_program->LinkedTransformFeedback;
5115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
5116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < info->NumOutputs; i++) {
5117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      so->output[i].register_index =
5118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         outputMapping[info->Outputs[i].OutputRegister];
5119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      so->output[i].start_component = info->Outputs[i].ComponentOffset;
5120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      so->output[i].num_components = info->Outputs[i].NumComponents;
5121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      so->output[i].output_buffer = info->Outputs[i].OutputBuffer;
5122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      so->output[i].dst_offset = info->Outputs[i].DstOffset;
5123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
5124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
5125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < PIPE_MAX_SO_BUFFERS; i++) {
5126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      so->stride[i] = info->BufferStride[i];
5127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
5128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   so->num_outputs = info->NumOutputs;
5129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
5130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
5131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} /* extern "C" */
5132