brw_fs_visitor.cpp revision 07e621c52329cd17b97051a26493626228d043b9
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
756d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt      if (ir->location == FRAG_RESULT_COLOR) {
766d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt	 /* Writing gl_FragColor outputs to all color regions. */
7751e5a266c1e1c12c4f0d82bee3caff008a41c9fdEric Anholt	 for (int i = 0; i < MAX2(c->key.nr_color_regions, 1); i++) {
786d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt	    this->outputs[i] = *reg;
796d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt	 }
806d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt      } else if (ir->location == FRAG_RESULT_DEPTH) {
816d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt	 this->frag_depth = ir;
826d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt      } else {
836d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt	 /* gl_FragData or a user-defined FS output */
846d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt	 assert(ir->location >= FRAG_RESULT_DATA0 &&
856d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt		ir->location < FRAG_RESULT_DATA0 + BRW_MAX_DRAW_BUFFERS);
866d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt
876d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt	 /* General color output. */
886d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt	 for (unsigned int i = 0; i < MAX2(1, ir->type->length); i++) {
896d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt	    int output = ir->location - FRAG_RESULT_DATA0 + i;
906d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt	    this->outputs[output] = *reg;
916d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt	    this->outputs[output].reg_offset += 4 * i;
926d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt	 }
936d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt      }
946d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt   } else if (ir->mode == ir_var_uniform) {
95d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      int param_index = c->prog_data.nr_params;
96d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
97d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (c->dispatch_width == 16) {
98d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 if (!variable_storage(ir)) {
99d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    fail("Failed to find uniform '%s' in 16-wide\n", ir->name);
100d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 }
101d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 return;
102d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
103d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
104d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (!strncmp(ir->name, "gl_", 3)) {
105d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 setup_builtin_uniform_values(ir);
106d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      } else {
107d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 setup_uniform_values(ir->location, ir->type);
108d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
109d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
110d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      reg = new(this->mem_ctx) fs_reg(UNIFORM, param_index);
111d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      reg->type = brw_type_for_base_type(ir->type);
112d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
113d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
114d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (!reg)
115d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      reg = new(this->mem_ctx) fs_reg(this, ir->type);
116d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
117d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   hash_table_insert(this->variable_ht, reg, ir);
118d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
119d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
120d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
121d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_dereference_variable *ir)
122d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
123d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg *reg = variable_storage(ir->var);
124d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->result = *reg;
125d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
126d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
127d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
128d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_dereference_record *ir)
129d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
130d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   const glsl_type *struct_type = ir->record->type;
131d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
132d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir->record->accept(this);
133d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
134d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   unsigned int offset = 0;
135d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   for (unsigned int i = 0; i < struct_type->length; i++) {
136d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0)
137d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
138d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      offset += type_size(struct_type->fields.structure[i].type);
139d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
140d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->result.reg_offset += offset;
141d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->result.type = brw_type_for_base_type(ir->type);
142d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
143d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
144d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
145d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_dereference_array *ir)
146d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
147d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir_constant *index;
148d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int element_size;
149d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
150d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir->array->accept(this);
151d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   index = ir->array_index->as_constant();
152d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
153d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   element_size = type_size(ir->type);
154d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->result.type = brw_type_for_base_type(ir->type);
155d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
156d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (index) {
157b76378d46a211521582cfab56dc05031a57502a6Eric Anholt      assert(this->result.file == UNIFORM || this->result.file == GRF);
158d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->result.reg_offset += index->value.i[0] * element_size;
159d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else {
160d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!"FINISHME: non-constant array element");
161d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
162d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
163d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
164d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/* Instruction selection: Produce a MOV.sat instead of
165d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * MIN(MAX(val, 0), 1) when possible.
166d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */
167d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtbool
168d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::try_emit_saturate(ir_expression *ir)
169d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
170d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir_rvalue *sat_val = ir->as_rvalue_to_saturate();
171d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
172d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (!sat_val)
173d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      return false;
174d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
175d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   sat_val->accept(this);
176d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg src = this->result;
177d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
178d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->result = fs_reg(this, ir->type);
179d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *inst = emit(BRW_OPCODE_MOV, this->result, src);
180d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->saturate = true;
181d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
182d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   return true;
183d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
184d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
185d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
186d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_expression *ir)
187d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
188d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   unsigned int operand;
189d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg op[2], temp;
190d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *inst;
191d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
192d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   assert(ir->get_num_operands() <= 2);
193d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
194d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (try_emit_saturate(ir))
195d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      return;
196d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
197d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   for (operand = 0; operand < ir->get_num_operands(); operand++) {
198d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->operands[operand]->accept(this);
199d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (this->result.file == BAD_FILE) {
200d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 ir_print_visitor v;
201d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 fail("Failed to get tree for expression operand:\n");
202d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 ir->operands[operand]->accept(&v);
203d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
204d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      op[operand] = this->result;
205d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
206d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* Matrix expression operands should have been broken down to vector
207d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * operations already.
208d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       */
209d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!ir->operands[operand]->type->is_matrix());
210d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* And then those vector operands should have been broken down to scalar.
211d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       */
212d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!ir->operands[operand]->type->is_vector());
213d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
214d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
215d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke   /* Storage for our result.  If our result goes into an assignment, it will
216d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke    * just get copy-propagated out, so no worries.
217d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    */
218d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke   this->result = fs_reg(this, ir->type);
219d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
220d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   switch (ir->operation) {
221d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_logic_not:
222d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* Note that BRW_OPCODE_NOT is not appropriate here, since it is
223d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * ones complement of the whole register, not just bit 0.
224d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       */
225d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_XOR, this->result, op[0], fs_reg(1));
226d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
227d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_neg:
228d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      op[0].negate = !op[0].negate;
229d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->result = op[0];
230d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
231d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_abs:
232d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      op[0].abs = true;
233d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      op[0].negate = false;
234d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->result = op[0];
235d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
236d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_sign:
237d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      temp = fs_reg(this, ir->type);
238d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
239d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, this->result, fs_reg(0.0f));
240d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
241d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_CMP, reg_null_f, op[0], fs_reg(0.0f));
242d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->conditional_mod = BRW_CONDITIONAL_G;
243d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_MOV, this->result, fs_reg(1.0f));
244d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->predicated = true;
245d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
246d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_CMP, reg_null_f, op[0], fs_reg(0.0f));
247d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->conditional_mod = BRW_CONDITIONAL_L;
248d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_MOV, this->result, fs_reg(-1.0f));
249d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->predicated = true;
250d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
251d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
252d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_rcp:
25365b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt      emit_math(SHADER_OPCODE_RCP, this->result, op[0]);
254d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
255d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
256d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_exp2:
25765b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt      emit_math(SHADER_OPCODE_EXP2, this->result, op[0]);
258d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
259d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_log2:
26065b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt      emit_math(SHADER_OPCODE_LOG2, this->result, op[0]);
261d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
262d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_exp:
263d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_log:
264d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!"not reached: should be handled by ir_explog_to_explog2");
265d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
266d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_sin:
267d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_sin_reduced:
26865b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt      emit_math(SHADER_OPCODE_SIN, this->result, op[0]);
269d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
270d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_cos:
271d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_cos_reduced:
27265b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt      emit_math(SHADER_OPCODE_COS, this->result, op[0]);
273d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
274d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
275d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_dFdx:
276d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(FS_OPCODE_DDX, this->result, op[0]);
277d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
278d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_dFdy:
279d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(FS_OPCODE_DDY, this->result, op[0]);
280d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
281d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
282d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_add:
283d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_ADD, this->result, op[0], op[1]);
284d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
285d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_sub:
286d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!"not reached: should be handled by ir_sub_to_add_neg");
287d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
288d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
289d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_mul:
2903f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt      if (ir->type->is_integer()) {
2913f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	 /* For integer multiplication, the MUL uses the low 16 bits
2923f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	  * of one of the operands (src0 on gen6, src1 on gen7).  The
2933f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	  * MACH accumulates in the contribution of the upper 16 bits
2943f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	  * of that operand.
2953f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	  *
2963f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	  * FINISHME: Emit just the MUL if we know an operand is small
2973f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	  * enough.
2983f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	  */
2993f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	 struct brw_reg acc = retype(brw_acc_reg(), BRW_REGISTER_TYPE_D);
3003f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt
3013f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	 emit(BRW_OPCODE_MUL, acc, op[0], op[1]);
3023f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	 emit(BRW_OPCODE_MACH, reg_null_d, op[0], op[1]);
3033f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	 emit(BRW_OPCODE_MOV, this->result, fs_reg(acc));
3043f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt      } else {
3053f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	 emit(BRW_OPCODE_MUL, this->result, op[0], op[1]);
3063f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt      }
307d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
308d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_div:
30983dc891b41c0224f5ba3624b3e3560129e644e28Eric Anholt      if (intel->gen >= 7 && c->dispatch_width == 16)
31083dc891b41c0224f5ba3624b3e3560129e644e28Eric Anholt	 fail("16-wide INTDIV unsupported\n");
31183dc891b41c0224f5ba3624b3e3560129e644e28Eric Anholt
312ff8f272b0d02b41a0ce34ab6af7119b9e06f4961Kenneth Graunke      /* Floating point should be lowered by DIV_TO_MUL_RCP in the compiler. */
313ff8f272b0d02b41a0ce34ab6af7119b9e06f4961Kenneth Graunke      assert(ir->type->is_integer());
314ff8f272b0d02b41a0ce34ab6af7119b9e06f4961Kenneth Graunke      emit_math(SHADER_OPCODE_INT_QUOTIENT, this->result, op[0], op[1]);
315d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
316d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_mod:
31783dc891b41c0224f5ba3624b3e3560129e644e28Eric Anholt      if (intel->gen >= 7 && c->dispatch_width == 16)
31883dc891b41c0224f5ba3624b3e3560129e644e28Eric Anholt	 fail("16-wide INTDIV unsupported\n");
31983dc891b41c0224f5ba3624b3e3560129e644e28Eric Anholt
320ff8f272b0d02b41a0ce34ab6af7119b9e06f4961Kenneth Graunke      /* Floating point should be lowered by MOD_TO_FRACT in the compiler. */
321ff8f272b0d02b41a0ce34ab6af7119b9e06f4961Kenneth Graunke      assert(ir->type->is_integer());
322ff8f272b0d02b41a0ce34ab6af7119b9e06f4961Kenneth Graunke      emit_math(SHADER_OPCODE_INT_REMAINDER, this->result, op[0], op[1]);
323d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
324d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
325d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_less:
326d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_greater:
327d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_lequal:
328d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_gequal:
329d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_equal:
330d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_all_equal:
331d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_nequal:
332d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_any_nequal:
333d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      temp = this->result;
334d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* original gen4 does implicit conversion before comparison. */
335d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (intel->gen < 5)
336d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 temp.type = op[0].type;
337d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
33873b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt      resolve_ud_negate(&op[0]);
33973b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt      resolve_ud_negate(&op[1]);
34073b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt
341d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_CMP, temp, op[0], op[1]);
342d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->conditional_mod = brw_conditional_for_comparison(ir->operation);
343d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_AND, this->result, this->result, fs_reg(0x1));
344d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
345d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
346d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_logic_xor:
347d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_XOR, this->result, op[0], op[1]);
348d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
349d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
350d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_logic_or:
351d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_OR, this->result, op[0], op[1]);
352d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
353d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
354d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_logic_and:
355d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_AND, this->result, op[0], op[1]);
356d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
357d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
358d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_dot:
359d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_any:
360d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!"not reached: should be handled by brw_fs_channel_expressions");
361d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
362d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
363d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_noise:
364d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!"not reached: should be handled by lower_noise");
365d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
366d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
367d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_quadop_vector:
368d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!"not reached: should be handled by lower_quadop_vector");
369d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
370d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
371d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_sqrt:
37265b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt      emit_math(SHADER_OPCODE_SQRT, this->result, op[0]);
373d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
374d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
375d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_rsq:
37665b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt      emit_math(SHADER_OPCODE_RSQ, this->result, op[0]);
377d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
378d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
379b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke   case ir_unop_i2u:
380b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke      op[0].type = BRW_REGISTER_TYPE_UD;
381b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke      this->result = op[0];
382b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke      break;
383b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke   case ir_unop_u2i:
384b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke      op[0].type = BRW_REGISTER_TYPE_D;
385b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke      this->result = op[0];
386b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke      break;
387d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_i2f:
3884bc5bfb641bce931bf35f0e78ec2b44263d152baKenneth Graunke   case ir_unop_u2f:
389d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_b2f:
390d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_b2i:
391d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_f2i:
392d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, this->result, op[0]);
393d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
394d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_f2b:
395d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_i2b:
396d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      temp = this->result;
397d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* original gen4 does implicit conversion before comparison. */
398d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (intel->gen < 5)
399d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 temp.type = op[0].type;
400d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
40173b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt      resolve_ud_negate(&op[0]);
40273b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt
403d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_CMP, temp, op[0], fs_reg(0.0f));
404d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->conditional_mod = BRW_CONDITIONAL_NZ;
405d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_AND, this->result, this->result, fs_reg(1));
406d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
407d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
408d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_trunc:
409d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_RNDZ, this->result, op[0]);
410d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
411d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_ceil:
412d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      op[0].negate = !op[0].negate;
413d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_RNDD, this->result, op[0]);
414d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->result.negate = true;
415d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
416d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_floor:
417d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_RNDD, this->result, op[0]);
418d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
419d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_fract:
420d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_FRC, this->result, op[0]);
421d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
422d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_round_even:
423d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_RNDE, this->result, op[0]);
424d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
425d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
426d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_min:
42773b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt      resolve_ud_negate(&op[0]);
42873b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt      resolve_ud_negate(&op[1]);
42973b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt
430c331b3123ecda127919458e24848b7c1596525acEric Anholt      if (intel->gen >= 6) {
431c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]);
432c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_L;
433c331b3123ecda127919458e24848b7c1596525acEric Anholt      } else {
434c331b3123ecda127919458e24848b7c1596525acEric Anholt	 /* Unalias the destination */
435c331b3123ecda127919458e24848b7c1596525acEric Anholt	 this->result = fs_reg(this, ir->type);
436d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
437c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst = emit(BRW_OPCODE_CMP, this->result, op[0], op[1]);
438c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_L;
439d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
440c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]);
441c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst->predicated = true;
442c331b3123ecda127919458e24848b7c1596525acEric Anholt      }
443d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
444d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_max:
44573b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt      resolve_ud_negate(&op[0]);
44673b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt      resolve_ud_negate(&op[1]);
44773b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt
448c331b3123ecda127919458e24848b7c1596525acEric Anholt      if (intel->gen >= 6) {
449c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]);
450c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_GE;
451c331b3123ecda127919458e24848b7c1596525acEric Anholt      } else {
452c331b3123ecda127919458e24848b7c1596525acEric Anholt	 /* Unalias the destination */
453c331b3123ecda127919458e24848b7c1596525acEric Anholt	 this->result = fs_reg(this, ir->type);
454d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
455c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst = emit(BRW_OPCODE_CMP, this->result, op[0], op[1]);
456c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_G;
457d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
458c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]);
459c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst->predicated = true;
460c331b3123ecda127919458e24848b7c1596525acEric Anholt      }
461d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
462d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
463d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_pow:
46465b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt      emit_math(SHADER_OPCODE_POW, this->result, op[0], op[1]);
465d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
466d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
467d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_bit_not:
468d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_NOT, this->result, op[0]);
469d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
470d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_bit_and:
471d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_AND, this->result, op[0], op[1]);
472d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
473d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_bit_xor:
474d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_XOR, this->result, op[0], op[1]);
475d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
476d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_bit_or:
477d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_OR, this->result, op[0], op[1]);
478d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
479d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
480d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_lshift:
4817de6e749df90a214d1547956dd66cfec6edcb446Eric Anholt      inst = emit(BRW_OPCODE_SHL, this->result, op[0], op[1]);
4827de6e749df90a214d1547956dd66cfec6edcb446Eric Anholt      break;
4837de6e749df90a214d1547956dd66cfec6edcb446Eric Anholt
484d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_rshift:
4857de6e749df90a214d1547956dd66cfec6edcb446Eric Anholt      if (ir->type->base_type == GLSL_TYPE_INT)
4867de6e749df90a214d1547956dd66cfec6edcb446Eric Anholt	 inst = emit(BRW_OPCODE_ASR, this->result, op[0], op[1]);
4877de6e749df90a214d1547956dd66cfec6edcb446Eric Anholt      else
4887de6e749df90a214d1547956dd66cfec6edcb446Eric Anholt	 inst = emit(BRW_OPCODE_SHR, this->result, op[0], op[1]);
489d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
490d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
491d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
492d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
493d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
494d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_assignment_writes(fs_reg &l, fs_reg &r,
495d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt				   const glsl_type *type, bool predicated)
496d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
497d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   switch (type->base_type) {
498d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case GLSL_TYPE_FLOAT:
499d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case GLSL_TYPE_UINT:
500d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case GLSL_TYPE_INT:
501d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case GLSL_TYPE_BOOL:
502d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (unsigned int i = 0; i < type->components(); i++) {
503d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 l.type = brw_type_for_base_type(type);
504d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 r.type = brw_type_for_base_type(type);
505d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
506d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 if (predicated || !l.equals(&r)) {
507d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    fs_inst *inst = emit(BRW_OPCODE_MOV, l, r);
508d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    inst->predicated = predicated;
509d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 }
510d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
511d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 l.reg_offset++;
512d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 r.reg_offset++;
513d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
514d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
515d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case GLSL_TYPE_ARRAY:
516d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (unsigned int i = 0; i < type->length; i++) {
517d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 emit_assignment_writes(l, r, type->fields.array, predicated);
518d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
519d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
520d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
521d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case GLSL_TYPE_STRUCT:
522d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (unsigned int i = 0; i < type->length; i++) {
523d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 emit_assignment_writes(l, r, type->fields.structure[i].type,
524d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt				predicated);
525d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
526d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
527d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
528d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case GLSL_TYPE_SAMPLER:
529d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
530d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
531d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   default:
532d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!"not reached");
533d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
534d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
535d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
536d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
537dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke/* If the RHS processing resulted in an instruction generating a
538dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke * temporary value, and it would be easy to rewrite the instruction to
539dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke * generate its result right into the LHS instead, do so.  This ends
540dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke * up reliably removing instructions where it can be tricky to do so
541dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke * later without real UD chain information.
542dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke */
543dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunkebool
544dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunkefs_visitor::try_rewrite_rhs_to_dst(ir_assignment *ir,
545dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke                                   fs_reg dst,
546dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke                                   fs_reg src,
547dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke                                   fs_inst *pre_rhs_inst,
548dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke                                   fs_inst *last_rhs_inst)
549dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke{
550dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   if (pre_rhs_inst == last_rhs_inst)
551dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke      return false; /* No instructions generated to work with. */
552dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke
553dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   /* Only attempt if we're doing a direct assignment. */
554dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   if (ir->condition ||
555dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke       !(ir->lhs->type->is_scalar() ||
556dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke        (ir->lhs->type->is_vector() &&
557dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke         ir->write_mask == (1 << ir->lhs->type->vector_elements) - 1)))
558dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke      return false;
559dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke
560dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   /* Make sure the last instruction generated our source reg. */
561dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   if (last_rhs_inst->predicated ||
562dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke       last_rhs_inst->force_uncompressed ||
563dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke       last_rhs_inst->force_sechalf ||
564dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke       !src.equals(&last_rhs_inst->dst))
565dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke      return false;
566dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke
567dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   /* Success!  Rewrite the instruction. */
568dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   last_rhs_inst->dst = dst;
569dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke
570dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   return true;
571dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke}
572dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke
573d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
574d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_assignment *ir)
575d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
576eb86bb55f5faef67c21604db19210c6788592679Kenneth Graunke   fs_reg l, r;
577d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *inst;
578d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
579d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* FINISHME: arrays on the lhs */
580d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir->lhs->accept(this);
581d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   l = this->result;
582d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
583dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   fs_inst *pre_rhs_inst = (fs_inst *) this->instructions.get_tail();
584dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke
585d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir->rhs->accept(this);
586d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   r = this->result;
587d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
588dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   fs_inst *last_rhs_inst = (fs_inst *) this->instructions.get_tail();
589dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke
590d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   assert(l.file != BAD_FILE);
591d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   assert(r.file != BAD_FILE);
592d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
593dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   if (try_rewrite_rhs_to_dst(ir, l, r, pre_rhs_inst, last_rhs_inst))
594dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke      return;
595dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke
596d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->condition) {
597d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit_bool_to_cond_code(ir->condition);
598d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
599d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
600d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->lhs->type->is_scalar() ||
601d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       ir->lhs->type->is_vector()) {
602d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (int i = 0; i < ir->lhs->type->vector_elements; i++) {
603d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 if (ir->write_mask & (1 << i)) {
604d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke	    inst = emit(BRW_OPCODE_MOV, l, r);
605d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke	    if (ir->condition)
606d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	       inst->predicated = true;
607d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    r.reg_offset++;
608d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 }
609d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 l.reg_offset++;
610d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
611d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else {
612d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit_assignment_writes(l, r, ir->lhs->type, ir->condition != NULL);
613d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
614d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
615d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
616d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_inst *
617d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate,
618d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt			      int sampler)
619d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
620d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int mlen;
621d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int base_mrf = 1;
622d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   bool simd16 = false;
623d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg orig_dst;
624d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
625d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* g0 header. */
626d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   mlen = 1;
627d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
6286430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke   if (ir->shadow_comparitor && ir->op != ir_txd) {
629d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
63007e621c52329cd17b97051a26493626228d043b9Eric Anholt	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i), coordinate);
631d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 coordinate.reg_offset++;
632d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
633d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* gen4's SIMD8 sampler always has the slots for u,v,r present. */
634d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen += 3;
635d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
636d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (ir->op == ir_tex) {
637d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 /* There's no plain shadow compare message, so we use shadow
638d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  * compare with a bias of 0.0.
639d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  */
640d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), fs_reg(0.0f));
641d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 mlen++;
642d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      } else if (ir->op == ir_txb) {
643d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 ir->lod_info.bias->accept(this);
644d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
645d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 mlen++;
646d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      } else {
647d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 assert(ir->op == ir_txl);
648d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 ir->lod_info.lod->accept(this);
649d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
650d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 mlen++;
651d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
652d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
653d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->shadow_comparitor->accept(this);
654d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
655d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen++;
656d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else if (ir->op == ir_tex) {
657d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
65807e621c52329cd17b97051a26493626228d043b9Eric Anholt	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i), coordinate);
659d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 coordinate.reg_offset++;
660d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
661d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* gen4's SIMD8 sampler always has the slots for u,v,r present. */
662d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen += 3;
663d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else if (ir->op == ir_txd) {
6646c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      ir->lod_info.grad.dPdx->accept(this);
6656c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      fs_reg dPdx = this->result;
6666c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke
6676c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      ir->lod_info.grad.dPdy->accept(this);
6686c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      fs_reg dPdy = this->result;
6696c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke
6706c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
6716c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i), coordinate);
6726c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke	 coordinate.reg_offset++;
6736c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      }
6746c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      /* the slots for u and v are always present, but r is optional */
6756c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      mlen += MAX2(ir->coordinate->type->vector_elements, 2);
6766c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke
6776c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      /*  P   = u, v, r
6786c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       * dPdx = dudx, dvdx, drdx
6796c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       * dPdy = dudy, dvdy, drdy
6806c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       *
6813e1fd13f605f16e8b48f3a9b71910a3c66eb84b5Kenneth Graunke       * 1-arg: Does not exist.
6823e1fd13f605f16e8b48f3a9b71910a3c66eb84b5Kenneth Graunke       *
6836c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       * 2-arg: dudx   dvdx   dudy   dvdy
6846c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       *        dPdx.x dPdx.y dPdy.x dPdy.y
6856c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       *        m4     m5     m6     m7
6866c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       *
6876c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       * 3-arg: dudx   dvdx   drdx   dudy   dvdy   drdy
6886c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       *        dPdx.x dPdx.y dPdx.z dPdy.x dPdy.y dPdy.z
6896c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       *        m5     m6     m7     m8     m9     m10
6906c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       */
6916c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      for (int i = 0; i < ir->lod_info.grad.dPdx->type->vector_elements; i++) {
6926c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdx);
6936c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke	 dPdx.reg_offset++;
6946c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      }
6953e1fd13f605f16e8b48f3a9b71910a3c66eb84b5Kenneth Graunke      mlen += MAX2(ir->lod_info.grad.dPdx->type->vector_elements, 2);
6966c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke
6976c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      for (int i = 0; i < ir->lod_info.grad.dPdy->type->vector_elements; i++) {
6986c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdy);
6996c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke	 dPdy.reg_offset++;
7006c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      }
7013e1fd13f605f16e8b48f3a9b71910a3c66eb84b5Kenneth Graunke      mlen += MAX2(ir->lod_info.grad.dPdy->type->vector_elements, 2);
7024eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke   } else if (ir->op == ir_txs) {
7034eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke      /* There's no SIMD8 resinfo message on Gen4.  Use SIMD16 instead. */
7044eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke      simd16 = true;
7054eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke      ir->lod_info.lod->accept(this);
7064eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), this->result);
7074eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke      mlen += 2;
708d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else {
709d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* Oh joy.  gen4 doesn't have SIMD8 non-shadow-compare bias/lod
710d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * instructions.  We'll need to do SIMD16 here.
711d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       */
7124eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke      simd16 = true;
71347b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke      assert(ir->op == ir_txb || ir->op == ir_txl || ir->op == ir_txf);
714d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
715d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
71607e621c52329cd17b97051a26493626228d043b9Eric Anholt	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i * 2, coordinate.type),
71707e621c52329cd17b97051a26493626228d043b9Eric Anholt	      coordinate);
718d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 coordinate.reg_offset++;
719d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
720d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
72147b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke      /* Initialize the rest of u/v/r with 0.0.  Empirically, this seems to
72247b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke       * be necessary for TXF (ld), but seems wise to do for all messages.
72347b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke       */
72447b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke      for (int i = ir->coordinate->type->vector_elements; i < 3; i++) {
72547b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i * 2), fs_reg(0.0f));
72647b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke      }
72747b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke
728d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* lod/bias appears after u/v/r. */
729d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen += 6;
730d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
731d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (ir->op == ir_txb) {
732d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 ir->lod_info.bias->accept(this);
733d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
734d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 mlen++;
735d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      } else {
736d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 ir->lod_info.lod->accept(this);
73747b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, this->result.type),
73847b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke			      this->result);
739d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 mlen++;
740d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
741d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
742d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* The unused upper half. */
743d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen++;
7444eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke   }
745d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
7464eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke   if (simd16) {
747d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* Now, since we're doing simd16, the return is 2 interleaved
748d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * vec4s where the odd-indexed ones are junk. We'll need to move
749d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * this weirdness around to the expected layout.
750d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       */
751d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      orig_dst = dst;
7524eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke      const glsl_type *vec_type =
7534eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke	 glsl_type::get_instance(ir->type->base_type, 4, 1);
7544eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke      dst = fs_reg(this, glsl_type::get_array_instance(vec_type, 2));
7554eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke      dst.type = intel->is_g4x ? brw_type_for_base_type(ir->type)
7564eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke			       : BRW_REGISTER_TYPE_F;
757d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
758d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
759d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *inst = NULL;
760d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   switch (ir->op) {
761d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_tex:
762febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke      inst = emit(SHADER_OPCODE_TEX, dst);
763d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
764d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_txb:
765d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(FS_OPCODE_TXB, dst);
766d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
767d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_txl:
768febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke      inst = emit(SHADER_OPCODE_TXL, dst);
769d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
770d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_txd:
771febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke      inst = emit(SHADER_OPCODE_TXD, dst);
772d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
7731e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke   case ir_txs:
774febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke      inst = emit(SHADER_OPCODE_TXS, dst);
7754eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke      break;
7764eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke   case ir_txf:
777febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke      inst = emit(SHADER_OPCODE_TXF, dst);
778d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
779d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
780d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->base_mrf = base_mrf;
781d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->mlen = mlen;
782d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->header_present = true;
783d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
784d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (simd16) {
785d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (int i = 0; i < 4; i++) {
786d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 emit(BRW_OPCODE_MOV, orig_dst, dst);
787d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 orig_dst.reg_offset++;
788d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 dst.reg_offset += 2;
789d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
790d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
791d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
792d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   return inst;
793d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
794d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
795d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/* gen5's sampler has slots for u, v, r, array index, then optional
796d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * parameters like shadow comparitor or LOD bias.  If optional
797d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * parameters aren't present, those base slots are optional and don't
798d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * need to be included in the message.
799d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt *
800d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * We don't fill in the unnecessary slots regardless, which may look
801d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * surprising in the disassembly.
802d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */
803d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_inst *
804d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate,
805d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt			      int sampler)
806d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
807d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int mlen = 0;
808d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int base_mrf = 2;
809d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int reg_width = c->dispatch_width / 8;
810d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   bool header_present = false;
811ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke   const int vector_elements =
812ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke      ir->coordinate ? ir->coordinate->type->vector_elements : 0;
813d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
814d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->offset) {
815d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* The offsets set up by the ir_texture visitor are in the
816d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m1 header, so we can't go headerless.
817d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       */
818d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      header_present = true;
819d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen++;
820d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      base_mrf--;
821d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
822d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
823ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke   for (int i = 0; i < vector_elements; i++) {
82407e621c52329cd17b97051a26493626228d043b9Eric Anholt      emit(BRW_OPCODE_MOV,
82507e621c52329cd17b97051a26493626228d043b9Eric Anholt	   fs_reg(MRF, base_mrf + mlen + i * reg_width, coordinate.type),
82607e621c52329cd17b97051a26493626228d043b9Eric Anholt	   coordinate);
827d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      coordinate.reg_offset++;
828d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
829ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke   mlen += vector_elements * reg_width;
830d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
8316430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke   if (ir->shadow_comparitor && ir->op != ir_txd) {
832d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen = MAX2(mlen, header_present + 4 * reg_width);
833d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
834d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->shadow_comparitor->accept(this);
835d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
836d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen += reg_width;
837d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
838d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
839d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *inst = NULL;
840d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   switch (ir->op) {
841d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_tex:
842febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke      inst = emit(SHADER_OPCODE_TEX, dst);
843d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
844d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_txb:
845d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->lod_info.bias->accept(this);
846d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen = MAX2(mlen, header_present + 4 * reg_width);
847d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
848d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen += reg_width;
849d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
850d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(FS_OPCODE_TXB, dst);
851d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
852d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
853d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_txl:
854d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->lod_info.lod->accept(this);
855d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen = MAX2(mlen, header_present + 4 * reg_width);
856d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
857d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen += reg_width;
858d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
859febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke      inst = emit(SHADER_OPCODE_TXL, dst);
860d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
8612f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke   case ir_txd: {
8622f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke      ir->lod_info.grad.dPdx->accept(this);
8632f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke      fs_reg dPdx = this->result;
8642f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke
8652f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke      ir->lod_info.grad.dPdy->accept(this);
8662f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke      fs_reg dPdy = this->result;
8672f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke
8682f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke      mlen = MAX2(mlen, header_present + 4 * reg_width); /* skip over 'ai' */
8692f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke
8702f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke      /**
8712f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke       *  P   =  u,    v,    r
8722f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke       * dPdx = dudx, dvdx, drdx
8732f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke       * dPdy = dudy, dvdy, drdy
8742f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke       *
8752f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke       * Load up these values:
8762f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke       * - dudx   dudy   dvdx   dvdy   drdx   drdy
8772f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke       * - dPdx.x dPdy.x dPdx.y dPdy.y dPdx.z dPdy.z
8782f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke       */
8792f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke      for (int i = 0; i < ir->lod_info.grad.dPdx->type->vector_elements; i++) {
8802f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdx);
8812f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke	 dPdx.reg_offset++;
8822f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke	 mlen += reg_width;
8832f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke
8842f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdy);
8852f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke	 dPdy.reg_offset++;
8862f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke	 mlen += reg_width;
8872f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke      }
8882f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke
889febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke      inst = emit(SHADER_OPCODE_TXD, dst);
8902f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke      break;
8912f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke   }
8921e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke   case ir_txs:
893ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke      ir->lod_info.lod->accept(this);
894ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), this->result);
895ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke      mlen += reg_width;
896febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke      inst = emit(SHADER_OPCODE_TXS, dst);
897ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke      break;
898ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke   case ir_txf:
89930be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke      mlen = header_present + 4 * reg_width;
90030be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke
90130be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke      ir->lod_info.lod->accept(this);
90230be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke      emit(BRW_OPCODE_MOV,
90330be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke	   fs_reg(MRF, base_mrf + mlen - reg_width, BRW_REGISTER_TYPE_UD),
90430be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke	   this->result);
905febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke      inst = emit(SHADER_OPCODE_TXF, dst);
906d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
907d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
908d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->base_mrf = base_mrf;
909d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->mlen = mlen;
910d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->header_present = header_present;
911d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
912d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (mlen > 11) {
913d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fail("Message length >11 disallowed by hardware\n");
914d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
915d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
916d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   return inst;
917d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
918d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
919d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_inst *
920d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
921d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt			      int sampler)
922d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
923d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int mlen = 0;
924d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int base_mrf = 2;
925d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int reg_width = c->dispatch_width / 8;
926d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   bool header_present = false;
927d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
928d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->offset) {
929d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* The offsets set up by the ir_texture visitor are in the
930d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m1 header, so we can't go headerless.
931d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       */
932d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      header_present = true;
933d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen++;
934d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      base_mrf--;
935d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
936d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
9376430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke   if (ir->shadow_comparitor && ir->op != ir_txd) {
938d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->shadow_comparitor->accept(this);
939d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
940d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen += reg_width;
941d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
942d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
943d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Set up the LOD info */
944d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   switch (ir->op) {
945d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_tex:
946d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
947d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_txb:
948d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->lod_info.bias->accept(this);
949d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
950d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen += reg_width;
951d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
952d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_txl:
953d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->lod_info.lod->accept(this);
954d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
955d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen += reg_width;
956d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
9573fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke   case ir_txd: {
9583fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke      if (c->dispatch_width == 16)
9593fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 fail("Gen7 does not support sample_d/sample_d_c in SIMD16 mode.");
9603fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke
9613fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke      ir->lod_info.grad.dPdx->accept(this);
9623fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke      fs_reg dPdx = this->result;
9633fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke
9643fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke      ir->lod_info.grad.dPdy->accept(this);
9653fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke      fs_reg dPdy = this->result;
9663fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke
9673fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke      /* Load dPdx and the coordinate together:
9683fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke       * [hdr], [ref], x, dPdx.x, dPdy.x, y, dPdx.y, dPdy.y, z, dPdx.z, dPdy.z
9693fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke       */
9703fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke      for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
97107e621c52329cd17b97051a26493626228d043b9Eric Anholt	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), coordinate);
9723fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 coordinate.reg_offset++;
9733fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 mlen += reg_width;
9743fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke
9753fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdx);
9763fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 dPdx.reg_offset++;
9773fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 mlen += reg_width;
9783fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke
9793fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdy);
9803fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 dPdy.reg_offset++;
9813fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 mlen += reg_width;
9823fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke      }
9833fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke      break;
9843fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke   }
9851e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke   case ir_txs:
986ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke      ir->lod_info.lod->accept(this);
987ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), this->result);
988ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke      mlen += reg_width;
989ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke      break;
990ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke   case ir_txf:
9910edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke      /* Unfortunately, the parameters for LD are intermixed: u, lod, v, r. */
992c310c35a754be835c9ceafe578c4974a667b9a77Eric Anholt      emit(BRW_OPCODE_MOV,
993c310c35a754be835c9ceafe578c4974a667b9a77Eric Anholt	   fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_D), coordinate);
9940edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke      coordinate.reg_offset++;
9950edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke      mlen += reg_width;
9960edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke
9970edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke      ir->lod_info.lod->accept(this);
9980edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_D), this->result);
9990edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke      mlen += reg_width;
10000edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke
10010edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke      for (int i = 1; i < ir->coordinate->type->vector_elements; i++) {
1002c310c35a754be835c9ceafe578c4974a667b9a77Eric Anholt	 emit(BRW_OPCODE_MOV,
1003c310c35a754be835c9ceafe578c4974a667b9a77Eric Anholt	      fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_D), coordinate);
10040edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke	 coordinate.reg_offset++;
10050edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke	 mlen += reg_width;
10060edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke      }
1007d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
1008d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1009d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
10100edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke   /* Set up the coordinate (except for cases where it was done above) */
10110edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke   if (ir->op != ir_txd && ir->op != ir_txs && ir->op != ir_txf) {
10123fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke      for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
101307e621c52329cd17b97051a26493626228d043b9Eric Anholt	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), coordinate);
10143fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 coordinate.reg_offset++;
10153fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 mlen += reg_width;
10163fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke      }
1017d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1018d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1019d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Generate the SEND */
1020d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *inst = NULL;
1021d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   switch (ir->op) {
1022febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke   case ir_tex: inst = emit(SHADER_OPCODE_TEX, dst); break;
1023d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_txb: inst = emit(FS_OPCODE_TXB, dst); break;
1024febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke   case ir_txl: inst = emit(SHADER_OPCODE_TXL, dst); break;
1025febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke   case ir_txd: inst = emit(SHADER_OPCODE_TXD, dst); break;
1026febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke   case ir_txf: inst = emit(SHADER_OPCODE_TXF, dst); break;
1027febad1779ae5cb5c85d66c2635baea62da52d2faKenneth Graunke   case ir_txs: inst = emit(SHADER_OPCODE_TXS, dst); break;
1028d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1029d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->base_mrf = base_mrf;
1030d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->mlen = mlen;
1031d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->header_present = header_present;
1032d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1033d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (mlen > 11) {
1034d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fail("Message length >11 disallowed by hardware\n");
1035d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1036d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1037d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   return inst;
1038d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1039d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1040d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1041d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_texture *ir)
1042d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1043d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *inst = NULL;
1044d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1045f1622cfe9c0f37a9b452be1297f187cba8c46e6aKenneth Graunke   int sampler = _mesa_get_sampler_uniform_value(ir->sampler, prog, &fp->Base);
1046f1622cfe9c0f37a9b452be1297f187cba8c46e6aKenneth Graunke   sampler = fp->Base.SamplerUnits[sampler];
1047f1622cfe9c0f37a9b452be1297f187cba8c46e6aKenneth Graunke
10486430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke   /* Our hardware doesn't have a sample_d_c message, so shadow compares
10496430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke    * for textureGrad/TXD need to be emulated with instructions.
10506430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke    */
10516430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke   bool hw_compare_supported = ir->op != ir_txd;
10526430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke   if (ir->shadow_comparitor && !hw_compare_supported) {
10531b05fc7cdd0e5d77b50bc8ee2f2c851da5884d72Kenneth Graunke      assert(c->key.tex.compare_funcs[sampler] != GL_NONE);
10546430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke      /* No need to even sample for GL_ALWAYS or GL_NEVER...bail early */
10551b05fc7cdd0e5d77b50bc8ee2f2c851da5884d72Kenneth Graunke      if (c->key.tex.compare_funcs[sampler] == GL_ALWAYS)
10566430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 return swizzle_result(ir, fs_reg(1.0f), sampler);
10571b05fc7cdd0e5d77b50bc8ee2f2c851da5884d72Kenneth Graunke      else if (c->key.tex.compare_funcs[sampler] == GL_NEVER)
10586430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 return swizzle_result(ir, fs_reg(0.0f), sampler);
10596430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke   }
10606430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke
1061ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke   if (ir->coordinate)
1062ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke      ir->coordinate->accept(this);
1063d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg coordinate = this->result;
1064d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1065d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->offset != NULL) {
1066475d70d6ef5feb94efab3923e5607e625f2aee67Kenneth Graunke      uint32_t offset_bits = brw_texture_offset(ir->offset->as_constant());
1067d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1068d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* Explicitly set up the message header by copying g0 to msg reg m1. */
1069d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, fs_reg(MRF, 1, BRW_REGISTER_TYPE_UD),
1070512431b3575eb5f2c27d8795c5e2191047ebb5edKenneth Graunke	   fs_reg(retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UD)));
1071d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1072d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* Then set the offset bits in DWord 2 of the message header. */
1073d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV,
1074d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	   fs_reg(retype(brw_vec1_reg(BRW_MESSAGE_REGISTER_FILE, 1, 2),
1075d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt			 BRW_REGISTER_TYPE_UD)),
1076d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	   fs_reg(brw_imm_uw(offset_bits)));
1077d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1078d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1079d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Should be lowered by do_lower_texture_projection */
1080d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   assert(!ir->projector);
1081d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1082d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* The 965 requires the EU to do the normalization of GL rectangle
1083d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * texture coordinates.  We use the program parameter state
1084d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * tracking to get the scaling factor.
1085d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    */
10869d4b98eb9eadecc17cd1cda0074b420a39e74647Eric Anholt   if (intel->gen < 6 &&
10879d4b98eb9eadecc17cd1cda0074b420a39e74647Eric Anholt       ir->sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_RECT) {
1088d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      struct gl_program_parameter_list *params = c->fp->program.Base.Parameters;
1089d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      int tokens[STATE_LENGTH] = {
1090d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 STATE_INTERNAL,
1091d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 STATE_TEXRECT_SCALE,
1092d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 sampler,
1093d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 0,
1094d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 0
1095d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      };
1096d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1097d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (c->dispatch_width == 16) {
1098d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 fail("rectangle scale uniform setup not supported on 16-wide\n");
1099d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 this->result = fs_reg(this, ir->type);
1100d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 return;
1101d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1102d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1103d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      c->prog_data.param_convert[c->prog_data.nr_params] =
1104d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 PARAM_NO_CONVERT;
1105d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      c->prog_data.param_convert[c->prog_data.nr_params + 1] =
1106d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 PARAM_NO_CONVERT;
1107d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1108d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_reg scale_x = fs_reg(UNIFORM, c->prog_data.nr_params);
1109d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_reg scale_y = fs_reg(UNIFORM, c->prog_data.nr_params + 1);
1110d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      GLuint index = _mesa_add_state_reference(params,
1111d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt					       (gl_state_index *)tokens);
1112d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1113d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->param_index[c->prog_data.nr_params] = index;
1114d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->param_offset[c->prog_data.nr_params] = 0;
1115d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      c->prog_data.nr_params++;
1116d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->param_index[c->prog_data.nr_params] = index;
1117d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->param_offset[c->prog_data.nr_params] = 1;
1118d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      c->prog_data.nr_params++;
1119d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1120d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_reg dst = fs_reg(this, ir->coordinate->type);
1121d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_reg src = coordinate;
1122d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      coordinate = dst;
1123d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1124d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MUL, dst, src, scale_x);
1125d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      dst.reg_offset++;
1126d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      src.reg_offset++;
1127d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MUL, dst, src, scale_y);
1128d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
112907e621c52329cd17b97051a26493626228d043b9Eric Anholt
113007e621c52329cd17b97051a26493626228d043b9Eric Anholt   if (ir->coordinate) {
113107e621c52329cd17b97051a26493626228d043b9Eric Anholt      for (int i = 0; i < MIN2(ir->coordinate->type->vector_elements, 3); i++) {
113207e621c52329cd17b97051a26493626228d043b9Eric Anholt	 if (c->key.tex.gl_clamp_mask[i] & (1 << sampler)) {
113307e621c52329cd17b97051a26493626228d043b9Eric Anholt	    fs_reg chan = coordinate;
113407e621c52329cd17b97051a26493626228d043b9Eric Anholt	    chan.reg_offset += i;
113507e621c52329cd17b97051a26493626228d043b9Eric Anholt
113607e621c52329cd17b97051a26493626228d043b9Eric Anholt	    fs_inst *inst = emit(BRW_OPCODE_MOV, chan, chan);
113707e621c52329cd17b97051a26493626228d043b9Eric Anholt	    inst->saturate = true;
113807e621c52329cd17b97051a26493626228d043b9Eric Anholt	 }
113907e621c52329cd17b97051a26493626228d043b9Eric Anholt      }
114007e621c52329cd17b97051a26493626228d043b9Eric Anholt   }
1141d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1142d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Writemasking doesn't eliminate channels on SIMD8 texture
1143d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * samples, so don't worry about them.
1144d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    */
1145b6bdcf2a908889532ef6d5eb643791176dffcb9dKenneth Graunke   fs_reg dst = fs_reg(this, glsl_type::get_instance(ir->type->base_type, 4, 1));
1146d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1147d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (intel->gen >= 7) {
1148d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit_texture_gen7(ir, dst, coordinate, sampler);
1149d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else if (intel->gen >= 5) {
1150d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit_texture_gen5(ir, dst, coordinate, sampler);
1151d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else {
1152d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit_texture_gen4(ir, dst, coordinate, sampler);
1153d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1154d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1155d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* If there's an offset, we already set up m1.  To avoid the implied move,
1156d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * use the null register.  Otherwise, we want an implied move from g0.
1157d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    */
1158d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->offset != NULL || !inst->header_present)
1159d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->src[0] = reg_undef;
1160d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   else
1161d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->src[0] = fs_reg(retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW));
1162d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1163d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->sampler = sampler;
1164d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
11656430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke   if (ir->shadow_comparitor) {
11666430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke      if (hw_compare_supported) {
11676430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 inst->shadow_compare = true;
11686430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke      } else {
11696430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 ir->shadow_comparitor->accept(this);
11706430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 fs_reg ref = this->result;
11716430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke
11726430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 fs_reg value = dst;
11736430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 dst = fs_reg(this, glsl_type::vec4_type);
11746430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke
11756430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 /* FINISHME: This needs to be done pre-filtering. */
11766430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke
11776430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 uint32_t conditional = 0;
11781b05fc7cdd0e5d77b50bc8ee2f2c851da5884d72Kenneth Graunke	 switch (c->key.tex.compare_funcs[sampler]) {
11796430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 /* GL_ALWAYS and GL_NEVER were handled at the top of the function */
11806430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 case GL_LESS:     conditional = BRW_CONDITIONAL_L;   break;
11816430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 case GL_GREATER:  conditional = BRW_CONDITIONAL_G;   break;
11826430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 case GL_LEQUAL:   conditional = BRW_CONDITIONAL_LE;  break;
11836430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 case GL_GEQUAL:   conditional = BRW_CONDITIONAL_GE;  break;
11846430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 case GL_EQUAL:    conditional = BRW_CONDITIONAL_EQ;  break;
11856430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 case GL_NOTEQUAL: conditional = BRW_CONDITIONAL_NEQ; break;
11866430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 default: assert(!"Should not get here: bad shadow compare function");
11876430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 }
11886430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke
11896430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 /* Use conditional moves to load 0 or 1 as the result */
11906430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 this->current_annotation = "manual shadow comparison";
11916430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 for (int i = 0; i < 4; i++) {
11926430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	    inst = emit(BRW_OPCODE_MOV, dst, fs_reg(0.0f));
11936430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke
11946430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	    inst = emit(BRW_OPCODE_CMP, reg_null_f, ref, value);
11956430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	    inst->conditional_mod = conditional;
11966430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke
11976430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	    inst = emit(BRW_OPCODE_MOV, dst, fs_reg(1.0f));
11986430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	    inst->predicated = true;
11996430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke
12006430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	    dst.reg_offset++;
12016430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	    value.reg_offset++;
12026430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 }
12036430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 dst.reg_offset = 0;
12046430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke      }
12056430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke   }
1206d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
120701fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke   swizzle_result(ir, dst, sampler);
120801fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke}
120901fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke
121001fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke/**
121101fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke * Swizzle the result of a texture result.  This is necessary for
121201fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke * EXT_texture_swizzle as well as DEPTH_TEXTURE_MODE for shadow comparisons.
121301fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke */
121401fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunkevoid
121501fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunkefs_visitor::swizzle_result(ir_texture *ir, fs_reg orig_val, int sampler)
121601fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke{
121701fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke   this->result = orig_val;
121801fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke
1219c592ebc581e5ca0122660b3d76ec924b96581216Kenneth Graunke   if (ir->op == ir_txs)
1220c592ebc581e5ca0122660b3d76ec924b96581216Kenneth Graunke      return;
1221c592ebc581e5ca0122660b3d76ec924b96581216Kenneth Graunke
1222d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->type == glsl_type::float_type) {
1223d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* Ignore DEPTH_TEXTURE_MODE swizzling. */
1224d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(ir->sampler->type->sampler_shadow);
12251b05fc7cdd0e5d77b50bc8ee2f2c851da5884d72Kenneth Graunke   } else if (c->key.tex.swizzles[sampler] != SWIZZLE_NOOP) {
122601fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke      fs_reg swizzled_result = fs_reg(this, glsl_type::vec4_type);
1227d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1228d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (int i = 0; i < 4; i++) {
12291b05fc7cdd0e5d77b50bc8ee2f2c851da5884d72Kenneth Graunke	 int swiz = GET_SWZ(c->key.tex.swizzles[sampler], i);
123001fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke	 fs_reg l = swizzled_result;
1231d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 l.reg_offset += i;
1232d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1233d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 if (swiz == SWIZZLE_ZERO) {
1234d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    emit(BRW_OPCODE_MOV, l, fs_reg(0.0f));
1235d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 } else if (swiz == SWIZZLE_ONE) {
1236d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    emit(BRW_OPCODE_MOV, l, fs_reg(1.0f));
1237d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 } else {
123801fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke	    fs_reg r = orig_val;
12391b05fc7cdd0e5d77b50bc8ee2f2c851da5884d72Kenneth Graunke	    r.reg_offset += GET_SWZ(c->key.tex.swizzles[sampler], i);
1240d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    emit(BRW_OPCODE_MOV, l, r);
1241d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 }
1242d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
124301fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke      this->result = swizzled_result;
1244d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1245d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1246d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1247d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1248d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_swizzle *ir)
1249d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1250d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir->val->accept(this);
1251d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg val = this->result;
1252d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1253d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->type->vector_elements == 1) {
1254d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->result.reg_offset += ir->mask.x;
1255d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      return;
1256d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1257d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1258d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg result = fs_reg(this, ir->type);
1259d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->result = result;
1260d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1261d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   for (unsigned int i = 0; i < ir->type->vector_elements; i++) {
1262d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_reg channel = val;
1263d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      int swiz = 0;
1264d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1265d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      switch (i) {
1266d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case 0:
1267d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 swiz = ir->mask.x;
1268d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1269d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case 1:
1270d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 swiz = ir->mask.y;
1271d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1272d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case 2:
1273d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 swiz = ir->mask.z;
1274d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1275d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case 3:
1276d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 swiz = ir->mask.w;
1277d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1278d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1279d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1280d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      channel.reg_offset += swiz;
1281d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, result, channel);
1282d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      result.reg_offset++;
1283d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1284d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1285d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1286d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1287d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_discard *ir)
1288d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1289d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   assert(ir->condition == NULL); /* FINISHME */
1290d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1291d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(FS_OPCODE_DISCARD);
1292d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   kill_emitted = true;
1293d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1294d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1295d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1296d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_constant *ir)
1297d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1298d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Set this->result to reg at the bottom of the function because some code
1299d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * paths will cause this visitor to be applied to other fields.  This will
1300d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * cause the value stored in this->result to be modified.
1301d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    *
1302d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * Make reg constant so that it doesn't get accidentally modified along the
1303d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * way.  Yes, I actually had this problem. :(
1304d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    */
1305d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   const fs_reg reg(this, ir->type);
1306d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg dst_reg = reg;
1307d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1308d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->type->is_array()) {
1309d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      const unsigned size = type_size(ir->type->fields.array);
1310d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1311d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (unsigned i = 0; i < ir->type->length; i++) {
1312d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 ir->array_elements[i]->accept(this);
1313d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 fs_reg src_reg = this->result;
1314d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1315d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 dst_reg.type = src_reg.type;
1316d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 for (unsigned j = 0; j < size; j++) {
1317d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    emit(BRW_OPCODE_MOV, dst_reg, src_reg);
1318d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    src_reg.reg_offset++;
1319d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    dst_reg.reg_offset++;
1320d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 }
1321d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1322d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else if (ir->type->is_record()) {
1323d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      foreach_list(node, &ir->components) {
1324d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 ir_instruction *const field = (ir_instruction *) node;
1325d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 const unsigned size = type_size(field->type);
1326d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1327d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 field->accept(this);
1328d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 fs_reg src_reg = this->result;
1329d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1330d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 dst_reg.type = src_reg.type;
1331d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 for (unsigned j = 0; j < size; j++) {
1332d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    emit(BRW_OPCODE_MOV, dst_reg, src_reg);
1333d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    src_reg.reg_offset++;
1334d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    dst_reg.reg_offset++;
1335d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 }
1336d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1337d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else {
1338d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      const unsigned size = type_size(ir->type);
1339d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1340d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (unsigned i = 0; i < size; i++) {
1341d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 switch (ir->type->base_type) {
1342d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 case GLSL_TYPE_FLOAT:
1343d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    emit(BRW_OPCODE_MOV, dst_reg, fs_reg(ir->value.f[i]));
1344d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    break;
1345d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 case GLSL_TYPE_UINT:
1346d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    emit(BRW_OPCODE_MOV, dst_reg, fs_reg(ir->value.u[i]));
1347d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    break;
1348d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 case GLSL_TYPE_INT:
1349d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    emit(BRW_OPCODE_MOV, dst_reg, fs_reg(ir->value.i[i]));
1350d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    break;
1351d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 case GLSL_TYPE_BOOL:
1352d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    emit(BRW_OPCODE_MOV, dst_reg, fs_reg((int)ir->value.b[i]));
1353d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    break;
1354d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 default:
1355d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    assert(!"Non-float/uint/int/bool constant");
1356d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 }
1357d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 dst_reg.reg_offset++;
1358d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1359d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1360d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1361d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->result = reg;
1362d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1363d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1364d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1365d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_bool_to_cond_code(ir_rvalue *ir)
1366d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1367d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir_expression *expr = ir->as_expression();
1368d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1369d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (expr) {
1370d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_reg op[2];
1371d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_inst *inst;
1372d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1373d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(expr->get_num_operands() <= 2);
1374d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (unsigned int i = 0; i < expr->get_num_operands(); i++) {
1375d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 assert(expr->operands[i]->type->is_scalar());
1376d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1377d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 expr->operands[i]->accept(this);
1378d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 op[i] = this->result;
137973b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt
138073b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt	 resolve_ud_negate(&op[i]);
1381d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1382d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1383d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      switch (expr->operation) {
1384d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_unop_logic_not:
1385d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_AND, reg_null_d, op[0], fs_reg(1));
1386d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_Z;
1387d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1388d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1389d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_logic_xor:
1390d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_XOR, reg_null_d, op[0], op[1]);
1391d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_NZ;
1392d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1393d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1394d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_logic_or:
1395d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_OR, reg_null_d, op[0], op[1]);
1396d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_NZ;
1397d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1398d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1399d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_logic_and:
1400d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_AND, reg_null_d, op[0], op[1]);
1401d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_NZ;
1402d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1403d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1404d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_unop_f2b:
1405d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 if (intel->gen >= 6) {
1406d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    inst = emit(BRW_OPCODE_CMP, reg_null_d, op[0], fs_reg(0.0f));
1407d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 } else {
1408d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    inst = emit(BRW_OPCODE_MOV, reg_null_f, op[0]);
1409d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 }
1410d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_NZ;
1411d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1412d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1413d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_unop_i2b:
1414d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 if (intel->gen >= 6) {
1415d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    inst = emit(BRW_OPCODE_CMP, reg_null_d, op[0], fs_reg(0));
1416d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 } else {
1417d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    inst = emit(BRW_OPCODE_MOV, reg_null_d, op[0]);
1418d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 }
1419d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_NZ;
1420d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1421d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1422d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_greater:
1423d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_gequal:
1424d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_less:
1425d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_lequal:
1426d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_equal:
1427d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_all_equal:
1428d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_nequal:
1429d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_any_nequal:
1430d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_CMP, reg_null_cmp, op[0], op[1]);
1431d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod =
1432d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    brw_conditional_for_comparison(expr->operation);
1433d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1434d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1435d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      default:
1436d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 assert(!"not reached");
1437d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 fail("bad cond code\n");
1438d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1439d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1440d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      return;
1441d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1442d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1443d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir->accept(this);
1444d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1445d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (intel->gen >= 6) {
1446d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_inst *inst = emit(BRW_OPCODE_AND, reg_null_d, this->result, fs_reg(1));
1447d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->conditional_mod = BRW_CONDITIONAL_NZ;
1448d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else {
1449d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_inst *inst = emit(BRW_OPCODE_MOV, reg_null_d, this->result);
1450d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->conditional_mod = BRW_CONDITIONAL_NZ;
1451d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1452d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1453d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1454d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/**
1455d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * Emit a gen6 IF statement with the comparison folded into the IF
1456d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * instruction.
1457d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */
1458d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1459d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_if_gen6(ir_if *ir)
1460d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1461d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir_expression *expr = ir->condition->as_expression();
1462d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1463d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (expr) {
1464d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_reg op[2];
1465d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_inst *inst;
1466d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_reg temp;
1467d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1468d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(expr->get_num_operands() <= 2);
1469d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (unsigned int i = 0; i < expr->get_num_operands(); i++) {
1470d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 assert(expr->operands[i]->type->is_scalar());
1471d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1472d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 expr->operands[i]->accept(this);
1473d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 op[i] = this->result;
1474d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1475d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1476d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      switch (expr->operation) {
1477d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_unop_logic_not:
1478d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_IF, temp, op[0], fs_reg(0));
1479d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_Z;
1480d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 return;
1481d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1482d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_logic_xor:
1483d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_IF, reg_null_d, op[0], op[1]);
1484d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_NZ;
1485d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 return;
1486d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1487d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_logic_or:
1488d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 temp = fs_reg(this, glsl_type::bool_type);
1489d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 emit(BRW_OPCODE_OR, temp, op[0], op[1]);
1490d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_IF, reg_null_d, temp, fs_reg(0));
1491d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_NZ;
1492d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 return;
1493d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1494d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_logic_and:
1495d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 temp = fs_reg(this, glsl_type::bool_type);
1496d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 emit(BRW_OPCODE_AND, temp, op[0], op[1]);
1497d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_IF, reg_null_d, temp, fs_reg(0));
1498d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_NZ;
1499d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 return;
1500d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1501d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_unop_f2b:
1502d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_IF, reg_null_f, op[0], fs_reg(0));
1503d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_NZ;
1504d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 return;
1505d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1506d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_unop_i2b:
1507d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_IF, reg_null_d, op[0], fs_reg(0));
1508d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_NZ;
1509d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 return;
1510d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1511d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_greater:
1512d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_gequal:
1513d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_less:
1514d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_lequal:
1515d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_equal:
1516d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_all_equal:
1517d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_nequal:
1518d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_any_nequal:
1519d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_IF, reg_null_d, op[0], op[1]);
1520d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod =
1521d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    brw_conditional_for_comparison(expr->operation);
1522d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 return;
1523d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      default:
1524d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 assert(!"not reached");
1525d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_IF, reg_null_d, op[0], fs_reg(0));
1526d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_NZ;
1527d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 fail("bad condition\n");
1528d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 return;
1529d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1530d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      return;
1531d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1532d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1533d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir->condition->accept(this);
1534d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1535d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *inst = emit(BRW_OPCODE_IF, reg_null_d, this->result, fs_reg(0));
1536d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->conditional_mod = BRW_CONDITIONAL_NZ;
1537d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1538d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1539d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1540d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_if *ir)
1541d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1542d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *inst;
1543d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
154479cba4c2b17456e2b25ac555c45e1c106b4e3f6bKenneth Graunke   if (intel->gen < 6 && c->dispatch_width == 16) {
1545d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fail("Can't support (non-uniform) control flow on 16-wide\n");
1546d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1547d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1548d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Don't point the annotation at the if statement, because then it plus
1549d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * the then and else blocks get printed.
1550d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    */
1551d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->base_ir = ir->condition;
1552d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1553d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (intel->gen == 6) {
1554d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit_if_gen6(ir);
1555d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else {
1556d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit_bool_to_cond_code(ir->condition);
1557d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1558d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_IF);
1559d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->predicated = true;
1560d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1561d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
156244ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt   foreach_list(node, &ir->then_instructions) {
156344ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt      ir_instruction *ir = (ir_instruction *)node;
1564d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->base_ir = ir;
1565d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke
1566d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->accept(this);
1567d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1568d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1569d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (!ir->else_instructions.is_empty()) {
1570d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_ELSE);
1571d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
157244ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt      foreach_list(node, &ir->else_instructions) {
157344ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt	 ir_instruction *ir = (ir_instruction *)node;
1574d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 this->base_ir = ir;
1575d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke
1576d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 ir->accept(this);
1577d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1578d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1579d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1580d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_ENDIF);
1581d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1582d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1583d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1584d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_loop *ir)
1585d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1586d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg counter = reg_undef;
1587d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1588d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (c->dispatch_width == 16) {
1589d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fail("Can't support (non-uniform) control flow on 16-wide\n");
1590d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1591d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1592d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->counter) {
1593d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->base_ir = ir->counter;
1594d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->counter->accept(this);
1595d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      counter = *(variable_storage(ir->counter));
1596d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1597d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (ir->from) {
1598d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 this->base_ir = ir->from;
1599d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 ir->from->accept(this);
1600d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1601d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke	 emit(BRW_OPCODE_MOV, counter, this->result);
1602d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1603d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1604d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1605d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_DO);
1606d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1607d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->to) {
1608d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->base_ir = ir->to;
1609d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->to->accept(this);
1610d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1611d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_inst *inst = emit(BRW_OPCODE_CMP, reg_null_cmp, counter, this->result);
1612d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->conditional_mod = brw_conditional_for_comparison(ir->cmp);
1613d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1614d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_BREAK);
1615d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->predicated = true;
1616d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1617d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
161844ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt   foreach_list(node, &ir->body_instructions) {
161944ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt      ir_instruction *ir = (ir_instruction *)node;
1620d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1621d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->base_ir = ir;
1622d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->accept(this);
1623d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1624d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1625d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->increment) {
1626d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->base_ir = ir->increment;
1627d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->increment->accept(this);
1628d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_ADD, counter, counter, this->result);
1629d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1630d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1631d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_WHILE);
1632d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1633d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1634d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1635d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_loop_jump *ir)
1636d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1637d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   switch (ir->mode) {
1638d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_loop_jump::jump_break:
1639d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_BREAK);
1640d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
1641d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_loop_jump::jump_continue:
1642d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_CONTINUE);
1643d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
1644d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1645d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1646d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1647d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1648d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_call *ir)
1649d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1650d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   assert(!"FINISHME");
1651d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1652d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1653d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1654d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_return *ir)
1655d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1656d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   assert(!"FINISHME");
1657d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1658d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1659d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1660d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_function *ir)
1661d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1662d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Ignore function bodies other than main() -- we shouldn't see calls to
1663d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * them since they should all be inlined before we get to ir_to_mesa.
1664d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    */
1665d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (strcmp(ir->name, "main") == 0) {
1666d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      const ir_function_signature *sig;
1667d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      exec_list empty;
1668d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1669d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      sig = ir->matching_signature(&empty);
1670d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1671d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(sig);
1672d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
167344ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt      foreach_list(node, &sig->body) {
167444ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt	 ir_instruction *ir = (ir_instruction *)node;
1675d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 this->base_ir = ir;
1676d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke
1677d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 ir->accept(this);
1678d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1679d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1680d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1681d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1682d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1683d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_function_signature *ir)
1684d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1685d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   assert(!"not reached");
1686d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   (void)ir;
1687d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1688d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1689d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_inst *
1690d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit(fs_inst inst)
1691d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1692d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *list_inst = new(mem_ctx) fs_inst;
1693d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   *list_inst = inst;
1694d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1695d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (force_uncompressed_stack > 0)
1696d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      list_inst->force_uncompressed = true;
1697d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   else if (force_sechalf_stack > 0)
1698d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      list_inst->force_sechalf = true;
1699d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1700d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   list_inst->annotation = this->current_annotation;
1701d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   list_inst->ir = this->base_ir;
1702d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1703d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->instructions.push_tail(list_inst);
1704d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1705d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   return list_inst;
1706d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1707d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1708d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/** Emits a dummy fragment shader consisting of magenta for bringup purposes. */
1709d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1710d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_dummy_fs()
1711d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1712d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Everyone's favorite color. */
1713d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_MOV, fs_reg(MRF, 2), fs_reg(1.0f));
1714d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_MOV, fs_reg(MRF, 3), fs_reg(0.0f));
1715d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_MOV, fs_reg(MRF, 4), fs_reg(1.0f));
1716d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_MOV, fs_reg(MRF, 5), fs_reg(0.0f));
1717d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1718d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *write;
1719d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   write = emit(FS_OPCODE_FB_WRITE, fs_reg(0), fs_reg(0));
17206750226e6d915742ebf96bae2cfcdd287b85db35Ben Widawsky   write->base_mrf = 2;
1721d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1722d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1723d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/* The register location here is relative to the start of the URB
1724d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * data.  It will get adjusted to be a real location before
1725d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * generate_code() time.
1726d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */
1727d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtstruct brw_reg
1728d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::interp_reg(int location, int channel)
1729d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1730d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int regnr = urb_setup[location] * 2 + channel / 2;
1731d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int stride = (channel & 1) * 4;
1732d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1733d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   assert(urb_setup[location] != -1);
1734d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1735d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   return brw_vec1_grf(regnr, stride);
1736d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1737d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1738d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/** Emits the interpolation for the varying inputs. */
1739d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1740d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_interpolation_setup_gen4()
1741d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1742d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->current_annotation = "compute pixel centers";
1743d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->pixel_x = fs_reg(this, glsl_type::uint_type);
1744d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->pixel_y = fs_reg(this, glsl_type::uint_type);
1745d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->pixel_x.type = BRW_REGISTER_TYPE_UW;
1746d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->pixel_y.type = BRW_REGISTER_TYPE_UW;
1747d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1748d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(FS_OPCODE_PIXEL_X, this->pixel_x);
1749d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(FS_OPCODE_PIXEL_Y, this->pixel_y);
1750d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1751d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->current_annotation = "compute pixel deltas from v0";
1752d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (brw->has_pln) {
1753e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry      this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC] =
1754e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry         fs_reg(this, glsl_type::vec2_type);
1755e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry      this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC] =
1756e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry         this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC];
1757e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry      this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC].reg_offset++;
1758d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else {
1759e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry      this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC] =
1760e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry         fs_reg(this, glsl_type::float_type);
1761e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry      this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC] =
1762e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry         fs_reg(this, glsl_type::float_type);
1763d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1764e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry   emit(BRW_OPCODE_ADD, this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC],
1765d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	this->pixel_x, fs_reg(negate(brw_vec1_grf(1, 0))));
1766e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry   emit(BRW_OPCODE_ADD, this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC],
1767d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	this->pixel_y, fs_reg(negate(brw_vec1_grf(1, 1))));
1768d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1769d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->current_annotation = "compute pos.w and 1/pos.w";
1770d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Compute wpos.w.  It's always in our setup, since it's needed to
1771d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * interpolate the other attributes.
1772d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    */
1773d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->wpos_w = fs_reg(this, glsl_type::float_type);
1774e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry   emit(FS_OPCODE_LINTERP, wpos_w,
1775e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry        this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC],
1776e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry        this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC],
1777d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	interp_reg(FRAG_ATTRIB_WPOS, 3));
1778d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Compute the pixel 1/W value from wpos.w. */
1779d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->pixel_w = fs_reg(this, glsl_type::float_type);
178065b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt   emit_math(SHADER_OPCODE_RCP, this->pixel_w, wpos_w);
1781d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->current_annotation = NULL;
1782d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1783d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1784d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/** Emits the interpolation for the varying inputs. */
1785d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1786d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_interpolation_setup_gen6()
1787d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1788d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   struct brw_reg g1_uw = retype(brw_vec1_grf(1, 0), BRW_REGISTER_TYPE_UW);
1789d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1790d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* If the pixel centers end up used, the setup is the same as for gen4. */
1791d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->current_annotation = "compute pixel centers";
1792d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg int_pixel_x = fs_reg(this, glsl_type::uint_type);
1793d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg int_pixel_y = fs_reg(this, glsl_type::uint_type);
1794d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int_pixel_x.type = BRW_REGISTER_TYPE_UW;
1795d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int_pixel_y.type = BRW_REGISTER_TYPE_UW;
1796d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_ADD,
1797d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	int_pixel_x,
1798d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	fs_reg(stride(suboffset(g1_uw, 4), 2, 4, 0)),
1799d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	fs_reg(brw_imm_v(0x10101010)));
1800d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_ADD,
1801d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	int_pixel_y,
1802d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	fs_reg(stride(suboffset(g1_uw, 5), 2, 4, 0)),
1803d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	fs_reg(brw_imm_v(0x11001100)));
1804d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1805d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* As of gen6, we can no longer mix float and int sources.  We have
1806d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * to turn the integer pixel centers into floats for their actual
1807d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * use.
1808d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    */
1809d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->pixel_x = fs_reg(this, glsl_type::float_type);
1810d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->pixel_y = fs_reg(this, glsl_type::float_type);
1811d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_MOV, this->pixel_x, int_pixel_x);
1812d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_MOV, this->pixel_y, int_pixel_y);
1813d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1814d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->current_annotation = "compute pos.w";
1815d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->pixel_w = fs_reg(brw_vec8_grf(c->source_w_reg, 0));
1816d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->wpos_w = fs_reg(this, glsl_type::float_type);
181765b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt   emit_math(SHADER_OPCODE_RCP, this->wpos_w, this->pixel_w);
1818d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1819e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry   for (int i = 0; i < BRW_WM_BARYCENTRIC_INTERP_MODE_COUNT; ++i) {
1820e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry      uint8_t reg = c->barycentric_coord_reg[i];
1821e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry      this->delta_x[i] = fs_reg(brw_vec8_grf(reg, 0));
1822e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry      this->delta_y[i] = fs_reg(brw_vec8_grf(reg + 1, 0));
1823e04bdeae82797dbdcf6f544a997a4626fdfd4aeePaul Berry   }
1824d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1825d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->current_annotation = NULL;
1826d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1827d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1828d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
18296d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholtfs_visitor::emit_color_write(int target, int index, int first_color_mrf)
1830d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1831d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int reg_width = c->dispatch_width / 8;
18324fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt   fs_inst *inst;
18336d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt   fs_reg color = outputs[target];
18346d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt   fs_reg mrf;
18356d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt
18366d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt   /* If there's no color data to be written, skip it. */
18376d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt   if (color.file == BAD_FILE)
18386d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt      return;
18396d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt
18406d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt   color.reg_offset += index;
1841d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
184283df7fbe62be2798d557142a47e01af86ec9e2e2Kenneth Graunke   if (c->dispatch_width == 8 || intel->gen >= 6) {
1843d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* SIMD8 write looks like:
1844d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 0: r0
1845d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 1: r1
1846d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 2: g0
1847d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 3: g1
1848d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       *
1849d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * gen6 SIMD16 DP write looks like:
1850d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 0: r0
1851d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 1: r1
1852d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 2: g0
1853d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 3: g1
1854d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 4: b0
1855d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 5: b1
1856d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 6: a0
1857d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 7: a1
1858d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       */
18594fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt      inst = emit(BRW_OPCODE_MOV,
1860e988d816e16f9c0844424472d689486a833931c3Eric Anholt		  fs_reg(MRF, first_color_mrf + index * reg_width, color.type),
18614fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt		  color);
18624fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt      inst->saturate = c->key.clamp_fragment_color;
1863d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else {
1864d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* pre-gen6 SIMD16 single source DP write looks like:
1865d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 0: r0
1866d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 1: g0
1867d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 2: b0
1868d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 3: a0
1869d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 4: r1
1870d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 5: g1
1871d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 6: b1
1872d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 7: a1
1873d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       */
1874d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (brw->has_compr4) {
1875d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 /* By setting the high bit of the MRF register number, we
1876d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  * indicate that we want COMPR4 mode - instead of doing the
1877d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  * usual destination + 1 for the second half we get
1878d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  * destination + 4.
1879d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  */
18804fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt	 inst = emit(BRW_OPCODE_MOV,
1881e988d816e16f9c0844424472d689486a833931c3Eric Anholt		     fs_reg(MRF, BRW_MRF_COMPR4 + first_color_mrf + index,
1882e988d816e16f9c0844424472d689486a833931c3Eric Anholt			    color.type),
18834fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt		     color);
18844fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt	 inst->saturate = c->key.clamp_fragment_color;
1885d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      } else {
1886d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 push_force_uncompressed();
1887e988d816e16f9c0844424472d689486a833931c3Eric Anholt	 inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, first_color_mrf + index,
1888e988d816e16f9c0844424472d689486a833931c3Eric Anholt					    color.type),
18894fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt		     color);
18904fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt	 inst->saturate = c->key.clamp_fragment_color;
1891d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 pop_force_uncompressed();
1892d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1893d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 push_force_sechalf();
1894d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 color.sechalf = true;
1895e988d816e16f9c0844424472d689486a833931c3Eric Anholt	 inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, first_color_mrf + index + 4,
1896e988d816e16f9c0844424472d689486a833931c3Eric Anholt					    color.type),
18974fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt		     color);
18984fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt	 inst->saturate = c->key.clamp_fragment_color;
1899d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 pop_force_sechalf();
1900d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 color.sechalf = false;
1901d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1902d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1903d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1904d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1905d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1906d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_fb_writes()
1907d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1908d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->current_annotation = "FB write header";
19092e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunke   bool header_present = true;
1910eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke   int base_mrf = 2;
1911eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke   int nr = base_mrf;
1912d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int reg_width = c->dispatch_width / 8;
1913d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1914d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (intel->gen >= 6 &&
1915d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       !this->kill_emitted &&
1916d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       c->key.nr_color_regions == 1) {
1917d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      header_present = false;
1918d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1919d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1920d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (header_present) {
19216750226e6d915742ebf96bae2cfcdd287b85db35Ben Widawsky      /* m2, m3 header */
1922d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      nr += 2;
1923d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1924d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1925d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (c->aa_dest_stencil_reg) {
1926d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      push_force_uncompressed();
1927d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, fs_reg(MRF, nr++),
1928d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	   fs_reg(brw_vec8_grf(c->aa_dest_stencil_reg, 0)));
1929d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      pop_force_uncompressed();
1930d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1931d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1932d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Reserve space for color. It'll be filled in per MRT below. */
1933d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int color_mrf = nr;
1934d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   nr += 4 * reg_width;
1935d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1936d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (c->source_depth_to_render_target) {
1937d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (intel->gen == 6 && c->dispatch_width == 16) {
1938d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 /* For outputting oDepth on gen6, SIMD8 writes have to be
1939d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  * used.  This would require 8-wide moves of each half to
1940d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  * message regs, kind of like pre-gen5 SIMD16 FB writes.
1941d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  * Just bail on doing so for now.
1942d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  */
1943d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 fail("Missing support for simd16 depth writes on gen6\n");
1944d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1945d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1946d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (c->computes_depth) {
1947d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 /* Hand over gl_FragDepth. */
1948d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 assert(this->frag_depth);
1949d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 fs_reg depth = *(variable_storage(this->frag_depth));
1950d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1951d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 emit(BRW_OPCODE_MOV, fs_reg(MRF, nr), depth);
1952d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      } else {
1953d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 /* Pass through the payload depth. */
1954d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 emit(BRW_OPCODE_MOV, fs_reg(MRF, nr),
1955d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	      fs_reg(brw_vec8_grf(c->source_depth_reg, 0)));
1956d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1957d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      nr += reg_width;
1958d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1959d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1960d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (c->dest_depth_reg) {
1961d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, fs_reg(MRF, nr),
1962d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	   fs_reg(brw_vec8_grf(c->dest_depth_reg, 0)));
1963d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      nr += reg_width;
1964d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1965d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1966d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   for (int target = 0; target < c->key.nr_color_regions; target++) {
1967d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->current_annotation = ralloc_asprintf(this->mem_ctx,
1968d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt						 "FB write target %d",
1969d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt						 target);
19706d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt      for (int i = 0; i < 4; i++)
19716d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt	 emit_color_write(target, i, color_mrf);
1972d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1973d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_inst *inst = emit(FS_OPCODE_FB_WRITE);
1974d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->target = target;
1975eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke      inst->base_mrf = base_mrf;
1976eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke      inst->mlen = nr - base_mrf;
1977d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (target == c->key.nr_color_regions - 1)
1978d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->eot = true;
1979d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->header_present = header_present;
1980d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1981d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1982d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (c->key.nr_color_regions == 0) {
19836d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt      if (c->key.alpha_test) {
1984d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 /* If the alpha test is enabled but there's no color buffer,
1985d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  * we still need to send alpha out the pipeline to our null
1986d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  * renderbuffer.
1987d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  */
19886d874d0ee18b3694c49e0206fa519bd8b746ec24Eric Anholt	 emit_color_write(0, 3, color_mrf);
1989d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1990d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1991d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_inst *inst = emit(FS_OPCODE_FB_WRITE);
1992eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke      inst->base_mrf = base_mrf;
1993eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke      inst->mlen = nr - base_mrf;
1994d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->eot = true;
1995d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->header_present = header_present;
1996d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1997d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1998d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->current_annotation = NULL;
1999d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
200073b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt
200173b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholtvoid
200273b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholtfs_visitor::resolve_ud_negate(fs_reg *reg)
200373b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt{
200473b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt   if (reg->type != BRW_REGISTER_TYPE_UD ||
200573b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt       !reg->negate)
200673b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt      return;
200773b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt
200873b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt   fs_reg temp = fs_reg(this, glsl_type::uint_type);
200973b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt   emit(BRW_OPCODE_MOV, temp, *reg);
201073b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt   *reg = temp;
201173b0a28ba8b3e2ab917d4c729f34ddbde52c9e88Eric Anholt}
2012