1d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/*
2d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * Copyright © 2010 Intel Corporation
3d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt *
4d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * Permission is hereby granted, free of charge, to any person obtaining a
5d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * copy of this software and associated documentation files (the "Software"),
6d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * to deal in the Software without restriction, including without limitation
7d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * and/or sell copies of the Software, and to permit persons to whom the
9d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * Software is furnished to do so, subject to the following conditions:
10d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt *
11d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * The above copyright notice and this permission notice (including the next
12d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * paragraph) shall be included in all copies or substantial portions of the
13d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * Software.
14d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt *
15d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * IN THE SOFTWARE.
22d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */
23d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
24d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/** @file brw_fs_visitor.cpp
25d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt *
26d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * This file supports generating the FS LIR from the GLSL IR.  The LIR
27d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * makes it easier to do backend-specific optimizations than doing so
28d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * in the GLSL IR or in the native code.
29d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */
30d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtextern "C" {
31d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
32d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include <sys/types.h>
33d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
34d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "main/macros.h"
35d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "main/shaderobj.h"
36d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "main/uniforms.h"
37d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "program/prog_parameter.h"
38d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "program/prog_print.h"
39d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "program/prog_optimize.h"
40d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "program/register_allocate.h"
41d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "program/sampler.h"
42d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "program/hash_table.h"
43d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "brw_context.h"
44d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "brw_eu.h"
45d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "brw_wm.h"
46d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
47d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "brw_shader.h"
48d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt#include "brw_fs.h"
492f0edc60f4bd2ae5999a6afa656e3bb3f181bf0fChad Versace#include "glsl/glsl_types.h"
502f0edc60f4bd2ae5999a6afa656e3bb3f181bf0fChad Versace#include "glsl/ir_optimization.h"
512f0edc60f4bd2ae5999a6afa656e3bb3f181bf0fChad Versace#include "glsl/ir_print_visitor.h"
52d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
53d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
54d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_variable *ir)
55d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
56d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg *reg = NULL;
57d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
58d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (variable_storage(ir))
59d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      return;
60d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
61d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->mode == ir_var_in) {
62d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (!strcmp(ir->name, "gl_FragCoord")) {
63d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 reg = emit_fragcoord_interpolation(ir);
64d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      } else if (!strcmp(ir->name, "gl_FrontFacing")) {
65d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 reg = emit_frontfacing_interpolation(ir);
66d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      } else {
67d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 reg = emit_general_interpolation(ir);
68d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
69d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(reg);
70d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      hash_table_insert(this->variable_ht, reg, ir);
71d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      return;
726d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt   } else if (ir->mode == ir_var_out) {
736d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt      reg = new(this->mem_ctx) fs_reg(this, ir->type);
74d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
7529362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt      if (ir->index > 0) {
7629362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt	 assert(ir->location == FRAG_RESULT_DATA0);
7729362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt	 assert(ir->index == 1);
7829362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt	 this->dual_src_output = *reg;
7929362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt      } else if (ir->location == FRAG_RESULT_COLOR) {
806d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt	 /* Writing gl_FragColor outputs to all color regions. */
811e188f2daef1ae31224d2429bcc1fab75c81fb36Eric Anholt	 for (unsigned int i = 0; i < MAX2(c->key.nr_color_regions, 1); i++) {
826d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt	    this->outputs[i] = *reg;
832f18698220d8b27991fab550c4721590d17278e0Kenneth Graunke	    this->output_components[i] = 4;
846d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt	 }
856d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt      } else if (ir->location == FRAG_RESULT_DEPTH) {
866d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt	 this->frag_depth = ir;
876d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt      } else {
886d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt	 /* gl_FragData or a user-defined FS output */
896d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt	 assert(ir->location >= FRAG_RESULT_DATA0 &&
906d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt		ir->location < FRAG_RESULT_DATA0 + BRW_MAX_DRAW_BUFFERS);
916d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt
922f18698220d8b27991fab550c4721590d17278e0Kenneth Graunke	 int vector_elements =
932f18698220d8b27991fab550c4721590d17278e0Kenneth Graunke	    ir->type->is_array() ? ir->type->fields.array->vector_elements
942f18698220d8b27991fab550c4721590d17278e0Kenneth Graunke				 : ir->type->vector_elements;
952f18698220d8b27991fab550c4721590d17278e0Kenneth Graunke
966d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt	 /* General color output. */
976d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt	 for (unsigned int i = 0; i < MAX2(1, ir->type->length); i++) {
986d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt	    int output = ir->location - FRAG_RESULT_DATA0 + i;
996d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt	    this->outputs[output] = *reg;
1002f18698220d8b27991fab550c4721590d17278e0Kenneth Graunke	    this->outputs[output].reg_offset += vector_elements * i;
1012f18698220d8b27991fab550c4721590d17278e0Kenneth Graunke	    this->output_components[output] = vector_elements;
1026d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt	 }
1036d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt      }
1046d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt   } else if (ir->mode == ir_var_uniform) {
105d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      int param_index = c->prog_data.nr_params;
106d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
10790de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt      /* Thanks to the lower_ubo_reference pass, we will see only
10890de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt       * ir_binop_ubo_load expressions and not ir_dereference_variable for UBO
10990de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt       * variables, so no need for them to be in variable_ht.
11090de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt       */
11190de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt      if (ir->uniform_block != -1)
11290de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt         return;
11390de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt
114d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (c->dispatch_width == 16) {
115d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 if (!variable_storage(ir)) {
116d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    fail("Failed to find uniform '%s' in 16-wide\n", ir->name);
117d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 }
118d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 return;
119d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
120d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
121d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (!strncmp(ir->name, "gl_", 3)) {
122d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 setup_builtin_uniform_values(ir);
123d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      } else {
124d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 setup_uniform_values(ir->location, ir->type);
125d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
126d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
127d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      reg = new(this->mem_ctx) fs_reg(UNIFORM, param_index);
128d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      reg->type = brw_type_for_base_type(ir->type);
129d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
130d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
131d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (!reg)
132d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      reg = new(this->mem_ctx) fs_reg(this, ir->type);
133d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
134d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   hash_table_insert(this->variable_ht, reg, ir);
135d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
136d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
137d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
138d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_dereference_variable *ir)
139d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
140d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg *reg = variable_storage(ir->var);
141d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->result = *reg;
142d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
143d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
144d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
145d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_dereference_record *ir)
146d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
147d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   const glsl_type *struct_type = ir->record->type;
148d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
149d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir->record->accept(this);
150d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
151d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   unsigned int offset = 0;
152d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   for (unsigned int i = 0; i < struct_type->length; i++) {
153d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0)
154d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
155d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      offset += type_size(struct_type->fields.structure[i].type);
156d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
157d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->result.reg_offset += offset;
158d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->result.type = brw_type_for_base_type(ir->type);
159d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
160d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
161d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
162d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_dereference_array *ir)
163d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
164d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir_constant *index;
165d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int element_size;
166d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
167d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir->array->accept(this);
168d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   index = ir->array_index->as_constant();
169d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
170d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   element_size = type_size(ir->type);
171d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->result.type = brw_type_for_base_type(ir->type);
172d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
173d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (index) {
174b76378d46a211521582cfab56dc05031a57502a6Eric Anholt      assert(this->result.file == UNIFORM || this->result.file == GRF);
175d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->result.reg_offset += index->value.i[0] * element_size;
176d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else {
177d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!"FINISHME: non-constant array element");
178d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
179d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
180d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
181d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/* Instruction selection: Produce a MOV.sat instead of
182d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * MIN(MAX(val, 0), 1) when possible.
183d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */
184d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtbool
185d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::try_emit_saturate(ir_expression *ir)
186d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
187d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir_rvalue *sat_val = ir->as_rvalue_to_saturate();
188d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
189d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (!sat_val)
190d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      return false;
191d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
19232ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt   fs_inst *pre_inst = (fs_inst *) this->instructions.get_tail();
19332ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt
194d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   sat_val->accept(this);
195d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg src = this->result;
196d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
19732ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt   fs_inst *last_inst = (fs_inst *) this->instructions.get_tail();
19832ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt
19932ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt   /* If the last instruction from our accept() didn't generate our
20032ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt    * src, generate a saturated MOV
20132ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt    */
20232ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt   fs_inst *modify = get_instruction_generating_reg(pre_inst, last_inst, src);
20332ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt   if (!modify || modify->regs_written() != 1) {
2040ba14013f66c03c6a3cc0a5e3ef74e92bfe5afb9Eric Anholt      this->result = fs_reg(this, ir->type);
20532ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt      fs_inst *inst = emit(BRW_OPCODE_MOV, this->result, src);
20632ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt      inst->saturate = true;
20732ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt   } else {
20832ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt      modify->saturate = true;
20932ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt      this->result = src;
21032ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt   }
21132ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt
212d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
213d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   return true;
214d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
215d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
2167d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholtbool
2177d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholtfs_visitor::try_emit_mad(ir_expression *ir, int mul_arg)
2187d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt{
2197d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt   /* 3-src instructions were introduced in gen6. */
2207d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt   if (intel->gen < 6)
2217d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt      return false;
2227d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt
2237d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt   /* MAD can only handle floating-point data. */
2247d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt   if (ir->type != glsl_type::float_type)
2257d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt      return false;
2267d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt
2277d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt   ir_rvalue *nonmul = ir->operands[1 - mul_arg];
2287d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt   ir_expression *mul = ir->operands[mul_arg]->as_expression();
2297d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt
2307d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt   if (!mul || mul->operation != ir_binop_mul)
2317d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt      return false;
2327d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt
2337d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt   if (nonmul->as_constant() ||
2347d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt       mul->operands[0]->as_constant() ||
2357d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt       mul->operands[1]->as_constant())
2367d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt      return false;
2377d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt
2387d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt   nonmul->accept(this);
2397d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt   fs_reg src0 = this->result;
2407d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt
2417d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt   mul->operands[0]->accept(this);
2427d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt   fs_reg src1 = this->result;
2437d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt
2447d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt   mul->operands[1]->accept(this);
2457d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt   fs_reg src2 = this->result;
2467d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt
2477d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt   this->result = fs_reg(this, ir->type);
2487d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt   emit(BRW_OPCODE_MAD, this->result, src0, src1, src2);
2497d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt
2507d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt   return true;
2517d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt}
2527d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt
253d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
254d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_expression *ir)
255d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
256d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   unsigned int operand;
257d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg op[2], temp;
258d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *inst;
259d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
260d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   assert(ir->get_num_operands() <= 2);
261d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
262d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (try_emit_saturate(ir))
263d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      return;
2647d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt   if (ir->operation == ir_binop_add) {
2657d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt      if (try_emit_mad(ir, 0) || try_emit_mad(ir, 1))
2667d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt	 return;
2677d55f37b0e87db9b3806088797075161a1c9a8bbEric Anholt   }
268d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
269d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   for (operand = 0; operand < ir->get_num_operands(); operand++) {
270d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->operands[operand]->accept(this);
271d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (this->result.file == BAD_FILE) {
272d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 ir_print_visitor v;
273d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 fail("Failed to get tree for expression operand:\n");
274d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 ir->operands[operand]->accept(&v);
275d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
276d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      op[operand] = this->result;
277d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
278d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* Matrix expression operands should have been broken down to vector
279d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * operations already.
280d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       */
281d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!ir->operands[operand]->type->is_matrix());
282d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* And then those vector operands should have been broken down to scalar.
283d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       */
284d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!ir->operands[operand]->type->is_vector());
285d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
286d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
287d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke   /* Storage for our result.  If our result goes into an assignment, it will
288d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke    * just get copy-propagated out, so no worries.
289d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    */
290d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke   this->result = fs_reg(this, ir->type);
291d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
292d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   switch (ir->operation) {
293d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_logic_not:
294d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* Note that BRW_OPCODE_NOT is not appropriate here, since it is
295d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * ones complement of the whole register, not just bit 0.
296d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       */
297d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_XOR, this->result, op[0], fs_reg(1));
298d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
299d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_neg:
300d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      op[0].negate = !op[0].negate;
301d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->result = op[0];
302d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
303d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_abs:
304d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      op[0].abs = true;
305d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      op[0].negate = false;
306d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->result = op[0];
307d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
308d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_sign:
309d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      temp = fs_reg(this, ir->type);
310d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
311d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, this->result, fs_reg(0.0f));
312d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
313d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_CMP, reg_null_f, op[0], fs_reg(0.0f));
314d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->conditional_mod = BRW_CONDITIONAL_G;
315d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_MOV, this->result, fs_reg(1.0f));
316d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->predicated = true;
317d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
318d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_CMP, reg_null_f, op[0], fs_reg(0.0f));
319d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->conditional_mod = BRW_CONDITIONAL_L;
320d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_MOV, this->result, fs_reg(-1.0f));
321d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->predicated = true;
322d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
323d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
324d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_rcp:
32565b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt      emit_math(SHADER_OPCODE_RCP, this->result, op[0]);
326d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
327d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
328d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_exp2:
32965b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt      emit_math(SHADER_OPCODE_EXP2, this->result, op[0]);
330d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
331d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_log2:
33265b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt      emit_math(SHADER_OPCODE_LOG2, this->result, op[0]);
333d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
334d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_exp:
335d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_log:
336d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!"not reached: should be handled by ir_explog_to_explog2");
337d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
338d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_sin:
339d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_sin_reduced:
34065b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt      emit_math(SHADER_OPCODE_SIN, this->result, op[0]);
341d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
342d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_cos:
343d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_cos_reduced:
34465b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt      emit_math(SHADER_OPCODE_COS, this->result, op[0]);
345d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
346d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
347d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_dFdx:
348d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(FS_OPCODE_DDX, this->result, op[0]);
349d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
350d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_dFdy:
351d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(FS_OPCODE_DDY, this->result, op[0]);
352d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
353d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
354d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_add:
355d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_ADD, this->result, op[0], op[1]);
356d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
357d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_sub:
358d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!"not reached: should be handled by ir_sub_to_add_neg");
359d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
360d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
361d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_mul:
3623f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt      if (ir->type->is_integer()) {
3633f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	 /* For integer multiplication, the MUL uses the low 16 bits
3643f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	  * of one of the operands (src0 on gen6, src1 on gen7).  The
3653f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	  * MACH accumulates in the contribution of the upper 16 bits
3663f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	  * of that operand.
3673f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	  *
3683f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	  * FINISHME: Emit just the MUL if we know an operand is small
3693f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	  * enough.
3703f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	  */
37101044fce6b3de11635ea5078b76ffee1a33b3802Kenneth Graunke	 if (intel->gen >= 7 && c->dispatch_width == 16)
37201044fce6b3de11635ea5078b76ffee1a33b3802Kenneth Graunke	    fail("16-wide explicit accumulator operands unsupported\n");
37301044fce6b3de11635ea5078b76ffee1a33b3802Kenneth Graunke
3743f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	 struct brw_reg acc = retype(brw_acc_reg(), BRW_REGISTER_TYPE_D);
3753f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt
3763f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	 emit(BRW_OPCODE_MUL, acc, op[0], op[1]);
3773f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	 emit(BRW_OPCODE_MACH, reg_null_d, op[0], op[1]);
3783f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	 emit(BRW_OPCODE_MOV, this->result, fs_reg(acc));
3793f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt      } else {
3803f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	 emit(BRW_OPCODE_MUL, this->result, op[0], op[1]);
3813f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt      }
382d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
383d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_div:
38483dc891b41c0224f5ba3624b3e3560129e644e28Eric Anholt      if (intel->gen >= 7 && c->dispatch_width == 16)
38583dc891b41c0224f5ba3624b3e3560129e644e28Eric Anholt	 fail("16-wide INTDIV unsupported\n");
38683dc891b41c0224f5ba3624b3e3560129e644e28Eric Anholt
387ff8f272b0d02b41a0ce34ab6af7119b9e06f4961Kenneth Graunke      /* Floating point should be lowered by DIV_TO_MUL_RCP in the compiler. */
388ff8f272b0d02b41a0ce34ab6af7119b9e06f4961Kenneth Graunke      assert(ir->type->is_integer());
389ff8f272b0d02b41a0ce34ab6af7119b9e06f4961Kenneth Graunke      emit_math(SHADER_OPCODE_INT_QUOTIENT, this->result, op[0], op[1]);
390d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
391d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_mod:
39283dc891b41c0224f5ba3624b3e3560129e644e28Eric Anholt      if (intel->gen >= 7 && c->dispatch_width == 16)
39383dc891b41c0224f5ba3624b3e3560129e644e28Eric Anholt	 fail("16-wide INTDIV unsupported\n");
39483dc891b41c0224f5ba3624b3e3560129e644e28Eric Anholt
395ff8f272b0d02b41a0ce34ab6af7119b9e06f4961Kenneth Graunke      /* Floating point should be lowered by MOD_TO_FRACT in the compiler. */
396ff8f272b0d02b41a0ce34ab6af7119b9e06f4961Kenneth Graunke      assert(ir->type->is_integer());
397ff8f272b0d02b41a0ce34ab6af7119b9e06f4961Kenneth Graunke      emit_math(SHADER_OPCODE_INT_REMAINDER, this->result, op[0], op[1]);
398d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
399d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
400d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_less:
401d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_greater:
402d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_lequal:
403d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_gequal:
404d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_equal:
405d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_all_equal:
406d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_nequal:
407d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_any_nequal:
408d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      temp = this->result;
409d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* original gen4 does implicit conversion before comparison. */
410d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (intel->gen < 5)
411d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 temp.type = op[0].type;
412d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
41373b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt      resolve_ud_negate(&op[0]);
41473b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt      resolve_ud_negate(&op[1]);
41573b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt
416dc42910e98dc00760255cc4579da458de09175b9Eric Anholt      resolve_bool_comparison(ir->operands[0], &op[0]);
417dc42910e98dc00760255cc4579da458de09175b9Eric Anholt      resolve_bool_comparison(ir->operands[1], &op[1]);
418dc42910e98dc00760255cc4579da458de09175b9Eric Anholt
419d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_CMP, temp, op[0], op[1]);
420d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->conditional_mod = brw_conditional_for_comparison(ir->operation);
421d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
422d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
423d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_logic_xor:
424d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_XOR, this->result, op[0], op[1]);
425d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
426d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
427d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_logic_or:
428d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_OR, this->result, op[0], op[1]);
429d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
430d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
431d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_logic_and:
432d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_AND, this->result, op[0], op[1]);
433d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
434d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
435d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_dot:
436d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_any:
437d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!"not reached: should be handled by brw_fs_channel_expressions");
438d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
439d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
440d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_noise:
441d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!"not reached: should be handled by lower_noise");
442d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
443d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
444d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_quadop_vector:
445d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!"not reached: should be handled by lower_quadop_vector");
446d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
447d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
448d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_sqrt:
44965b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt      emit_math(SHADER_OPCODE_SQRT, this->result, op[0]);
450d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
451d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
452d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_rsq:
45365b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt      emit_math(SHADER_OPCODE_RSQ, this->result, op[0]);
454d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
455d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
45605790746df077183d6c3caf87ca2d276a60302a8Kenneth Graunke   case ir_unop_bitcast_i2f:
45705790746df077183d6c3caf87ca2d276a60302a8Kenneth Graunke   case ir_unop_bitcast_u2f:
45805790746df077183d6c3caf87ca2d276a60302a8Kenneth Graunke      op[0].type = BRW_REGISTER_TYPE_F;
45905790746df077183d6c3caf87ca2d276a60302a8Kenneth Graunke      this->result = op[0];
46005790746df077183d6c3caf87ca2d276a60302a8Kenneth Graunke      break;
461b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke   case ir_unop_i2u:
46205790746df077183d6c3caf87ca2d276a60302a8Kenneth Graunke   case ir_unop_bitcast_f2u:
463b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke      op[0].type = BRW_REGISTER_TYPE_UD;
464b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke      this->result = op[0];
465b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke      break;
466b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke   case ir_unop_u2i:
46705790746df077183d6c3caf87ca2d276a60302a8Kenneth Graunke   case ir_unop_bitcast_f2i:
468b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke      op[0].type = BRW_REGISTER_TYPE_D;
469b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke      this->result = op[0];
470b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke      break;
471d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_i2f:
4724bc5bfb641bce931bf35f0e78ec2b44263d152baKenneth Graunke   case ir_unop_u2f:
473d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_f2i:
47411a7b93592c22c8165f8fde6395f76778fca452ePaul Berry   case ir_unop_f2u:
475d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, this->result, op[0]);
476d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
47780ecb8f15b9ad7d6edcc85bd19f1867c368b09b6Eric Anholt
47880ecb8f15b9ad7d6edcc85bd19f1867c368b09b6Eric Anholt   case ir_unop_b2i:
47980ecb8f15b9ad7d6edcc85bd19f1867c368b09b6Eric Anholt      inst = emit(BRW_OPCODE_AND, this->result, op[0], fs_reg(1));
48080ecb8f15b9ad7d6edcc85bd19f1867c368b09b6Eric Anholt      break;
48180ecb8f15b9ad7d6edcc85bd19f1867c368b09b6Eric Anholt   case ir_unop_b2f:
48280ecb8f15b9ad7d6edcc85bd19f1867c368b09b6Eric Anholt      temp = fs_reg(this, glsl_type::int_type);
48380ecb8f15b9ad7d6edcc85bd19f1867c368b09b6Eric Anholt      emit(BRW_OPCODE_AND, temp, op[0], fs_reg(1));
48480ecb8f15b9ad7d6edcc85bd19f1867c368b09b6Eric Anholt      emit(BRW_OPCODE_MOV, this->result, temp);
48580ecb8f15b9ad7d6edcc85bd19f1867c368b09b6Eric Anholt      break;
48680ecb8f15b9ad7d6edcc85bd19f1867c368b09b6Eric Anholt
487d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_f2b:
488cf0bbb30f6bd9d3fa61b5207320e8f34c563a2c6Chad Versace      inst = emit(BRW_OPCODE_CMP, this->result, op[0], fs_reg(0.0f));
489cf0bbb30f6bd9d3fa61b5207320e8f34c563a2c6Chad Versace      inst->conditional_mod = BRW_CONDITIONAL_NZ;
490cf0bbb30f6bd9d3fa61b5207320e8f34c563a2c6Chad Versace      emit(BRW_OPCODE_AND, this->result, this->result, fs_reg(1));
491cf0bbb30f6bd9d3fa61b5207320e8f34c563a2c6Chad Versace      break;
492d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_i2b:
493cf0bbb30f6bd9d3fa61b5207320e8f34c563a2c6Chad Versace      assert(op[0].type == BRW_REGISTER_TYPE_D);
49473b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt
495cf0bbb30f6bd9d3fa61b5207320e8f34c563a2c6Chad Versace      inst = emit(BRW_OPCODE_CMP, this->result, op[0], fs_reg(0));
496d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->conditional_mod = BRW_CONDITIONAL_NZ;
497cf0bbb30f6bd9d3fa61b5207320e8f34c563a2c6Chad Versace      emit(BRW_OPCODE_AND, this->result, this->result, fs_reg(1));
498d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
499d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
500d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_trunc:
501d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_RNDZ, this->result, op[0]);
502d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
503d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_ceil:
504d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      op[0].negate = !op[0].negate;
505d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_RNDD, this->result, op[0]);
506d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->result.negate = true;
507d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
508d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_floor:
509d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_RNDD, this->result, op[0]);
510d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
511d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_fract:
512d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_FRC, this->result, op[0]);
513d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
514d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_round_even:
515d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_RNDE, this->result, op[0]);
516d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
517d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
518d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_min:
51973b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt      resolve_ud_negate(&op[0]);
52073b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt      resolve_ud_negate(&op[1]);
52173b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt
522c331b3123ecda127919458e24848b7c1596525acEric Anholt      if (intel->gen >= 6) {
523c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]);
524c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_L;
525c331b3123ecda127919458e24848b7c1596525acEric Anholt      } else {
526c331b3123ecda127919458e24848b7c1596525acEric Anholt	 /* Unalias the destination */
527c331b3123ecda127919458e24848b7c1596525acEric Anholt	 this->result = fs_reg(this, ir->type);
528d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
529c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst = emit(BRW_OPCODE_CMP, this->result, op[0], op[1]);
530c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_L;
531d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
532c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]);
533c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst->predicated = true;
534c331b3123ecda127919458e24848b7c1596525acEric Anholt      }
535d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
536d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_max:
53773b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt      resolve_ud_negate(&op[0]);
53873b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt      resolve_ud_negate(&op[1]);
53973b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt
540c331b3123ecda127919458e24848b7c1596525acEric Anholt      if (intel->gen >= 6) {
541c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]);
542c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_GE;
543c331b3123ecda127919458e24848b7c1596525acEric Anholt      } else {
544c331b3123ecda127919458e24848b7c1596525acEric Anholt	 /* Unalias the destination */
545c331b3123ecda127919458e24848b7c1596525acEric Anholt	 this->result = fs_reg(this, ir->type);
546d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
547c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst = emit(BRW_OPCODE_CMP, this->result, op[0], op[1]);
548c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_G;
549d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
550c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]);
551c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst->predicated = true;
552c331b3123ecda127919458e24848b7c1596525acEric Anholt      }
553d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
554d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
555d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_pow:
55665b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt      emit_math(SHADER_OPCODE_POW, this->result, op[0], op[1]);
557d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
558d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
559d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_bit_not:
560d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_NOT, this->result, op[0]);
561d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
562d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_bit_and:
563d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_AND, this->result, op[0], op[1]);
564d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
565d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_bit_xor:
566d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_XOR, this->result, op[0], op[1]);
567d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
568d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_bit_or:
569d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_OR, this->result, op[0], op[1]);
570d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
571d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
572d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_lshift:
5737de6e749df90a214d1547956dd66cfec6edcb446Eric Anholt      inst = emit(BRW_OPCODE_SHL, this->result, op[0], op[1]);
5747de6e749df90a214d1547956dd66cfec6edcb446Eric Anholt      break;
5757de6e749df90a214d1547956dd66cfec6edcb446Eric Anholt
576d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_rshift:
5777de6e749df90a214d1547956dd66cfec6edcb446Eric Anholt      if (ir->type->base_type == GLSL_TYPE_INT)
5787de6e749df90a214d1547956dd66cfec6edcb446Eric Anholt	 inst = emit(BRW_OPCODE_ASR, this->result, op[0], op[1]);
5797de6e749df90a214d1547956dd66cfec6edcb446Eric Anholt      else
5807de6e749df90a214d1547956dd66cfec6edcb446Eric Anholt	 inst = emit(BRW_OPCODE_SHR, this->result, op[0], op[1]);
581d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
5822ea3ab14f2182978f471674c9dfce029d37f70a7Eric Anholt
5832ea3ab14f2182978f471674c9dfce029d37f70a7Eric Anholt   case ir_binop_ubo_load:
58490de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt      ir_constant *uniform_block = ir->operands[0]->as_constant();
58590de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt      ir_constant *offset = ir->operands[1]->as_constant();
58690de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt
58790de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt      fs_reg packed_consts = fs_reg(this, glsl_type::float_type);
58890de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt      packed_consts.type = result.type;
58990de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt      fs_reg surf_index = fs_reg((unsigned)SURF_INDEX_WM_UBO(uniform_block->value.u[0]));
59090de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt      fs_inst *pull = emit(fs_inst(FS_OPCODE_PULL_CONSTANT_LOAD,
59190de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt                                   packed_consts,
59290de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt                                   surf_index,
59390de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt                                   fs_reg(offset->value.u[0])));
59490de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt      pull->base_mrf = 14;
59590de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt      pull->mlen = 1;
59690de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt
59790de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt      packed_consts.smear = offset->value.u[0] % 16 / 4;
59890de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt      for (int i = 0; i < ir->type->vector_elements; i++) {
59990de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt         /* UBO bools are any nonzero value.  We consider bools to be
60090de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt          * values with the low bit set to 1.  Convert them using CMP.
60190de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt          */
60290de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt         if (ir->type->base_type == GLSL_TYPE_BOOL) {
60390de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt            fs_inst *inst = emit(fs_inst(BRW_OPCODE_CMP, result,
60490de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt                                         packed_consts, fs_reg(0u)));
60590de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt            inst->conditional_mod = BRW_CONDITIONAL_NZ;
60690de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt         } else {
60790de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt            emit(fs_inst(BRW_OPCODE_MOV, result, packed_consts));
60890de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt         }
60990de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt
61090de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt         packed_consts.smear++;
61190de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt         result.reg_offset++;
61290de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt
61390de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt         /* The std140 packing rules don't allow vectors to cross 16-byte
61490de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt          * boundaries, and a reg is 32 bytes.
61590de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt          */
61690de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt         assert(packed_consts.smear < 8);
61790de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt      }
61890de96ff0d6d54ba0f9a337a6a107acf4134682dEric Anholt      result.reg_offset = 0;
6192ea3ab14f2182978f471674c9dfce029d37f70a7Eric Anholt      break;
620d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
621d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
622d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
623d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
624d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_assignment_writes(fs_reg &l, fs_reg &r,
625d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt				   const glsl_type *type, bool predicated)
626d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
627d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   switch (type->base_type) {
628d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case GLSL_TYPE_FLOAT:
629d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case GLSL_TYPE_UINT:
630d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case GLSL_TYPE_INT:
631d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case GLSL_TYPE_BOOL:
632d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (unsigned int i = 0; i < type->components(); i++) {
633d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 l.type = brw_type_for_base_type(type);
634d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 r.type = brw_type_for_base_type(type);
635d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
636d1029f99884e2ba7f663765274cd6bdb4f82feedKenneth Graunke	 if (predicated || !l.equals(r)) {
637d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    fs_inst *inst = emit(BRW_OPCODE_MOV, l, r);
638d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    inst->predicated = predicated;
639d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 }
640d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
641d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 l.reg_offset++;
642d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 r.reg_offset++;
643d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
644d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
645d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case GLSL_TYPE_ARRAY:
646d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (unsigned int i = 0; i < type->length; i++) {
647d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 emit_assignment_writes(l, r, type->fields.array, predicated);
648d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
649d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
650d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
651d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case GLSL_TYPE_STRUCT:
652d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (unsigned int i = 0; i < type->length; i++) {
653d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 emit_assignment_writes(l, r, type->fields.structure[i].type,
654d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt				predicated);
655d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
656d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
657d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
658d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case GLSL_TYPE_SAMPLER:
659d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
660d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
661d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   default:
662d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!"not reached");
663d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
664d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
665d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
666d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
667dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke/* If the RHS processing resulted in an instruction generating a
668dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke * temporary value, and it would be easy to rewrite the instruction to
669dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke * generate its result right into the LHS instead, do so.  This ends
670dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke * up reliably removing instructions where it can be tricky to do so
671dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke * later without real UD chain information.
672dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke */
673dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunkebool
674dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunkefs_visitor::try_rewrite_rhs_to_dst(ir_assignment *ir,
675dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke                                   fs_reg dst,
676dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke                                   fs_reg src,
677dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke                                   fs_inst *pre_rhs_inst,
678dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke                                   fs_inst *last_rhs_inst)
679dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke{
680dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   /* Only attempt if we're doing a direct assignment. */
681dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   if (ir->condition ||
682dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke       !(ir->lhs->type->is_scalar() ||
683dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke        (ir->lhs->type->is_vector() &&
684dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke         ir->write_mask == (1 << ir->lhs->type->vector_elements) - 1)))
685dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke      return false;
686dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke
687dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   /* Make sure the last instruction generated our source reg. */
68832ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt   fs_inst *modify = get_instruction_generating_reg(pre_rhs_inst,
68932ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt						    last_rhs_inst,
69032ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt						    src);
69132ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt   if (!modify)
692dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke      return false;
693dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke
6944b274068204c7f0bacaa4639f24feb433353b861Kenneth Graunke   /* If last_rhs_inst wrote a different number of components than our LHS,
6954b274068204c7f0bacaa4639f24feb433353b861Kenneth Graunke    * we can't safely rewrite it.
6964b274068204c7f0bacaa4639f24feb433353b861Kenneth Graunke    */
69732ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt   if (ir->lhs->type->vector_elements != modify->regs_written())
6984b274068204c7f0bacaa4639f24feb433353b861Kenneth Graunke      return false;
6994b274068204c7f0bacaa4639f24feb433353b861Kenneth Graunke
700dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   /* Success!  Rewrite the instruction. */
70132ae8d3b321185a85b73ff703d8fc26bd5f48fa7Eric Anholt   modify->dst = dst;
702dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke
703dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   return true;
704dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke}
705dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke
706d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
707d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_assignment *ir)
708d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
709eb86bb55f5faef67c21604db19210c6788592679Kenneth Graunke   fs_reg l, r;
710d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *inst;
711d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
712d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* FINISHME: arrays on the lhs */
713d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir->lhs->accept(this);
714d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   l = this->result;
715d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
716dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   fs_inst *pre_rhs_inst = (fs_inst *) this->instructions.get_tail();
717dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke
718d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir->rhs->accept(this);
719d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   r = this->result;
720d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
721dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   fs_inst *last_rhs_inst = (fs_inst *) this->instructions.get_tail();
722dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke
723d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   assert(l.file != BAD_FILE);
724d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   assert(r.file != BAD_FILE);
725d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
726dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   if (try_rewrite_rhs_to_dst(ir, l, r, pre_rhs_inst, last_rhs_inst))
727dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke      return;
728dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke
729d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->condition) {
730d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit_bool_to_cond_code(ir->condition);
731d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
732d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
733d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->lhs->type->is_scalar() ||
734d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       ir->lhs->type->is_vector()) {
735d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (int i = 0; i < ir->lhs->type->vector_elements; i++) {
736d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 if (ir->write_mask & (1 << i)) {
737d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke	    inst = emit(BRW_OPCODE_MOV, l, r);
738d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke	    if (ir->condition)
739d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	       inst->predicated = true;
740d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    r.reg_offset++;
741d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 }
742d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 l.reg_offset++;
743d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
744d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else {
745d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit_assignment_writes(l, r, ir->lhs->type, ir->condition != NULL);
746d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
747d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
748d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
749d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_inst *
750d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate,
751bf0308d8d6fbc842d0120060e65a3fe445f5b2fbKenneth Graunke			      fs_reg shadow_c, fs_reg lod, fs_reg dPdy)
752d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
753d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int mlen;
754d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int base_mrf = 1;
755d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   bool simd16 = false;
756d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg orig_dst;
757d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
758d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* g0 header. */
759d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   mlen = 1;
760d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
761b546aebae922214dced54c75e6f64830aabd5d1cKenneth Graunke   if (ir->shadow_comparitor) {
762d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
76307e621c52329cd17b97051a26493626228d043b9Eric Anholt	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i), coordinate);
764d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 coordinate.reg_offset++;
765d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
766d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* gen4's SIMD8 sampler always has the slots for u,v,r present. */
767d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen += 3;
768d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
769d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (ir->op == ir_tex) {
770d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 /* There's no plain shadow compare message, so we use shadow
771d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  * compare with a bias of 0.0.
772d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  */
773d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), fs_reg(0.0f));
774d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 mlen++;
775c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      } else if (ir->op == ir_txb || ir->op == ir_txl) {
776c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), lod);
777d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 mlen++;
778d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      } else {
779c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke         assert(!"Should not get here.");
780d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
781d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
782c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), shadow_c);
783d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen++;
784d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else if (ir->op == ir_tex) {
785d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
78607e621c52329cd17b97051a26493626228d043b9Eric Anholt	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i), coordinate);
787d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 coordinate.reg_offset++;
788d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
789d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* gen4's SIMD8 sampler always has the slots for u,v,r present. */
790d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen += 3;
791d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else if (ir->op == ir_txd) {
792c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      fs_reg &dPdx = lod;
7936c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke
7946c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
7956c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i), coordinate);
7966c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke	 coordinate.reg_offset++;
7976c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      }
7986c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      /* the slots for u and v are always present, but r is optional */
7996c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      mlen += MAX2(ir->coordinate->type->vector_elements, 2);
8006c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke
8016c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      /*  P   = u, v, r
8026c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       * dPdx = dudx, dvdx, drdx
8036c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       * dPdy = dudy, dvdy, drdy
8046c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       *
8053e1fd13f605f16e8b48f3a9b71910a3c66eb84b5Kenneth Graunke       * 1-arg: Does not exist.
8063e1fd13f605f16e8b48f3a9b71910a3c66eb84b5Kenneth Graunke       *
8076c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       * 2-arg: dudx   dvdx   dudy   dvdy
8086c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       *        dPdx.x dPdx.y dPdy.x dPdy.y
8096c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       *        m4     m5     m6     m7
8106c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       *
8116c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       * 3-arg: dudx   dvdx   drdx   dudy   dvdy   drdy
8126c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       *        dPdx.x dPdx.y dPdx.z dPdy.x dPdy.y dPdy.z
8136c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       *        m5     m6     m7     m8     m9     m10
8146c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       */
8156c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      for (int i = 0; i < ir->lod_info.grad.dPdx->type->vector_elements; i++) {
8166c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdx);
8176c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke	 dPdx.reg_offset++;
8186c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      }
8193e1fd13f605f16e8b48f3a9b71910a3c66eb84b5Kenneth Graunke      mlen += MAX2(ir->lod_info.grad.dPdx->type->vector_elements, 2);
8206c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke
8216c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      for (int i = 0; i < ir->lod_info.grad.dPdy->type->vector_elements; i++) {
8226c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdy);
8236c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke	 dPdy.reg_offset++;
8246c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      }
8253e1fd13f605f16e8b48f3a9b71910a3c66eb84b5Kenneth Graunke      mlen += MAX2(ir->lod_info.grad.dPdy->type->vector_elements, 2);
8264eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke   } else if (ir->op == ir_txs) {
8274eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke      /* There's no SIMD8 resinfo message on Gen4.  Use SIMD16 instead. */
8284eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke      simd16 = true;
829c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), lod);
8304eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke      mlen += 2;
831d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else {
832d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* Oh joy.  gen4 doesn't have SIMD8 non-shadow-compare bias/lod
833d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * instructions.  We'll need to do SIMD16 here.
834d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       */
8354eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke      simd16 = true;
83647b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke      assert(ir->op == ir_txb || ir->op == ir_txl || ir->op == ir_txf);
837d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
838d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
83907e621c52329cd17b97051a26493626228d043b9Eric Anholt	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i * 2, coordinate.type),
84007e621c52329cd17b97051a26493626228d043b9Eric Anholt	      coordinate);
841d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 coordinate.reg_offset++;
842d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
843d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
84447b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke      /* Initialize the rest of u/v/r with 0.0.  Empirically, this seems to
84547b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke       * be necessary for TXF (ld), but seems wise to do for all messages.
84647b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke       */
84747b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke      for (int i = ir->coordinate->type->vector_elements; i < 3; i++) {
84847b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i * 2), fs_reg(0.0f));
84947b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke      }
85047b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke
851d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* lod/bias appears after u/v/r. */
852d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen += 6;
853d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
854c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, lod.type), lod);
855c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      mlen++;
856d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
857d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* The unused upper half. */
858d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen++;
8594eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke   }
860d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
8614eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke   if (simd16) {
862d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* Now, since we're doing simd16, the return is 2 interleaved
863d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * vec4s where the odd-indexed ones are junk. We'll need to move
864d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * this weirdness around to the expected layout.
865d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       */
866d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      orig_dst = dst;
8674eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke      const glsl_type *vec_type =
8684eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke	 glsl_type::get_instance(ir->type->base_type, 4, 1);
8694eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke      dst = fs_reg(this, glsl_type::get_array_instance(vec_type, 2));
8704eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke      dst.type = intel->is_g4x ? brw_type_for_base_type(ir->type)
8714eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke			       : BRW_REGISTER_TYPE_F;
872d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
873d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
874d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *inst = NULL;
875d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   switch (ir->op) {
876d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_tex:
877febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke      inst = emit(SHADER_OPCODE_TEX, dst);
878d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
879d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_txb:
880d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(FS_OPCODE_TXB, dst);
881d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
882d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_txl:
883febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke      inst = emit(SHADER_OPCODE_TXL, dst);
884d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
885d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_txd:
886febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke      inst = emit(SHADER_OPCODE_TXD, dst);
887d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
8881e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke   case ir_txs:
889febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke      inst = emit(SHADER_OPCODE_TXS, dst);
8904eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke      break;
8914eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke   case ir_txf:
892febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke      inst = emit(SHADER_OPCODE_TXF, dst);
893d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
894d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
895d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->base_mrf = base_mrf;
896d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->mlen = mlen;
897d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->header_present = true;
898d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
899d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (simd16) {
900d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (int i = 0; i < 4; i++) {
901d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 emit(BRW_OPCODE_MOV, orig_dst, dst);
902d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 orig_dst.reg_offset++;
903d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 dst.reg_offset += 2;
904d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
905d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
906d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
907d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   return inst;
908d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
909d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
910d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/* gen5's sampler has slots for u, v, r, array index, then optional
911d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * parameters like shadow comparitor or LOD bias.  If optional
912d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * parameters aren't present, those base slots are optional and don't
913d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * need to be included in the message.
914d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt *
915d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * We don't fill in the unnecessary slots regardless, which may look
916d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * surprising in the disassembly.
917d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */
918d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_inst *
919d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate,
920bf0308d8d6fbc842d0120060e65a3fe445f5b2fbKenneth Graunke			      fs_reg shadow_c, fs_reg lod, fs_reg lod2)
921d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
922d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int mlen = 0;
923d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int base_mrf = 2;
924d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int reg_width = c->dispatch_width / 8;
925d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   bool header_present = false;
926ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke   const int vector_elements =
927ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke      ir->coordinate ? ir->coordinate->type->vector_elements : 0;
928d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
929217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke   if (ir->offset != NULL && ir->op == ir_txf) {
930217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke      /* It appears that the ld instruction used for txf does its
931217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke       * address bounds check before adding in the offset.  To work
932217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke       * around this, just add the integer offset to the integer texel
933217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke       * coordinate, and don't put the offset in the header.
934d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       */
935217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke      ir_constant *offset = ir->offset->as_constant();
936217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke      for (int i = 0; i < vector_elements; i++) {
937217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke	 emit(BRW_OPCODE_ADD,
938217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke	      fs_reg(MRF, base_mrf + mlen + i * reg_width, coordinate.type),
939217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke	      coordinate,
940217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke	      offset->value.i[i]);
941217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke	 coordinate.reg_offset++;
942217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke      }
943217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke   } else {
944217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke      if (ir->offset) {
945217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke	 /* The offsets set up by the ir_texture visitor are in the
946217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke	  * m1 header, so we can't go headerless.
947217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke	  */
948217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke	 header_present = true;
949217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke	 mlen++;
950217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke	 base_mrf--;
951217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke      }
952d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
953217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke      for (int i = 0; i < vector_elements; i++) {
954217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke	 emit(BRW_OPCODE_MOV,
955217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke	      fs_reg(MRF, base_mrf + mlen + i * reg_width, coordinate.type),
956217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke	      coordinate);
957217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke	 coordinate.reg_offset++;
958217b62bf001f6b1da31807b803bbe45d7cabe3baKenneth Graunke      }
959d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
960ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke   mlen += vector_elements * reg_width;
961d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
962b546aebae922214dced54c75e6f64830aabd5d1cKenneth Graunke   if (ir->shadow_comparitor) {
963d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen = MAX2(mlen, header_present + 4 * reg_width);
964d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
965c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), shadow_c);
966d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen += reg_width;
967d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
968d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
969d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *inst = NULL;
970d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   switch (ir->op) {
971d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_tex:
972febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke      inst = emit(SHADER_OPCODE_TEX, dst);
973d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
974d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_txb:
975d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen = MAX2(mlen, header_present + 4 * reg_width);
976c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), lod);
977d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen += reg_width;
978d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
979d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(FS_OPCODE_TXB, dst);
980d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
981d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_txl:
982d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen = MAX2(mlen, header_present + 4 * reg_width);
983c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), lod);
984d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen += reg_width;
985d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
986febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke      inst = emit(SHADER_OPCODE_TXL, dst);
987d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
9882f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke   case ir_txd: {
9892f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke      mlen = MAX2(mlen, header_present + 4 * reg_width); /* skip over 'ai' */
9902f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke
9912f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke      /**
9922f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke       *  P   =  u,    v,    r
9932f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke       * dPdx = dudx, dvdx, drdx
9942f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke       * dPdy = dudy, dvdy, drdy
9952f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke       *
9962f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke       * Load up these values:
9972f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke       * - dudx   dudy   dvdx   dvdy   drdx   drdy
9982f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke       * - dPdx.x dPdy.x dPdx.y dPdy.y dPdx.z dPdy.z
9992f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke       */
10002f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke      for (int i = 0; i < ir->lod_info.grad.dPdx->type->vector_elements; i++) {
1001c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), lod);
1002c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke	 lod.reg_offset++;
10032f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke	 mlen += reg_width;
10042f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke
1005c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), lod2);
1006c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke	 lod2.reg_offset++;
10072f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke	 mlen += reg_width;
10082f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke      }
10092f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke
1010febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke      inst = emit(SHADER_OPCODE_TXD, dst);
10112f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke      break;
10122f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke   }
10131e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke   case ir_txs:
1014c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), lod);
1015ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke      mlen += reg_width;
1016febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke      inst = emit(SHADER_OPCODE_TXS, dst);
1017ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke      break;
1018ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke   case ir_txf:
101930be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke      mlen = header_present + 4 * reg_width;
102030be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke
102130be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke      emit(BRW_OPCODE_MOV,
102230be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke	   fs_reg(MRF, base_mrf + mlen - reg_width, BRW_REGISTER_TYPE_UD),
1023c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke	   lod);
1024febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke      inst = emit(SHADER_OPCODE_TXF, dst);
1025d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
1026d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1027d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->base_mrf = base_mrf;
1028d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->mlen = mlen;
1029d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->header_present = header_present;
1030d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1031d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (mlen > 11) {
1032d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fail("Message length >11 disallowed by hardware\n");
1033d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1034d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1035d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   return inst;
1036d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1037d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1038d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_inst *
1039d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
1040bf0308d8d6fbc842d0120060e65a3fe445f5b2fbKenneth Graunke			      fs_reg shadow_c, fs_reg lod, fs_reg lod2)
1041d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1042d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int mlen = 0;
1043d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int base_mrf = 2;
1044d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int reg_width = c->dispatch_width / 8;
1045d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   bool header_present = false;
1046f41ecade7b458c02d504158b522acb2231585040Eric Anholt   int offsets[3];
1047d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1048f41ecade7b458c02d504158b522acb2231585040Eric Anholt   if (ir->offset && ir->op != ir_txf) {
1049d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* The offsets set up by the ir_texture visitor are in the
1050d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m1 header, so we can't go headerless.
1051d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       */
1052d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      header_present = true;
1053d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen++;
1054d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      base_mrf--;
1055d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1056d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1057b546aebae922214dced54c75e6f64830aabd5d1cKenneth Graunke   if (ir->shadow_comparitor) {
1058c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), shadow_c);
1059d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen += reg_width;
1060d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1061d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1062d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Set up the LOD info */
1063d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   switch (ir->op) {
1064d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_tex:
1065d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
1066d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_txb:
1067c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), lod);
1068d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen += reg_width;
1069d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
1070d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_txl:
1071c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), lod);
1072d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen += reg_width;
1073d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
10743fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke   case ir_txd: {
10753fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke      if (c->dispatch_width == 16)
10763fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 fail("Gen7 does not support sample_d/sample_d_c in SIMD16 mode.");
10773fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke
10783fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke      /* Load dPdx and the coordinate together:
10793fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke       * [hdr], [ref], x, dPdx.x, dPdy.x, y, dPdx.y, dPdy.y, z, dPdx.z, dPdy.z
10803fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke       */
10813fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke      for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
108207e621c52329cd17b97051a26493626228d043b9Eric Anholt	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), coordinate);
10833fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 coordinate.reg_offset++;
10843fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 mlen += reg_width;
10853fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke
1086c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), lod);
1087c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke	 lod.reg_offset++;
10883fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 mlen += reg_width;
10893fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke
1090c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), lod2);
1091c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke	 lod2.reg_offset++;
10923fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 mlen += reg_width;
10933fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke      }
10943fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke      break;
10953fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke   }
10961e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke   case ir_txs:
1097c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), lod);
1098ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke      mlen += reg_width;
1099ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke      break;
1100ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke   case ir_txf:
1101f41ecade7b458c02d504158b522acb2231585040Eric Anholt      /* It appears that the ld instruction used for txf does its
1102f41ecade7b458c02d504158b522acb2231585040Eric Anholt       * address bounds check before adding in the offset.  To work
1103f41ecade7b458c02d504158b522acb2231585040Eric Anholt       * around this, just add the integer offset to the integer texel
1104f41ecade7b458c02d504158b522acb2231585040Eric Anholt       * coordinate, and don't put the offset in the header.
1105f41ecade7b458c02d504158b522acb2231585040Eric Anholt       */
1106f41ecade7b458c02d504158b522acb2231585040Eric Anholt      if (ir->offset) {
1107f41ecade7b458c02d504158b522acb2231585040Eric Anholt	 ir_constant *offset = ir->offset->as_constant();
1108f41ecade7b458c02d504158b522acb2231585040Eric Anholt	 offsets[0] = offset->value.i[0];
1109f41ecade7b458c02d504158b522acb2231585040Eric Anholt	 offsets[1] = offset->value.i[1];
1110f41ecade7b458c02d504158b522acb2231585040Eric Anholt	 offsets[2] = offset->value.i[2];
1111f41ecade7b458c02d504158b522acb2231585040Eric Anholt      } else {
1112f41ecade7b458c02d504158b522acb2231585040Eric Anholt	 memset(offsets, 0, sizeof(offsets));
1113f41ecade7b458c02d504158b522acb2231585040Eric Anholt      }
1114f41ecade7b458c02d504158b522acb2231585040Eric Anholt
11150edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke      /* Unfortunately, the parameters for LD are intermixed: u, lod, v, r. */
1116f41ecade7b458c02d504158b522acb2231585040Eric Anholt      emit(BRW_OPCODE_ADD,
1117f41ecade7b458c02d504158b522acb2231585040Eric Anholt	   fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_D), coordinate, offsets[0]);
11180edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke      coordinate.reg_offset++;
11190edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke      mlen += reg_width;
11200edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke
1121c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_D), lod);
11220edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke      mlen += reg_width;
11230edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke
11240edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke      for (int i = 1; i < ir->coordinate->type->vector_elements; i++) {
1125f41ecade7b458c02d504158b522acb2231585040Eric Anholt	 emit(BRW_OPCODE_ADD,
1126f41ecade7b458c02d504158b522acb2231585040Eric Anholt	      fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_D), coordinate, offsets[i]);
11270edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke	 coordinate.reg_offset++;
11280edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke	 mlen += reg_width;
11290edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke      }
1130d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
1131d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1132d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
11330edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke   /* Set up the coordinate (except for cases where it was done above) */
11340edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke   if (ir->op != ir_txd && ir->op != ir_txs && ir->op != ir_txf) {
11353fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke      for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
113607e621c52329cd17b97051a26493626228d043b9Eric Anholt	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), coordinate);
11373fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 coordinate.reg_offset++;
11383fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 mlen += reg_width;
11393fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke      }
1140d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1141d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1142d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Generate the SEND */
1143d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *inst = NULL;
1144d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   switch (ir->op) {
1145febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke   case ir_tex: inst = emit(SHADER_OPCODE_TEX, dst); break;
1146d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_txb: inst = emit(FS_OPCODE_TXB, dst); break;
1147febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke   case ir_txl: inst = emit(SHADER_OPCODE_TXL, dst); break;
1148febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke   case ir_txd: inst = emit(SHADER_OPCODE_TXD, dst); break;
1149febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke   case ir_txf: inst = emit(SHADER_OPCODE_TXF, dst); break;
1150febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke   case ir_txs: inst = emit(SHADER_OPCODE_TXS, dst); break;
1151d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1152d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->base_mrf = base_mrf;
1153d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->mlen = mlen;
1154d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->header_present = header_present;
1155d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1156d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (mlen > 11) {
1157d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fail("Message length >11 disallowed by hardware\n");
1158d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1159d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1160d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   return inst;
1161d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1162d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
116327bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke/**
116427bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke * Emit code to produce the coordinates for a texture lookup.
116527bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke *
116627bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke * Returns the fs_reg containing the texture coordinate (as opposed to
116727bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke * setting this->result).
116827bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke */
116927bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunkefs_reg
1170f3d0daf7ea7e42ff9ce11e8bd6fba1059a2406e8Kenneth Graunkefs_visitor::emit_texcoord(ir_texture *ir, int sampler, int texunit)
1171d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1172d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *inst = NULL;
1173d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
117427bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke   if (!ir->coordinate)
117527bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke      return fs_reg(); /* Return the default BAD_FILE register. */
1176f1622cfe9c0f37a9b452be1297f187cba8c46e6aKenneth Graunke
117727bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke   ir->coordinate->accept(this);
1178d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg coordinate = this->result;
1179d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
11807c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt   bool needs_gl_clamp = true;
11817c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt
11827c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt   fs_reg scale_x, scale_y;
11837c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt
1184d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* The 965 requires the EU to do the normalization of GL rectangle
1185d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * texture coordinates.  We use the program parameter state
1186d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * tracking to get the scaling factor.
1187d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    */
11887c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt   if (ir->sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_RECT &&
11897c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt       (intel->gen < 6 ||
1190f3d0daf7ea7e42ff9ce11e8bd6fba1059a2406e8Kenneth Graunke	(intel->gen >= 6 && (c->key.tex.gl_clamp_mask[0] & (1 << sampler) ||
1191f3d0daf7ea7e42ff9ce11e8bd6fba1059a2406e8Kenneth Graunke			     c->key.tex.gl_clamp_mask[1] & (1 << sampler))))) {
1192d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      struct gl_program_parameter_list *params = c->fp->program.Base.Parameters;
1193d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      int tokens[STATE_LENGTH] = {
1194d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 STATE_INTERNAL,
1195d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 STATE_TEXRECT_SCALE,
11960ad2dce24aa0475e607e3c58b8aa50057412c6efKenneth Graunke	 texunit,
1197d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 0,
1198d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 0
1199d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      };
1200d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1201d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (c->dispatch_width == 16) {
1202d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 fail("rectangle scale uniform setup not supported on 16-wide\n");
120327bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke	 return fs_reg(this, ir->type);
1204d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1205d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
12067c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt      scale_x = fs_reg(UNIFORM, c->prog_data.nr_params);
12077c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt      scale_y = fs_reg(UNIFORM, c->prog_data.nr_params + 1);
12087c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt
1209d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      GLuint index = _mesa_add_state_reference(params,
1210d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt					       (gl_state_index *)tokens);
1211d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1212d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->param_index[c->prog_data.nr_params] = index;
1213d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->param_offset[c->prog_data.nr_params] = 0;
1214d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      c->prog_data.nr_params++;
1215d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->param_index[c->prog_data.nr_params] = index;
1216d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->param_offset[c->prog_data.nr_params] = 1;
1217d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      c->prog_data.nr_params++;
12187c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt   }
1219d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
12207c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt   /* The 965 requires the EU to do the normalization of GL rectangle
12217c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt    * texture coordinates.  We use the program parameter state
12227c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt    * tracking to get the scaling factor.
12237c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt    */
12247c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt   if (intel->gen < 6 &&
12257c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt       ir->sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_RECT) {
1226d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_reg dst = fs_reg(this, ir->coordinate->type);
1227d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_reg src = coordinate;
1228d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      coordinate = dst;
1229d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1230d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MUL, dst, src, scale_x);
1231d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      dst.reg_offset++;
1232d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      src.reg_offset++;
1233d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MUL, dst, src, scale_y);
12347c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt   } else if (ir->sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_RECT) {
12357c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt      /* On gen6+, the sampler handles the rectangle coordinates
12367c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt       * natively, without needing rescaling.  But that means we have
12377c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt       * to do GL_CLAMP clamping at the [0, width], [0, height] scale,
12387c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt       * not [0, 1] like the default case below.
12397c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt       */
12407c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt      needs_gl_clamp = false;
12417c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt
12427c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt      for (int i = 0; i < 2; i++) {
1243f3d0daf7ea7e42ff9ce11e8bd6fba1059a2406e8Kenneth Graunke	 if (c->key.tex.gl_clamp_mask[i] & (1 << sampler)) {
12447c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt	    fs_reg chan = coordinate;
12457c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt	    chan.reg_offset += i;
12467c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt
12477c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt	    inst = emit(BRW_OPCODE_SEL, chan, chan, brw_imm_f(0.0));
12487c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt	    inst->conditional_mod = BRW_CONDITIONAL_G;
12497c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt
12507c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt	    /* Our parameter comes in as 1.0/width or 1.0/height,
12517c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt	     * because that's what people normally want for doing
12527c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt	     * texture rectangle handling.  We need width or height
12537c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt	     * for clamping, but we don't care enough to make a new
12547c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt	     * parameter type, so just invert back.
12557c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt	     */
12567c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt	    fs_reg limit = fs_reg(this, glsl_type::float_type);
12577c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt	    emit(BRW_OPCODE_MOV, limit, i == 0 ? scale_x : scale_y);
12587c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt	    emit(SHADER_OPCODE_RCP, limit, limit);
12597c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt
12607c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt	    inst = emit(BRW_OPCODE_SEL, chan, chan, limit);
12617c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt	    inst->conditional_mod = BRW_CONDITIONAL_L;
12627c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt	 }
12637c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt      }
1264d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
126507e621c52329cd17b97051a26493626228d043b9Eric Anholt
12667c857a6b159debf76d4661f494fd2c97d205b5b1Eric Anholt   if (ir->coordinate && needs_gl_clamp) {
12671e188f2daef1ae31224d2429bcc1fab75c81fb36Eric Anholt      for (unsigned int i = 0;
12681e188f2daef1ae31224d2429bcc1fab75c81fb36Eric Anholt	   i < MIN2(ir->coordinate->type->vector_elements, 3); i++) {
1269f3d0daf7ea7e42ff9ce11e8bd6fba1059a2406e8Kenneth Graunke	 if (c->key.tex.gl_clamp_mask[i] & (1 << sampler)) {
127007e621c52329cd17b97051a26493626228d043b9Eric Anholt	    fs_reg chan = coordinate;
127107e621c52329cd17b97051a26493626228d043b9Eric Anholt	    chan.reg_offset += i;
127207e621c52329cd17b97051a26493626228d043b9Eric Anholt
127307e621c52329cd17b97051a26493626228d043b9Eric Anholt	    fs_inst *inst = emit(BRW_OPCODE_MOV, chan, chan);
127407e621c52329cd17b97051a26493626228d043b9Eric Anholt	    inst->saturate = true;
127507e621c52329cd17b97051a26493626228d043b9Eric Anholt	 }
127607e621c52329cd17b97051a26493626228d043b9Eric Anholt      }
127707e621c52329cd17b97051a26493626228d043b9Eric Anholt   }
127827bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke   return coordinate;
127927bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke}
128027bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke
128127bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunkevoid
128227bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunkefs_visitor::visit(ir_texture *ir)
128327bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke{
128427bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke   fs_inst *inst = NULL;
128527bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke
128627bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke   int sampler = _mesa_get_sampler_uniform_value(ir->sampler, prog, &fp->Base);
12870ad2dce24aa0475e607e3c58b8aa50057412c6efKenneth Graunke   int texunit = fp->Base.SamplerUnits[sampler];
128827bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke
128927bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke   /* Should be lowered by do_lower_texture_projection */
129027bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke   assert(!ir->projector);
129127bf9c1997b77f85c2099436e9ad5dfc0f1608c7Kenneth Graunke
1292c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke   /* Generate code to compute all the subexpression trees.  This has to be
1293c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke    * done before loading any values into MRFs for the sampler message since
1294c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke    * generating these values may involve SEND messages that need the MRFs.
1295c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke    */
1296f3d0daf7ea7e42ff9ce11e8bd6fba1059a2406e8Kenneth Graunke   fs_reg coordinate = emit_texcoord(ir, sampler, texunit);
1297d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1298c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke   fs_reg shadow_comparitor;
1299c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke   if (ir->shadow_comparitor) {
1300c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      ir->shadow_comparitor->accept(this);
1301c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      shadow_comparitor = this->result;
1302c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke   }
1303c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke
1304c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke   fs_reg lod, lod2;
1305c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke   switch (ir->op) {
1306c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke   case ir_tex:
1307c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      break;
1308c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke   case ir_txb:
1309c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      ir->lod_info.bias->accept(this);
1310c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      lod = this->result;
1311c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      break;
1312c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke   case ir_txd:
1313c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      ir->lod_info.grad.dPdx->accept(this);
1314c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      lod = this->result;
1315c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke
1316c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      ir->lod_info.grad.dPdy->accept(this);
1317c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      lod2 = this->result;
1318c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      break;
1319c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke   case ir_txf:
1320c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke   case ir_txl:
1321c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke   case ir_txs:
1322c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      ir->lod_info.lod->accept(this);
1323c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      lod = this->result;
1324c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      break;
1325c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke   };
1326c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke
1327d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Writemasking doesn't eliminate channels on SIMD8 texture
1328d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * samples, so don't worry about them.
1329d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    */
1330b6bdcf2a908889532ef6d5eb643791176dffcb9dKenneth Graunke   fs_reg dst = fs_reg(this, glsl_type::get_instance(ir->type->base_type, 4, 1));
1331d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1332d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (intel->gen >= 7) {
1333c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      inst = emit_texture_gen7(ir, dst, coordinate, shadow_comparitor,
1334bf0308d8d6fbc842d0120060e65a3fe445f5b2fbKenneth Graunke                               lod, lod2);
1335d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else if (intel->gen >= 5) {
1336c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      inst = emit_texture_gen5(ir, dst, coordinate, shadow_comparitor,
1337bf0308d8d6fbc842d0120060e65a3fe445f5b2fbKenneth Graunke                               lod, lod2);
1338d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else {
1339c0f60106df724188d6ffe7c9f21eeff22186ab25Kenneth Graunke      inst = emit_texture_gen4(ir, dst, coordinate, shadow_comparitor,
1340bf0308d8d6fbc842d0120060e65a3fe445f5b2fbKenneth Graunke                               lod, lod2);
1341d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1342d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
134382bfb4b41af7d61aa45e41d62c1842b6a09e9585Kenneth Graunke   /* The header is set up by generate_tex() when necessary. */
134482bfb4b41af7d61aa45e41d62c1842b6a09e9585Kenneth Graunke   inst->src[0] = reg_undef;
134582bfb4b41af7d61aa45e41d62c1842b6a09e9585Kenneth Graunke
134682bfb4b41af7d61aa45e41d62c1842b6a09e9585Kenneth Graunke   if (ir->offset != NULL && ir->op != ir_txf)
134782bfb4b41af7d61aa45e41d62c1842b6a09e9585Kenneth Graunke      inst->texture_offset = brw_texture_offset(ir->offset->as_constant());
1348d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
134985e8e9e000732908b259a7e2cbc1724a1be2d447Kenneth Graunke   inst->sampler = sampler;
1350d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1351b546aebae922214dced54c75e6f64830aabd5d1cKenneth Graunke   if (ir->shadow_comparitor)
1352b546aebae922214dced54c75e6f64830aabd5d1cKenneth Graunke      inst->shadow_compare = true;
1353d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1354f3d0daf7ea7e42ff9ce11e8bd6fba1059a2406e8Kenneth Graunke   swizzle_result(ir, dst, sampler);
135501fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke}
135601fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke
135701fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke/**
135801fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke * Swizzle the result of a texture result.  This is necessary for
135901fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke * EXT_texture_swizzle as well as DEPTH_TEXTURE_MODE for shadow comparisons.
136001fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke */
136101fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunkevoid
1362f3d0daf7ea7e42ff9ce11e8bd6fba1059a2406e8Kenneth Graunkefs_visitor::swizzle_result(ir_texture *ir, fs_reg orig_val, int sampler)
136301fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke{
136401fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke   this->result = orig_val;
136501fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke
1366c592ebc581e5ca0122660b3d76ec924b96581216Kenneth Graunke   if (ir->op == ir_txs)
1367c592ebc581e5ca0122660b3d76ec924b96581216Kenneth Graunke      return;
1368c592ebc581e5ca0122660b3d76ec924b96581216Kenneth Graunke
1369d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->type == glsl_type::float_type) {
1370d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* Ignore DEPTH_TEXTURE_MODE swizzling. */
1371d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(ir->sampler->type->sampler_shadow);
1372f3d0daf7ea7e42ff9ce11e8bd6fba1059a2406e8Kenneth Graunke   } else if (c->key.tex.swizzles[sampler] != SWIZZLE_NOOP) {
137301fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke      fs_reg swizzled_result = fs_reg(this, glsl_type::vec4_type);
1374d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1375d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (int i = 0; i < 4; i++) {
1376f3d0daf7ea7e42ff9ce11e8bd6fba1059a2406e8Kenneth Graunke	 int swiz = GET_SWZ(c->key.tex.swizzles[sampler], i);
137701fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke	 fs_reg l = swizzled_result;
1378d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 l.reg_offset += i;
1379d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1380d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 if (swiz == SWIZZLE_ZERO) {
1381d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    emit(BRW_OPCODE_MOV, l, fs_reg(0.0f));
1382d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 } else if (swiz == SWIZZLE_ONE) {
1383d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    emit(BRW_OPCODE_MOV, l, fs_reg(1.0f));
1384d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 } else {
138501fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke	    fs_reg r = orig_val;
1386f3d0daf7ea7e42ff9ce11e8bd6fba1059a2406e8Kenneth Graunke	    r.reg_offset += GET_SWZ(c->key.tex.swizzles[sampler], i);
1387d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    emit(BRW_OPCODE_MOV, l, r);
1388d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 }
1389d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
139001fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke      this->result = swizzled_result;
1391d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1392d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1393d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1394d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1395d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_swizzle *ir)
1396d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1397d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir->val->accept(this);
1398d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg val = this->result;
1399d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1400d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->type->vector_elements == 1) {
1401d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->result.reg_offset += ir->mask.x;
1402d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      return;
1403d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1404d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1405d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg result = fs_reg(this, ir->type);
1406d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->result = result;
1407d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1408d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   for (unsigned int i = 0; i < ir->type->vector_elements; i++) {
1409d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_reg channel = val;
1410d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      int swiz = 0;
1411d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1412d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      switch (i) {
1413d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case 0:
1414d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 swiz = ir->mask.x;
1415d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1416d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case 1:
1417d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 swiz = ir->mask.y;
1418d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1419d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case 2:
1420d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 swiz = ir->mask.z;
1421d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1422d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case 3:
1423d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 swiz = ir->mask.w;
1424d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1425d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1426d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1427d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      channel.reg_offset += swiz;
1428d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, result, channel);
1429d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      result.reg_offset++;
1430d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1431d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1432d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1433d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1434d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_discard *ir)
1435d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1436d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   assert(ir->condition == NULL); /* FINISHME */
1437d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1438d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(FS_OPCODE_DISCARD);
1439d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1440d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1441d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1442d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_constant *ir)
1443d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1444d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Set this->result to reg at the bottom of the function because some code
1445d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * paths will cause this visitor to be applied to other fields.  This will
1446d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * cause the value stored in this->result to be modified.
1447d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    *
1448d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * Make reg constant so that it doesn't get accidentally modified along the
1449d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * way.  Yes, I actually had this problem. :(
1450d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    */
1451d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   const fs_reg reg(this, ir->type);
1452d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg dst_reg = reg;
1453d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1454d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->type->is_array()) {
1455d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      const unsigned size = type_size(ir->type->fields.array);
1456d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1457d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (unsigned i = 0; i < ir->type->length; i++) {
1458d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 ir->array_elements[i]->accept(this);
1459d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 fs_reg src_reg = this->result;
1460d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1461d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 dst_reg.type = src_reg.type;
1462d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 for (unsigned j = 0; j < size; j++) {
1463d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    emit(BRW_OPCODE_MOV, dst_reg, src_reg);
1464d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    src_reg.reg_offset++;
1465d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    dst_reg.reg_offset++;
1466d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 }
1467d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1468d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else if (ir->type->is_record()) {
1469d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      foreach_list(node, &ir->components) {
1470f75c2d53146ea14f8dfedcc5b7a4704278ba0792Kenneth Graunke	 ir_constant *const field = (ir_constant *) node;
1471d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 const unsigned size = type_size(field->type);
1472d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1473d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 field->accept(this);
1474d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 fs_reg src_reg = this->result;
1475d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1476d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 dst_reg.type = src_reg.type;
1477d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 for (unsigned j = 0; j < size; j++) {
1478d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    emit(BRW_OPCODE_MOV, dst_reg, src_reg);
1479d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    src_reg.reg_offset++;
1480d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    dst_reg.reg_offset++;
1481d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 }
1482d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1483d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else {
1484d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      const unsigned size = type_size(ir->type);
1485d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1486d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (unsigned i = 0; i < size; i++) {
1487d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 switch (ir->type->base_type) {
1488d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 case GLSL_TYPE_FLOAT:
1489d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    emit(BRW_OPCODE_MOV, dst_reg, fs_reg(ir->value.f[i]));
1490d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    break;
1491d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 case GLSL_TYPE_UINT:
1492d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    emit(BRW_OPCODE_MOV, dst_reg, fs_reg(ir->value.u[i]));
1493d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    break;
1494d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 case GLSL_TYPE_INT:
1495d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    emit(BRW_OPCODE_MOV, dst_reg, fs_reg(ir->value.i[i]));
1496d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    break;
1497d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 case GLSL_TYPE_BOOL:
1498d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    emit(BRW_OPCODE_MOV, dst_reg, fs_reg((int)ir->value.b[i]));
1499d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    break;
1500d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 default:
1501d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    assert(!"Non-float/uint/int/bool constant");
1502d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 }
1503d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 dst_reg.reg_offset++;
1504d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1505d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1506d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1507d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->result = reg;
1508d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1509d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1510d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1511d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_bool_to_cond_code(ir_rvalue *ir)
1512d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1513d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir_expression *expr = ir->as_expression();
1514d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1515d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (expr) {
1516d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_reg op[2];
1517d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_inst *inst;
1518d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1519d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(expr->get_num_operands() <= 2);
1520d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (unsigned int i = 0; i < expr->get_num_operands(); i++) {
1521d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 assert(expr->operands[i]->type->is_scalar());
1522d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1523d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 expr->operands[i]->accept(this);
1524d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 op[i] = this->result;
152573b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt
152673b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt	 resolve_ud_negate(&op[i]);
1527d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1528d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1529d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      switch (expr->operation) {
1530d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_unop_logic_not:
1531d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_AND, reg_null_d, op[0], fs_reg(1));
1532d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_Z;
1533d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1534d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1535d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_logic_xor:
1536d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_logic_or:
1537d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_logic_and:
153880ecb8f15b9ad7d6edcc85bd19f1867c368b09b6Eric Anholt	 goto out;
1539d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1540d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_unop_f2b:
1541d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 if (intel->gen >= 6) {
1542d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    inst = emit(BRW_OPCODE_CMP, reg_null_d, op[0], fs_reg(0.0f));
1543d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 } else {
1544d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    inst = emit(BRW_OPCODE_MOV, reg_null_f, op[0]);
1545d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 }
1546d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_NZ;
1547d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1548d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1549d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_unop_i2b:
1550d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 if (intel->gen >= 6) {
1551d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    inst = emit(BRW_OPCODE_CMP, reg_null_d, op[0], fs_reg(0));
1552d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 } else {
1553d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    inst = emit(BRW_OPCODE_MOV, reg_null_d, op[0]);
1554d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 }
1555d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_NZ;
1556d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1557d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1558d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_greater:
1559d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_gequal:
1560d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_less:
1561d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_lequal:
1562d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_equal:
1563d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_all_equal:
1564d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_nequal:
1565d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_any_nequal:
1566dc42910e98dc00760255cc4579da458de09175b9Eric Anholt	 resolve_bool_comparison(expr->operands[0], &op[0]);
1567dc42910e98dc00760255cc4579da458de09175b9Eric Anholt	 resolve_bool_comparison(expr->operands[1], &op[1]);
1568dc42910e98dc00760255cc4579da458de09175b9Eric Anholt
1569d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_CMP, reg_null_cmp, op[0], op[1]);
1570d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod =
1571d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    brw_conditional_for_comparison(expr->operation);
1572d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1573d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1574d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      default:
1575d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 assert(!"not reached");
1576d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 fail("bad cond code\n");
1577d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1578d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1579d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      return;
1580d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1581d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
158280ecb8f15b9ad7d6edcc85bd19f1867c368b09b6Eric Anholtout:
1583d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir->accept(this);
1584d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
158580ecb8f15b9ad7d6edcc85bd19f1867c368b09b6Eric Anholt   fs_inst *inst = emit(BRW_OPCODE_AND, reg_null_d, this->result, fs_reg(1));
158680ecb8f15b9ad7d6edcc85bd19f1867c368b09b6Eric Anholt   inst->conditional_mod = BRW_CONDITIONAL_NZ;
1587d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1588d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1589d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/**
1590d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * Emit a gen6 IF statement with the comparison folded into the IF
1591d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * instruction.
1592d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */
1593d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1594d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_if_gen6(ir_if *ir)
1595d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1596d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir_expression *expr = ir->condition->as_expression();
1597d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1598d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (expr) {
1599d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_reg op[2];
1600d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_inst *inst;
1601d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_reg temp;
1602d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1603d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(expr->get_num_operands() <= 2);
1604d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (unsigned int i = 0; i < expr->get_num_operands(); i++) {
1605d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 assert(expr->operands[i]->type->is_scalar());
1606d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1607d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 expr->operands[i]->accept(this);
1608d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 op[i] = this->result;
1609d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1610d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1611d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      switch (expr->operation) {
1612d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_unop_logic_not:
1613d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_logic_xor:
1614d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_logic_or:
1615d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_logic_and:
1616457eab5a9bf563b54d46fa57cba513837224b120Eric Anholt         /* For operations on bool arguments, only the low bit of the bool is
1617457eab5a9bf563b54d46fa57cba513837224b120Eric Anholt          * valid, and the others are undefined.  Fall back to the condition
1618457eab5a9bf563b54d46fa57cba513837224b120Eric Anholt          * code path.
1619457eab5a9bf563b54d46fa57cba513837224b120Eric Anholt          */
1620457eab5a9bf563b54d46fa57cba513837224b120Eric Anholt         break;
1621d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1622d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_unop_f2b:
1623d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_IF, reg_null_f, op[0], fs_reg(0));
1624d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_NZ;
1625d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 return;
1626d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1627d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_unop_i2b:
1628d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_IF, reg_null_d, op[0], fs_reg(0));
1629d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_NZ;
1630d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 return;
1631d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1632d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_greater:
1633d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_gequal:
1634d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_less:
1635d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_lequal:
1636d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_equal:
1637d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_all_equal:
1638d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_nequal:
1639d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_any_nequal:
1640457eab5a9bf563b54d46fa57cba513837224b120Eric Anholt	 resolve_bool_comparison(expr->operands[0], &op[0]);
1641457eab5a9bf563b54d46fa57cba513837224b120Eric Anholt	 resolve_bool_comparison(expr->operands[1], &op[1]);
1642457eab5a9bf563b54d46fa57cba513837224b120Eric Anholt
1643d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_IF, reg_null_d, op[0], op[1]);
1644d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod =
1645d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    brw_conditional_for_comparison(expr->operation);
1646d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 return;
1647d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      default:
1648d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 assert(!"not reached");
1649d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_IF, reg_null_d, op[0], fs_reg(0));
1650d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_NZ;
1651d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 fail("bad condition\n");
1652d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 return;
1653d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1654d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1655d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1656457eab5a9bf563b54d46fa57cba513837224b120Eric Anholt   emit_bool_to_cond_code(ir->condition);
1657457eab5a9bf563b54d46fa57cba513837224b120Eric Anholt   fs_inst *inst = emit(BRW_OPCODE_IF);
1658457eab5a9bf563b54d46fa57cba513837224b120Eric Anholt   inst->predicated = true;
1659d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1660d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1661d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1662d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_if *ir)
1663d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1664d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *inst;
1665d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
166679cba4c2b17456e2b25ac555c45e1c106b4e3f6bKenneth Graunke   if (intel->gen < 6 && c->dispatch_width == 16) {
1667d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fail("Can't support (non-uniform) control flow on 16-wide\n");
1668d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1669d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1670d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Don't point the annotation at the if statement, because then it plus
1671d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * the then and else blocks get printed.
1672d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    */
1673d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->base_ir = ir->condition;
1674d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1675d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (intel->gen == 6) {
1676d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit_if_gen6(ir);
1677d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else {
1678d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit_bool_to_cond_code(ir->condition);
1679d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1680d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_IF);
1681d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->predicated = true;
1682d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1683d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
168444ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt   foreach_list(node, &ir->then_instructions) {
168544ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt      ir_instruction *ir = (ir_instruction *)node;
1686d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->base_ir = ir;
1687d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke
1688d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->accept(this);
1689d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1690d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1691d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (!ir->else_instructions.is_empty()) {
1692d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_ELSE);
1693d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
169444ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt      foreach_list(node, &ir->else_instructions) {
169544ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt	 ir_instruction *ir = (ir_instruction *)node;
1696d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 this->base_ir = ir;
1697d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke
1698d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 ir->accept(this);
1699d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1700d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1701d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1702d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_ENDIF);
1703d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1704d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1705d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1706d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_loop *ir)
1707d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1708d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg counter = reg_undef;
1709d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
171099cd475cc9d3bd54140f84c24b55b9e05d7310a1Kenneth Graunke   if (intel->gen < 6 && c->dispatch_width == 16) {
1711d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fail("Can't support (non-uniform) control flow on 16-wide\n");
1712d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1713d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1714d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->counter) {
1715d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->base_ir = ir->counter;
1716d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->counter->accept(this);
1717d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      counter = *(variable_storage(ir->counter));
1718d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1719d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (ir->from) {
1720d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 this->base_ir = ir->from;
1721d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 ir->from->accept(this);
1722d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1723d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke	 emit(BRW_OPCODE_MOV, counter, this->result);
1724d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1725d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1726d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
17278890c759513597903997f519c69e9db30790b6f4Eric Anholt   this->base_ir = NULL;
1728d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_DO);
1729d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1730d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->to) {
1731d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->base_ir = ir->to;
1732d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->to->accept(this);
1733d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1734d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_inst *inst = emit(BRW_OPCODE_CMP, reg_null_cmp, counter, this->result);
1735d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->conditional_mod = brw_conditional_for_comparison(ir->cmp);
1736d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1737d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_BREAK);
1738d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->predicated = true;
1739d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1740d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
174144ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt   foreach_list(node, &ir->body_instructions) {
174244ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt      ir_instruction *ir = (ir_instruction *)node;
1743d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1744d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->base_ir = ir;
1745d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->accept(this);
1746d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1747d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1748d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->increment) {
1749d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->base_ir = ir->increment;
1750d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->increment->accept(this);
1751d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_ADD, counter, counter, this->result);
1752d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1753d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
17548890c759513597903997f519c69e9db30790b6f4Eric Anholt   this->base_ir = NULL;
1755d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_WHILE);
1756d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1757d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1758d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1759d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_loop_jump *ir)
1760d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1761d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   switch (ir->mode) {
1762d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_loop_jump::jump_break:
1763d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_BREAK);
1764d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
1765d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_loop_jump::jump_continue:
1766d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_CONTINUE);
1767d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
1768d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1769d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1770d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1771d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1772d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_call *ir)
1773d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1774d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   assert(!"FINISHME");
1775d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1776d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1777d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1778d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_return *ir)
1779d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1780d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   assert(!"FINISHME");
1781d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1782d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1783d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1784d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_function *ir)
1785d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1786d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Ignore function bodies other than main() -- we shouldn't see calls to
1787d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * them since they should all be inlined before we get to ir_to_mesa.
1788d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    */
1789d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (strcmp(ir->name, "main") == 0) {
1790d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      const ir_function_signature *sig;
1791d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      exec_list empty;
1792d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1793d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      sig = ir->matching_signature(&empty);
1794d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1795d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(sig);
1796d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
179744ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt      foreach_list(node, &sig->body) {
179844ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt	 ir_instruction *ir = (ir_instruction *)node;
1799d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 this->base_ir = ir;
1800d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke
1801d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 ir->accept(this);
1802d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1803d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1804d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1805d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1806d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1807d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_function_signature *ir)
1808d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1809d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   assert(!"not reached");
1810d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   (void)ir;
1811d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1812d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1813d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_inst *
1814d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit(fs_inst inst)
1815d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1816d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *list_inst = new(mem_ctx) fs_inst;
1817d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   *list_inst = inst;
1818d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1819d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (force_uncompressed_stack > 0)
1820d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      list_inst->force_uncompressed = true;
1821d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   else if (force_sechalf_stack > 0)
1822d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      list_inst->force_sechalf = true;
1823d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1824d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   list_inst->annotation = this->current_annotation;
1825d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   list_inst->ir = this->base_ir;
1826d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1827d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->instructions.push_tail(list_inst);
1828d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1829d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   return list_inst;
1830d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1831d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1832d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/** Emits a dummy fragment shader consisting of magenta for bringup purposes. */
1833d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1834d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_dummy_fs()
1835d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1836df5963c25641a7c3a4bbfcb81cc3dc771581590eKenneth Graunke   int reg_width = c->dispatch_width / 8;
1837df5963c25641a7c3a4bbfcb81cc3dc771581590eKenneth Graunke
1838d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Everyone's favorite color. */
1839df5963c25641a7c3a4bbfcb81cc3dc771581590eKenneth Graunke   emit(BRW_OPCODE_MOV, fs_reg(MRF, 2 + 0 * reg_width), fs_reg(1.0f));
1840df5963c25641a7c3a4bbfcb81cc3dc771581590eKenneth Graunke   emit(BRW_OPCODE_MOV, fs_reg(MRF, 2 + 1 * reg_width), fs_reg(0.0f));
1841df5963c25641a7c3a4bbfcb81cc3dc771581590eKenneth Graunke   emit(BRW_OPCODE_MOV, fs_reg(MRF, 2 + 2 * reg_width), fs_reg(1.0f));
1842df5963c25641a7c3a4bbfcb81cc3dc771581590eKenneth Graunke   emit(BRW_OPCODE_MOV, fs_reg(MRF, 2 + 3 * reg_width), fs_reg(0.0f));
1843d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1844d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *write;
1845d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   write = emit(FS_OPCODE_FB_WRITE, fs_reg(0), fs_reg(0));
18466750226e6d915742ebf96bae2cfcdd287b85db35Ben Widawsky   write->base_mrf = 2;
1847df5963c25641a7c3a4bbfcb81cc3dc771581590eKenneth Graunke   write->mlen = 4 * reg_width;
1848393b42240f22dbbfb4f089036319031ad36173f3Kenneth Graunke   write->eot = true;
1849d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1850d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1851d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/* The register location here is relative to the start of the URB
1852d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * data.  It will get adjusted to be a real location before
1853d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * generate_code() time.
1854d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */
1855d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtstruct brw_reg
1856d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::interp_reg(int location, int channel)
1857d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1858d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int regnr = urb_setup[location] * 2 + channel / 2;
1859d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int stride = (channel & 1) * 4;
1860d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1861d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   assert(urb_setup[location] != -1);
1862d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1863d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   return brw_vec1_grf(regnr, stride);
1864d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1865d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1866d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/** Emits the interpolation for the varying inputs. */
1867d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1868d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_interpolation_setup_gen4()
1869d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1870d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->current_annotation = "compute pixel centers";
1871d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->pixel_x = fs_reg(this, glsl_type::uint_type);
1872d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->pixel_y = fs_reg(this, glsl_type::uint_type);
1873d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->pixel_x.type = BRW_REGISTER_TYPE_UW;
1874d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->pixel_y.type = BRW_REGISTER_TYPE_UW;
1875d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1876d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(FS_OPCODE_PIXEL_X, this->pixel_x);
1877d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(FS_OPCODE_PIXEL_Y, this->pixel_y);
1878d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1879d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->current_annotation = "compute pixel deltas from v0";
1880d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (brw->has_pln) {
1881e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry      this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC] =
1882e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry         fs_reg(this, glsl_type::vec2_type);
1883e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry      this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC] =
1884e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry         this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC];
1885e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry      this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC].reg_offset++;
1886d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else {
1887e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry      this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC] =
1888e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry         fs_reg(this, glsl_type::float_type);
1889e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry      this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC] =
1890e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry         fs_reg(this, glsl_type::float_type);
1891d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1892e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry   emit(BRW_OPCODE_ADD, this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC],
1893d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	this->pixel_x, fs_reg(negate(brw_vec1_grf(1, 0))));
1894e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry   emit(BRW_OPCODE_ADD, this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC],
1895d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	this->pixel_y, fs_reg(negate(brw_vec1_grf(1, 1))));
1896d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1897d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->current_annotation = "compute pos.w and 1/pos.w";
1898d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Compute wpos.w.  It's always in our setup, since it's needed to
1899d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * interpolate the other attributes.
1900d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    */
1901d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->wpos_w = fs_reg(this, glsl_type::float_type);
1902e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry   emit(FS_OPCODE_LINTERP, wpos_w,
1903e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry        this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC],
1904e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry        this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC],
1905d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	interp_reg(FRAG_ATTRIB_WPOS, 3));
1906d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Compute the pixel 1/W value from wpos.w. */
1907d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->pixel_w = fs_reg(this, glsl_type::float_type);
190865b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt   emit_math(SHADER_OPCODE_RCP, this->pixel_w, wpos_w);
1909d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->current_annotation = NULL;
1910d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1911d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1912d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/** Emits the interpolation for the varying inputs. */
1913d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1914d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_interpolation_setup_gen6()
1915d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1916d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   struct brw_reg g1_uw = retype(brw_vec1_grf(1, 0), BRW_REGISTER_TYPE_UW);
1917d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1918d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* If the pixel centers end up used, the setup is the same as for gen4. */
1919d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->current_annotation = "compute pixel centers";
1920d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg int_pixel_x = fs_reg(this, glsl_type::uint_type);
1921d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg int_pixel_y = fs_reg(this, glsl_type::uint_type);
1922d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int_pixel_x.type = BRW_REGISTER_TYPE_UW;
1923d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int_pixel_y.type = BRW_REGISTER_TYPE_UW;
1924d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_ADD,
1925d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	int_pixel_x,
1926d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	fs_reg(stride(suboffset(g1_uw, 4), 2, 4, 0)),
1927d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	fs_reg(brw_imm_v(0x10101010)));
1928d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_ADD,
1929d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	int_pixel_y,
1930d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	fs_reg(stride(suboffset(g1_uw, 5), 2, 4, 0)),
1931d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	fs_reg(brw_imm_v(0x11001100)));
1932d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1933d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* As of gen6, we can no longer mix float and int sources.  We have
1934d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * to turn the integer pixel centers into floats for their actual
1935d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * use.
1936d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    */
1937d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->pixel_x = fs_reg(this, glsl_type::float_type);
1938d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->pixel_y = fs_reg(this, glsl_type::float_type);
1939d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_MOV, this->pixel_x, int_pixel_x);
1940d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_MOV, this->pixel_y, int_pixel_y);
1941d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1942d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->current_annotation = "compute pos.w";
1943d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->pixel_w = fs_reg(brw_vec8_grf(c->source_w_reg, 0));
1944d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->wpos_w = fs_reg(this, glsl_type::float_type);
194565b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt   emit_math(SHADER_OPCODE_RCP, this->wpos_w, this->pixel_w);
1946d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1947e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry   for (int i = 0; i < BRW_WM_BARYCENTRIC_INTERP_MODE_COUNT; ++i) {
1948e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry      uint8_t reg = c->barycentric_coord_reg[i];
1949e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry      this->delta_x[i] = fs_reg(brw_vec8_grf(reg, 0));
1950e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry      this->delta_y[i] = fs_reg(brw_vec8_grf(reg + 1, 0));
1951e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry   }
1952d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1953d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->current_annotation = NULL;
1954d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1955d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1956d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
19576d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholtfs_visitor::emit_color_write(int target, int index, int first_color_mrf)
1958d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1959d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int reg_width = c->dispatch_width / 8;
19604fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt   fs_inst *inst;
19616d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt   fs_reg color = outputs[target];
19626d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt   fs_reg mrf;
19636d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt
19646d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt   /* If there's no color data to be written, skip it. */
19656d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt   if (color.file == BAD_FILE)
19666d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt      return;
19676d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt
19686d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt   color.reg_offset += index;
1969d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
197083df7fbe62be2798d557142a47e01af86ec9e2e2Kenneth Graunke   if (c->dispatch_width == 8 || intel->gen >= 6) {
1971d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* SIMD8 write looks like:
1972d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 0: r0
1973d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 1: r1
1974d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 2: g0
1975d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 3: g1
1976d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       *
1977d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * gen6 SIMD16 DP write looks like:
1978d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 0: r0
1979d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 1: r1
1980d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 2: g0
1981d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 3: g1
1982d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 4: b0
1983d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 5: b1
1984d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 6: a0
1985d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 7: a1
1986d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       */
19874fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt      inst = emit(BRW_OPCODE_MOV,
1988e988d816e16f9c0844424472d689486a833931c3Eric Anholt		  fs_reg(MRF, first_color_mrf + index * reg_width, color.type),
19894fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt		  color);
19904fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt      inst->saturate = c->key.clamp_fragment_color;
1991d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else {
1992d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* pre-gen6 SIMD16 single source DP write looks like:
1993d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 0: r0
1994d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 1: g0
1995d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 2: b0
1996d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 3: a0
1997d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 4: r1
1998d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 5: g1
1999d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 6: b1
2000d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 7: a1
2001d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       */
2002d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (brw->has_compr4) {
2003d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 /* By setting the high bit of the MRF register number, we
2004d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  * indicate that we want COMPR4 mode - instead of doing the
2005d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  * usual destination + 1 for the second half we get
2006d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  * destination + 4.
2007d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  */
20084fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt	 inst = emit(BRW_OPCODE_MOV,
2009e988d816e16f9c0844424472d689486a833931c3Eric Anholt		     fs_reg(MRF, BRW_MRF_COMPR4 + first_color_mrf + index,
2010e988d816e16f9c0844424472d689486a833931c3Eric Anholt			    color.type),
20114fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt		     color);
20124fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt	 inst->saturate = c->key.clamp_fragment_color;
2013d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      } else {
2014d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 push_force_uncompressed();
2015e988d816e16f9c0844424472d689486a833931c3Eric Anholt	 inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, first_color_mrf + index,
2016e988d816e16f9c0844424472d689486a833931c3Eric Anholt					    color.type),
20174fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt		     color);
20184fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt	 inst->saturate = c->key.clamp_fragment_color;
2019d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 pop_force_uncompressed();
2020d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
2021d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 push_force_sechalf();
2022d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 color.sechalf = true;
2023e988d816e16f9c0844424472d689486a833931c3Eric Anholt	 inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, first_color_mrf + index + 4,
2024e988d816e16f9c0844424472d689486a833931c3Eric Anholt					    color.type),
20254fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt		     color);
20264fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt	 inst->saturate = c->key.clamp_fragment_color;
2027d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 pop_force_sechalf();
2028d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 color.sechalf = false;
2029d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
2030d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
2031d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
2032d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
2033d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
2034d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_fb_writes()
2035d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
2036d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->current_annotation = "FB write header";
20372e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunke   bool header_present = true;
2038b443ca96a55a06ee215a3f9a9e7dba558deeb58cKenneth Graunke   /* We can potentially have a message length of up to 15, so we have to set
2039b443ca96a55a06ee215a3f9a9e7dba558deeb58cKenneth Graunke    * base_mrf to either 0 or 1 in order to fit in m0..m15.
2040b443ca96a55a06ee215a3f9a9e7dba558deeb58cKenneth Graunke    */
2041b443ca96a55a06ee215a3f9a9e7dba558deeb58cKenneth Graunke   int base_mrf = 1;
2042eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke   int nr = base_mrf;
2043d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int reg_width = c->dispatch_width / 8;
204429362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt   bool do_dual_src = this->dual_src_output.file != BAD_FILE;
2045e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat   bool src0_alpha_to_render_target = false;
2046d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
204729362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt   if (c->dispatch_width == 16 && do_dual_src) {
204829362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt      fail("GL_ARB_blend_func_extended not yet supported in 16-wide.");
204929362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt      do_dual_src = false;
205029362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt   }
205129362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt
205229362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt   /* From the Sandy Bridge PRM, volume 4, page 198:
205329362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt    *
205429362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt    *     "Dispatched Pixel Enables. One bit per pixel indicating
205529362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt    *      which pixels were originally enabled when the thread was
205629362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt    *      dispatched. This field is only required for the end-of-
205729362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt    *      thread message and on all dual-source messages."
205829362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt    */
2059d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (intel->gen >= 6 &&
20609544e44262651a51ffdb3a572f99f902807a6205Paul Berry       !this->fp->UsesKill &&
206129362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt       !do_dual_src &&
2062d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       c->key.nr_color_regions == 1) {
2063d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      header_present = false;
2064d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
2065d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
2066d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (header_present) {
2067e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat      src0_alpha_to_render_target = intel->gen >= 6 &&
2068e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat				    !do_dual_src &&
2069e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat				    c->key.nr_color_regions > 1 &&
2070e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat				    c->key.sample_alpha_to_coverage;
20716750226e6d915742ebf96bae2cfcdd287b85db35Ben Widawsky      /* m2, m3 header */
2072d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      nr += 2;
2073d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
2074d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
2075d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (c->aa_dest_stencil_reg) {
2076d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      push_force_uncompressed();
2077d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, fs_reg(MRF, nr++),
2078d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	   fs_reg(brw_vec8_grf(c->aa_dest_stencil_reg, 0)));
2079d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      pop_force_uncompressed();
2080d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
2081d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
2082d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Reserve space for color. It'll be filled in per MRT below. */
2083d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int color_mrf = nr;
2084d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   nr += 4 * reg_width;
208529362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt   if (do_dual_src)
208629362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt      nr += 4;
2087e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat   if (src0_alpha_to_render_target)
2088e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat      nr += reg_width;
2089d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
2090d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (c->source_depth_to_render_target) {
2091d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (intel->gen == 6 && c->dispatch_width == 16) {
2092d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 /* For outputting oDepth on gen6, SIMD8 writes have to be
2093d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  * used.  This would require 8-wide moves of each half to
2094d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  * message regs, kind of like pre-gen5 SIMD16 FB writes.
2095d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  * Just bail on doing so for now.
2096d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  */
2097d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 fail("Missing support for simd16 depth writes on gen6\n");
2098d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
2099d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
2100d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (c->computes_depth) {
2101d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 /* Hand over gl_FragDepth. */
2102d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 assert(this->frag_depth);
2103d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 fs_reg depth = *(variable_storage(this->frag_depth));
2104d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
2105d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 emit(BRW_OPCODE_MOV, fs_reg(MRF, nr), depth);
2106d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      } else {
2107d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 /* Pass through the payload depth. */
2108d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 emit(BRW_OPCODE_MOV, fs_reg(MRF, nr),
2109d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	      fs_reg(brw_vec8_grf(c->source_depth_reg, 0)));
2110d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
2111d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      nr += reg_width;
2112d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
2113d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
2114d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (c->dest_depth_reg) {
2115d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, fs_reg(MRF, nr),
2116d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	   fs_reg(brw_vec8_grf(c->dest_depth_reg, 0)));
2117d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      nr += reg_width;
2118d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
2119d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
212029362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt   if (do_dual_src) {
212129362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt      fs_reg src0 = this->outputs[0];
212229362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt      fs_reg src1 = this->dual_src_output;
212329362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt
212429362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt      this->current_annotation = ralloc_asprintf(this->mem_ctx,
212529362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt						 "FB write src0");
212629362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt      for (int i = 0; i < 4; i++) {
212729362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt	 fs_inst *inst = emit(BRW_OPCODE_MOV,
212829362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt			      fs_reg(MRF, color_mrf + i, src0.type),
212929362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt			      src0);
213029362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt	 src0.reg_offset++;
213129362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt	 inst->saturate = c->key.clamp_fragment_color;
213229362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt      }
213329362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt
213429362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt      this->current_annotation = ralloc_asprintf(this->mem_ctx,
213529362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt						 "FB write src1");
213629362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt      for (int i = 0; i < 4; i++) {
213729362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt	 fs_inst *inst = emit(BRW_OPCODE_MOV,
213829362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt			      fs_reg(MRF, color_mrf + 4 + i, src1.type),
213929362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt			      src1);
214029362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt	 src1.reg_offset++;
214129362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt	 inst->saturate = c->key.clamp_fragment_color;
214229362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt      }
214329362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt
214429362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt      fs_inst *inst = emit(FS_OPCODE_FB_WRITE);
214529362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt      inst->target = 0;
214629362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt      inst->base_mrf = base_mrf;
214729362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt      inst->mlen = nr - base_mrf;
214829362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt      inst->eot = true;
214929362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt      inst->header_present = header_present;
215029362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt
215129362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt      c->prog_data.dual_src_blend = true;
215229362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt      this->current_annotation = NULL;
215329362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt      return;
215429362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt   }
215529362875f2613ad87abe7725ce3c56c36d16cf9bEric Anholt
2156d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   for (int target = 0; target < c->key.nr_color_regions; target++) {
2157d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->current_annotation = ralloc_asprintf(this->mem_ctx,
2158d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt						 "FB write target %d",
2159d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt						 target);
2160e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat      /* If src0_alpha_to_render_target is true, include source zero alpha
2161e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat       * data in RenderTargetWrite message for targets > 0.
2162e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat       */
2163e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat      int write_color_mrf = color_mrf;
2164e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat      if (src0_alpha_to_render_target && target != 0) {
2165e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat         fs_inst *inst;
2166e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat         fs_reg color = outputs[0];
2167e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat         color.reg_offset += 3;
2168e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat
2169e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat         inst = emit(BRW_OPCODE_MOV,
2170e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat		     fs_reg(MRF, write_color_mrf, color.type),
2171e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat		     color);
2172e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat         inst->saturate = c->key.clamp_fragment_color;
2173e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat         write_color_mrf = color_mrf + reg_width;
2174e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat      }
2175e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat
21762f18698220d8b27991fab550c4721590d17278e0Kenneth Graunke      for (unsigned i = 0; i < this->output_components[target]; i++)
2177e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat         emit_color_write(target, i, write_color_mrf);
2178d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
2179d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_inst *inst = emit(FS_OPCODE_FB_WRITE);
2180d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->target = target;
2181eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke      inst->base_mrf = base_mrf;
2182e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat      if (src0_alpha_to_render_target && target == 0)
2183e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat         inst->mlen = nr - base_mrf - reg_width;
2184e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat      else
2185e592f7df0361eb8b5c75944f0151c4e6b3f839ddAnuj Phogat         inst->mlen = nr - base_mrf;
2186d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (target == c->key.nr_color_regions - 1)
2187d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->eot = true;
2188d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->header_present = header_present;
2189d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
2190d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
2191d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (c->key.nr_color_regions == 0) {
219286e401b771ce4a6f9a728f76c5061c339f012d0aKenneth Graunke      /* Even if there's no color buffers enabled, we still need to send
219386e401b771ce4a6f9a728f76c5061c339f012d0aKenneth Graunke       * alpha out the pipeline to our null renderbuffer to support
219486e401b771ce4a6f9a728f76c5061c339f012d0aKenneth Graunke       * alpha-testing, alpha-to-coverage, and so on.
219586e401b771ce4a6f9a728f76c5061c339f012d0aKenneth Graunke       */
219686e401b771ce4a6f9a728f76c5061c339f012d0aKenneth Graunke      emit_color_write(0, 3, color_mrf);
2197d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
2198d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_inst *inst = emit(FS_OPCODE_FB_WRITE);
2199eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke      inst->base_mrf = base_mrf;
2200eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke      inst->mlen = nr - base_mrf;
2201d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->eot = true;
2202d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->header_present = header_present;
2203d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
2204d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
2205d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->current_annotation = NULL;
2206d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
220773b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt
220873b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholtvoid
220973b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholtfs_visitor::resolve_ud_negate(fs_reg *reg)
221073b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt{
221173b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt   if (reg->type != BRW_REGISTER_TYPE_UD ||
221273b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt       !reg->negate)
221373b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt      return;
221473b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt
221573b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt   fs_reg temp = fs_reg(this, glsl_type::uint_type);
221673b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt   emit(BRW_OPCODE_MOV, temp, *reg);
221773b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt   *reg = temp;
221873b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt}
2219dc42910e98dc00760255cc4579da458de09175b9Eric Anholt
2220dc42910e98dc00760255cc4579da458de09175b9Eric Anholtvoid
2221dc42910e98dc00760255cc4579da458de09175b9Eric Anholtfs_visitor::resolve_bool_comparison(ir_rvalue *rvalue, fs_reg *reg)
2222dc42910e98dc00760255cc4579da458de09175b9Eric Anholt{
2223dc42910e98dc00760255cc4579da458de09175b9Eric Anholt   if (rvalue->type != glsl_type::bool_type)
2224dc42910e98dc00760255cc4579da458de09175b9Eric Anholt      return;
2225dc42910e98dc00760255cc4579da458de09175b9Eric Anholt
2226dc42910e98dc00760255cc4579da458de09175b9Eric Anholt   fs_reg temp = fs_reg(this, glsl_type::bool_type);
2227dc42910e98dc00760255cc4579da458de09175b9Eric Anholt   emit(BRW_OPCODE_AND, temp, *reg, fs_reg(1));
2228dc42910e98dc00760255cc4579da458de09175b9Eric Anholt   *reg = temp;
2229dc42910e98dc00760255cc4579da458de09175b9Eric Anholt}
2230fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt
2231fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholtfs_visitor::fs_visitor(struct brw_wm_compile *c, struct gl_shader_program *prog,
2232fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt                       struct brw_shader *shader)
2233fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt{
2234fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt   this->c = c;
2235fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt   this->p = &c->func;
2236fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt   this->brw = p->brw;
2237fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt   this->fp = (struct gl_fragment_program *)
2238fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt      prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program;
2239fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt   this->prog = prog;
2240fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt   this->intel = &brw->intel;
2241fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt   this->ctx = &intel->ctx;
2242fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt   this->mem_ctx = ralloc_context(NULL);
2243fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt   this->shader = shader;
2244fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt   this->failed = false;
2245fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt   this->variable_ht = hash_table_ctor(0,
2246fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt                                       hash_table_pointer_hash,
2247fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt                                       hash_table_pointer_compare);
2248fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt
2249fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt   /* There's a question that appears to be left open in the spec:
2250fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt    * How do implicit dst conversions interact with the CMP
2251fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt    * instruction or conditional mods?  On gen6, the instruction:
2252fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt    *
2253fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt    * CMP null<d> src0<f> src1<f>
2254fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt    *
2255fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt    * will do src1 - src0 and compare that result as if it was an
2256fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt    * integer.  On gen4, it will do src1 - src0 as float, convert
2257fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt    * the result to int, and compare as int.  In between, it
2258fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt    * appears that it does src1 - src0 and does the compare in the
2259fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt    * execution type so dst type doesn't matter.
2260fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt    */
2261fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt   if (this->intel->gen > 4)
2262fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt      this->reg_null_cmp = reg_null_d;
2263fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt   else
2264fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt      this->reg_null_cmp = reg_null_f;
2265fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt
2266fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt   this->frag_depth = NULL;
2267fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt   memset(this->outputs, 0, sizeof(this->outputs));
22686928bea7ca1f2ed308d8255c6816f44467306255Kenneth Graunke   memset(this->output_components, 0, sizeof(this->output_components));
2269fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt   this->first_non_payload_grf = 0;
2270fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt   this->max_grf = intel->gen >= 7 ? GEN7_MRF_HACK_START : BRW_MAX_GRF;
2271fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt
2272fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt   this->current_annotation = NULL;
2273fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt   this->base_ir = NULL;
2274fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt
2275fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt   this->virtual_grf_sizes = NULL;
2276a6411520b40d59a8806289c7aaea4a6b26a54443Eric Anholt   this->virtual_grf_count = 0;
2277fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt   this->virtual_grf_array_size = 0;
2278fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt   this->virtual_grf_def = NULL;
2279fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt   this->virtual_grf_use = NULL;
2280fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt   this->live_intervals_valid = false;
2281fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt
2282fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt   this->force_uncompressed_stack = 0;
2283fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt   this->force_sechalf_stack = 0;
2284fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt}
2285fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt
2286fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholtfs_visitor::~fs_visitor()
2287fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt{
2288fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt   ralloc_free(this->mem_ctx);
2289fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt   hash_table_dtor(this->variable_ht);
2290fe27916ddf41b9fb60c334c47c1aa81b8dd9005eEric Anholt}
2291