brw_fs_visitor.cpp revision 79cba4c2b17456e2b25ac555c45e1c106b4e3f6b
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 (strcmp(ir->name, "gl_FragColor") == 0) {
62d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->frag_color = ir;
63d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else if (strcmp(ir->name, "gl_FragData") == 0) {
64d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->frag_data = ir;
65d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else if (strcmp(ir->name, "gl_FragDepth") == 0) {
66d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->frag_depth = ir;
67d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
68d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
69d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->mode == ir_var_in) {
70d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (!strcmp(ir->name, "gl_FragCoord")) {
71d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 reg = emit_fragcoord_interpolation(ir);
72d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      } else if (!strcmp(ir->name, "gl_FrontFacing")) {
73d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 reg = emit_frontfacing_interpolation(ir);
74d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      } else {
75d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 reg = emit_general_interpolation(ir);
76d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
77d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(reg);
78d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      hash_table_insert(this->variable_ht, reg, ir);
79d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      return;
80d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
81d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
82d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->mode == ir_var_uniform) {
83d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      int param_index = c->prog_data.nr_params;
84d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
85d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (c->dispatch_width == 16) {
86d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 if (!variable_storage(ir)) {
87d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    fail("Failed to find uniform '%s' in 16-wide\n", ir->name);
88d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 }
89d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 return;
90d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
91d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
92d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (!strncmp(ir->name, "gl_", 3)) {
93d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 setup_builtin_uniform_values(ir);
94d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      } else {
95d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 setup_uniform_values(ir->location, ir->type);
96d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
97d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
98d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      reg = new(this->mem_ctx) fs_reg(UNIFORM, param_index);
99d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      reg->type = brw_type_for_base_type(ir->type);
100d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
101d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
102d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (!reg)
103d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      reg = new(this->mem_ctx) fs_reg(this, ir->type);
104d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
105d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   hash_table_insert(this->variable_ht, reg, ir);
106d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
107d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
108d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
109d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_dereference_variable *ir)
110d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
111d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg *reg = variable_storage(ir->var);
112d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->result = *reg;
113d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
114d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
115d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
116d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_dereference_record *ir)
117d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
118d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   const glsl_type *struct_type = ir->record->type;
119d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
120d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir->record->accept(this);
121d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
122d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   unsigned int offset = 0;
123d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   for (unsigned int i = 0; i < struct_type->length; i++) {
124d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0)
125d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
126d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      offset += type_size(struct_type->fields.structure[i].type);
127d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
128d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->result.reg_offset += offset;
129d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->result.type = brw_type_for_base_type(ir->type);
130d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
131d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
132d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
133d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_dereference_array *ir)
134d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
135d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir_constant *index;
136d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int element_size;
137d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
138d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir->array->accept(this);
139d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   index = ir->array_index->as_constant();
140d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
141d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   element_size = type_size(ir->type);
142d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->result.type = brw_type_for_base_type(ir->type);
143d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
144d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (index) {
145b76378d46a211521582cfab56dc05031a57502a6Eric Anholt      assert(this->result.file == UNIFORM || this->result.file == GRF);
146d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->result.reg_offset += index->value.i[0] * element_size;
147d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else {
148d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!"FINISHME: non-constant array element");
149d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
150d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
151d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
152d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/* Instruction selection: Produce a MOV.sat instead of
153d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * MIN(MAX(val, 0), 1) when possible.
154d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */
155d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtbool
156d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::try_emit_saturate(ir_expression *ir)
157d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
158d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir_rvalue *sat_val = ir->as_rvalue_to_saturate();
159d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
160d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (!sat_val)
161d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      return false;
162d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
163d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   sat_val->accept(this);
164d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg src = this->result;
165d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
166d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->result = fs_reg(this, ir->type);
167d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *inst = emit(BRW_OPCODE_MOV, this->result, src);
168d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->saturate = true;
169d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
170d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   return true;
171d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
172d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
173d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
174d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_expression *ir)
175d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
176d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   unsigned int operand;
177d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg op[2], temp;
178d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *inst;
179d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
180d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   assert(ir->get_num_operands() <= 2);
181d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
182d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (try_emit_saturate(ir))
183d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      return;
184d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
185d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   for (operand = 0; operand < ir->get_num_operands(); operand++) {
186d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->operands[operand]->accept(this);
187d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (this->result.file == BAD_FILE) {
188d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 ir_print_visitor v;
189d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 fail("Failed to get tree for expression operand:\n");
190d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 ir->operands[operand]->accept(&v);
191d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
192d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      op[operand] = this->result;
193d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
194d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* Matrix expression operands should have been broken down to vector
195d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * operations already.
196d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       */
197d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!ir->operands[operand]->type->is_matrix());
198d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* And then those vector operands should have been broken down to scalar.
199d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       */
200d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!ir->operands[operand]->type->is_vector());
201d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
202d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
203d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke   /* Storage for our result.  If our result goes into an assignment, it will
204d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke    * just get copy-propagated out, so no worries.
205d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    */
206d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke   this->result = fs_reg(this, ir->type);
207d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
208d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   switch (ir->operation) {
209d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_logic_not:
210d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* Note that BRW_OPCODE_NOT is not appropriate here, since it is
211d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * ones complement of the whole register, not just bit 0.
212d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       */
213d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_XOR, this->result, op[0], fs_reg(1));
214d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
215d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_neg:
216d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      op[0].negate = !op[0].negate;
217d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->result = op[0];
218d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
219d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_abs:
220d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      op[0].abs = true;
221d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      op[0].negate = false;
222d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->result = op[0];
223d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
224d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_sign:
225d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      temp = fs_reg(this, ir->type);
226d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
227d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, this->result, fs_reg(0.0f));
228d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
229d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_CMP, reg_null_f, op[0], fs_reg(0.0f));
230d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->conditional_mod = BRW_CONDITIONAL_G;
231d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_MOV, this->result, fs_reg(1.0f));
232d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->predicated = true;
233d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
234d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_CMP, reg_null_f, op[0], fs_reg(0.0f));
235d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->conditional_mod = BRW_CONDITIONAL_L;
236d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_MOV, this->result, fs_reg(-1.0f));
237d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->predicated = true;
238d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
239d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
240d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_rcp:
24165b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt      emit_math(SHADER_OPCODE_RCP, this->result, op[0]);
242d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
243d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
244d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_exp2:
24565b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt      emit_math(SHADER_OPCODE_EXP2, this->result, op[0]);
246d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
247d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_log2:
24865b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt      emit_math(SHADER_OPCODE_LOG2, this->result, op[0]);
249d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
250d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_exp:
251d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_log:
252d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!"not reached: should be handled by ir_explog_to_explog2");
253d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
254d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_sin:
255d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_sin_reduced:
25665b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt      emit_math(SHADER_OPCODE_SIN, this->result, op[0]);
257d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
258d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_cos:
259d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_cos_reduced:
26065b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt      emit_math(SHADER_OPCODE_COS, this->result, op[0]);
261d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
262d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
263d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_dFdx:
264d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(FS_OPCODE_DDX, this->result, op[0]);
265d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
266d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_dFdy:
267d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(FS_OPCODE_DDY, this->result, op[0]);
268d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
269d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
270d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_add:
271d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_ADD, this->result, op[0], op[1]);
272d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
273d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_sub:
274d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!"not reached: should be handled by ir_sub_to_add_neg");
275d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
276d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
277d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_mul:
2783f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt      if (ir->type->is_integer()) {
2793f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	 /* For integer multiplication, the MUL uses the low 16 bits
2803f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	  * of one of the operands (src0 on gen6, src1 on gen7).  The
2813f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	  * MACH accumulates in the contribution of the upper 16 bits
2823f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	  * of that operand.
2833f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	  *
2843f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	  * FINISHME: Emit just the MUL if we know an operand is small
2853f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	  * enough.
2863f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	  */
2873f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	 struct brw_reg acc = retype(brw_acc_reg(), BRW_REGISTER_TYPE_D);
2883f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt
2893f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	 emit(BRW_OPCODE_MUL, acc, op[0], op[1]);
2903f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	 emit(BRW_OPCODE_MACH, reg_null_d, op[0], op[1]);
2913f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	 emit(BRW_OPCODE_MOV, this->result, fs_reg(acc));
2923f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt      } else {
2933f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt	 emit(BRW_OPCODE_MUL, this->result, op[0], op[1]);
2943f78f719732b87e6707f94c187ad6e263c6c2ef0Eric Anholt      }
295d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
296d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_div:
297d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!"not reached: should be handled by ir_div_to_mul_rcp");
298d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
299d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_mod:
300d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!"ir_binop_mod should have been converted to b * fract(a/b)");
301d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
302d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
303d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_less:
304d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_greater:
305d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_lequal:
306d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_gequal:
307d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_equal:
308d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_all_equal:
309d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_nequal:
310d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_any_nequal:
311d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      temp = this->result;
312d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* original gen4 does implicit conversion before comparison. */
313d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (intel->gen < 5)
314d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 temp.type = op[0].type;
315d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
316d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_CMP, temp, op[0], op[1]);
317d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->conditional_mod = brw_conditional_for_comparison(ir->operation);
318d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_AND, this->result, this->result, fs_reg(0x1));
319d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
320d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
321d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_logic_xor:
322d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_XOR, this->result, op[0], op[1]);
323d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
324d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
325d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_logic_or:
326d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_OR, this->result, op[0], op[1]);
327d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
328d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
329d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_logic_and:
330d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_AND, this->result, op[0], op[1]);
331d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
332d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
333d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_dot:
334d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_any:
335d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!"not reached: should be handled by brw_fs_channel_expressions");
336d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
337d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
338d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_noise:
339d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!"not reached: should be handled by lower_noise");
340d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
341d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
342d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_quadop_vector:
343d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!"not reached: should be handled by lower_quadop_vector");
344d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
345d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
346d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_sqrt:
34765b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt      emit_math(SHADER_OPCODE_SQRT, this->result, op[0]);
348d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
349d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
350d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_rsq:
35165b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt      emit_math(SHADER_OPCODE_RSQ, this->result, op[0]);
352d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
353d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
354b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke   case ir_unop_i2u:
355b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke      op[0].type = BRW_REGISTER_TYPE_UD;
356b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke      this->result = op[0];
357b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke      break;
358b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke   case ir_unop_u2i:
359b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke      op[0].type = BRW_REGISTER_TYPE_D;
360b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke      this->result = op[0];
361b633ddeb9fd951ddc49e8a3fd25a946e5a16361fKenneth Graunke      break;
362d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_i2f:
3634bc5bfb641bce931bf35f0e78ec2b44263d152baKenneth Graunke   case ir_unop_u2f:
364d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_b2f:
365d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_b2i:
366d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_f2i:
367d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, this->result, op[0]);
368d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
369d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_f2b:
370d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_i2b:
371d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      temp = this->result;
372d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* original gen4 does implicit conversion before comparison. */
373d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (intel->gen < 5)
374d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 temp.type = op[0].type;
375d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
376d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_CMP, temp, op[0], fs_reg(0.0f));
377d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->conditional_mod = BRW_CONDITIONAL_NZ;
378d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_AND, this->result, this->result, fs_reg(1));
379d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
380d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
381d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_trunc:
382d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_RNDZ, this->result, op[0]);
383d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
384d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_ceil:
385d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      op[0].negate = !op[0].negate;
386d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_RNDD, this->result, op[0]);
387d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->result.negate = true;
388d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
389d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_floor:
390d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_RNDD, this->result, op[0]);
391d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
392d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_fract:
393d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_FRC, this->result, op[0]);
394d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
395d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_round_even:
396d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_RNDE, this->result, op[0]);
397d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
398d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
399d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_min:
400c331b3123ecda127919458e24848b7c1596525acEric Anholt      if (intel->gen >= 6) {
401c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]);
402c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_L;
403c331b3123ecda127919458e24848b7c1596525acEric Anholt      } else {
404c331b3123ecda127919458e24848b7c1596525acEric Anholt	 /* Unalias the destination */
405c331b3123ecda127919458e24848b7c1596525acEric Anholt	 this->result = fs_reg(this, ir->type);
406d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
407c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst = emit(BRW_OPCODE_CMP, this->result, op[0], op[1]);
408c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_L;
409d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
410c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]);
411c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst->predicated = true;
412c331b3123ecda127919458e24848b7c1596525acEric Anholt      }
413d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
414d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_max:
415c331b3123ecda127919458e24848b7c1596525acEric Anholt      if (intel->gen >= 6) {
416c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]);
417c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_GE;
418c331b3123ecda127919458e24848b7c1596525acEric Anholt      } else {
419c331b3123ecda127919458e24848b7c1596525acEric Anholt	 /* Unalias the destination */
420c331b3123ecda127919458e24848b7c1596525acEric Anholt	 this->result = fs_reg(this, ir->type);
421d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
422c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst = emit(BRW_OPCODE_CMP, this->result, op[0], op[1]);
423c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_G;
424d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
425c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]);
426c331b3123ecda127919458e24848b7c1596525acEric Anholt	 inst->predicated = true;
427c331b3123ecda127919458e24848b7c1596525acEric Anholt      }
428d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
429d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
430d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_pow:
43165b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt      emit_math(SHADER_OPCODE_POW, this->result, op[0], op[1]);
432d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
433d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
434d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_unop_bit_not:
435d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_NOT, this->result, op[0]);
436d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
437d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_bit_and:
438d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_AND, this->result, op[0], op[1]);
439d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
440d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_bit_xor:
441d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_XOR, this->result, op[0], op[1]);
442d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
443d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_bit_or:
444d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_OR, this->result, op[0], op[1]);
445d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
446d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
447d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_lshift:
448d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_binop_rshift:
449d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!"GLSL 1.30 features unsupported");
450d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
451d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
452d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
453d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
454d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
455d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_assignment_writes(fs_reg &l, fs_reg &r,
456d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt				   const glsl_type *type, bool predicated)
457d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
458d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   switch (type->base_type) {
459d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case GLSL_TYPE_FLOAT:
460d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case GLSL_TYPE_UINT:
461d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case GLSL_TYPE_INT:
462d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case GLSL_TYPE_BOOL:
463d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (unsigned int i = 0; i < type->components(); i++) {
464d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 l.type = brw_type_for_base_type(type);
465d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 r.type = brw_type_for_base_type(type);
466d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
467d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 if (predicated || !l.equals(&r)) {
468d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    fs_inst *inst = emit(BRW_OPCODE_MOV, l, r);
469d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    inst->predicated = predicated;
470d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 }
471d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
472d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 l.reg_offset++;
473d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 r.reg_offset++;
474d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
475d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
476d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case GLSL_TYPE_ARRAY:
477d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (unsigned int i = 0; i < type->length; i++) {
478d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 emit_assignment_writes(l, r, type->fields.array, predicated);
479d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
480d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
481d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
482d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case GLSL_TYPE_STRUCT:
483d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (unsigned int i = 0; i < type->length; i++) {
484d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 emit_assignment_writes(l, r, type->fields.structure[i].type,
485d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt				predicated);
486d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
487d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
488d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
489d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case GLSL_TYPE_SAMPLER:
490d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
491d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
492d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   default:
493d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(!"not reached");
494d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
495d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
496d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
497d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
498dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke/* If the RHS processing resulted in an instruction generating a
499dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke * temporary value, and it would be easy to rewrite the instruction to
500dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke * generate its result right into the LHS instead, do so.  This ends
501dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke * up reliably removing instructions where it can be tricky to do so
502dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke * later without real UD chain information.
503dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke */
504dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunkebool
505dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunkefs_visitor::try_rewrite_rhs_to_dst(ir_assignment *ir,
506dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke                                   fs_reg dst,
507dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke                                   fs_reg src,
508dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke                                   fs_inst *pre_rhs_inst,
509dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke                                   fs_inst *last_rhs_inst)
510dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke{
511dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   if (pre_rhs_inst == last_rhs_inst)
512dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke      return false; /* No instructions generated to work with. */
513dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke
514dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   /* Only attempt if we're doing a direct assignment. */
515dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   if (ir->condition ||
516dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke       !(ir->lhs->type->is_scalar() ||
517dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke        (ir->lhs->type->is_vector() &&
518dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke         ir->write_mask == (1 << ir->lhs->type->vector_elements) - 1)))
519dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke      return false;
520dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke
521dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   /* Make sure the last instruction generated our source reg. */
522dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   if (last_rhs_inst->predicated ||
523dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke       last_rhs_inst->force_uncompressed ||
524dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke       last_rhs_inst->force_sechalf ||
525dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke       !src.equals(&last_rhs_inst->dst))
526dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke      return false;
527dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke
528dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   /* Success!  Rewrite the instruction. */
529dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   last_rhs_inst->dst = dst;
530dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke
531dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   return true;
532dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke}
533dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke
534d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
535d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_assignment *ir)
536d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
537eb86bb55f5faef67c21604db19210c6788592679Kenneth Graunke   fs_reg l, r;
538d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *inst;
539d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
540d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* FINISHME: arrays on the lhs */
541d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir->lhs->accept(this);
542d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   l = this->result;
543d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
544dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   fs_inst *pre_rhs_inst = (fs_inst *) this->instructions.get_tail();
545dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke
546d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir->rhs->accept(this);
547d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   r = this->result;
548d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
549dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   fs_inst *last_rhs_inst = (fs_inst *) this->instructions.get_tail();
550dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke
551d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   assert(l.file != BAD_FILE);
552d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   assert(r.file != BAD_FILE);
553d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
554dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke   if (try_rewrite_rhs_to_dst(ir, l, r, pre_rhs_inst, last_rhs_inst))
555dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke      return;
556dc7f449d1ac53a66e6efb56ccf2a5953418a26caKenneth Graunke
557d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->condition) {
558d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit_bool_to_cond_code(ir->condition);
559d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
560d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
561d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->lhs->type->is_scalar() ||
562d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       ir->lhs->type->is_vector()) {
563d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (int i = 0; i < ir->lhs->type->vector_elements; i++) {
564d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 if (ir->write_mask & (1 << i)) {
565d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke	    inst = emit(BRW_OPCODE_MOV, l, r);
566d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke	    if (ir->condition)
567d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	       inst->predicated = true;
568d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    r.reg_offset++;
569d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 }
570d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 l.reg_offset++;
571d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
572d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else {
573d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit_assignment_writes(l, r, ir->lhs->type, ir->condition != NULL);
574d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
575d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
576d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
577d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_inst *
578d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate,
579d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt			      int sampler)
580d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
581d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int mlen;
582d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int base_mrf = 1;
583d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   bool simd16 = false;
584d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg orig_dst;
585d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
586d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* g0 header. */
587d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   mlen = 1;
588d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
5896430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke   if (ir->shadow_comparitor && ir->op != ir_txd) {
590d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
591d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 fs_inst *inst = emit(BRW_OPCODE_MOV,
592d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt			      fs_reg(MRF, base_mrf + mlen + i), coordinate);
593d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler))
594d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    inst->saturate = true;
595d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
596d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 coordinate.reg_offset++;
597d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
598d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* gen4's SIMD8 sampler always has the slots for u,v,r present. */
599d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen += 3;
600d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
601d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (ir->op == ir_tex) {
602d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 /* There's no plain shadow compare message, so we use shadow
603d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  * compare with a bias of 0.0.
604d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  */
605d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), fs_reg(0.0f));
606d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 mlen++;
607d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      } else if (ir->op == ir_txb) {
608d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 ir->lod_info.bias->accept(this);
609d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
610d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 mlen++;
611d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      } else {
612d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 assert(ir->op == ir_txl);
613d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 ir->lod_info.lod->accept(this);
614d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
615d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 mlen++;
616d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
617d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
618d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->shadow_comparitor->accept(this);
619d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
620d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen++;
621d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else if (ir->op == ir_tex) {
622d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
623d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i),
624d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt			      coordinate);
625d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler))
626d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    inst->saturate = true;
627d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 coordinate.reg_offset++;
628d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
629d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* gen4's SIMD8 sampler always has the slots for u,v,r present. */
630d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen += 3;
631d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else if (ir->op == ir_txd) {
6326c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      ir->lod_info.grad.dPdx->accept(this);
6336c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      fs_reg dPdx = this->result;
6346c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke
6356c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      ir->lod_info.grad.dPdy->accept(this);
6366c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      fs_reg dPdy = this->result;
6376c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke
6386c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
6396c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i), coordinate);
6406c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke	 coordinate.reg_offset++;
6416c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      }
6426c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      /* the slots for u and v are always present, but r is optional */
6436c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      mlen += MAX2(ir->coordinate->type->vector_elements, 2);
6446c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke
6456c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      /*  P   = u, v, r
6466c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       * dPdx = dudx, dvdx, drdx
6476c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       * dPdy = dudy, dvdy, drdy
6486c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       *
6493e1fd13f605f16e8b48f3a9b71910a3c66eb84b5Kenneth Graunke       * 1-arg: Does not exist.
6503e1fd13f605f16e8b48f3a9b71910a3c66eb84b5Kenneth Graunke       *
6516c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       * 2-arg: dudx   dvdx   dudy   dvdy
6526c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       *        dPdx.x dPdx.y dPdy.x dPdy.y
6536c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       *        m4     m5     m6     m7
6546c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       *
6556c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       * 3-arg: dudx   dvdx   drdx   dudy   dvdy   drdy
6566c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       *        dPdx.x dPdx.y dPdx.z dPdy.x dPdy.y dPdy.z
6576c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       *        m5     m6     m7     m8     m9     m10
6586c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke       */
6596c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      for (int i = 0; i < ir->lod_info.grad.dPdx->type->vector_elements; i++) {
6606c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdx);
6616c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke	 dPdx.reg_offset++;
6626c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      }
6633e1fd13f605f16e8b48f3a9b71910a3c66eb84b5Kenneth Graunke      mlen += MAX2(ir->lod_info.grad.dPdx->type->vector_elements, 2);
6646c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke
6656c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      for (int i = 0; i < ir->lod_info.grad.dPdy->type->vector_elements; i++) {
6666c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdy);
6676c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke	 dPdy.reg_offset++;
6686c947cfd1973c3791d54f1406c973357b4a9621aKenneth Graunke      }
6693e1fd13f605f16e8b48f3a9b71910a3c66eb84b5Kenneth Graunke      mlen += MAX2(ir->lod_info.grad.dPdy->type->vector_elements, 2);
6704eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke   } else if (ir->op == ir_txs) {
6714eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke      /* There's no SIMD8 resinfo message on Gen4.  Use SIMD16 instead. */
6724eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke      simd16 = true;
6734eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke      ir->lod_info.lod->accept(this);
6744eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), this->result);
6754eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke      mlen += 2;
676d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else {
677d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* Oh joy.  gen4 doesn't have SIMD8 non-shadow-compare bias/lod
678d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * instructions.  We'll need to do SIMD16 here.
679d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       */
6804eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke      simd16 = true;
68147b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke      assert(ir->op == ir_txb || ir->op == ir_txl || ir->op == ir_txf);
682d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
683d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
684d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF,
68547b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke						     base_mrf + mlen + i * 2,
68647b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke						     coordinate.type),
687d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt			      coordinate);
688d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler))
689d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    inst->saturate = true;
690d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 coordinate.reg_offset++;
691d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
692d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
69347b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke      /* Initialize the rest of u/v/r with 0.0.  Empirically, this seems to
69447b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke       * be necessary for TXF (ld), but seems wise to do for all messages.
69547b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke       */
69647b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke      for (int i = ir->coordinate->type->vector_elements; i < 3; i++) {
69747b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i * 2), fs_reg(0.0f));
69847b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke      }
69947b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke
700d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* lod/bias appears after u/v/r. */
701d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen += 6;
702d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
703d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (ir->op == ir_txb) {
704d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 ir->lod_info.bias->accept(this);
705d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
706d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 mlen++;
707d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      } else {
708d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 ir->lod_info.lod->accept(this);
70947b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, this->result.type),
71047b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke			      this->result);
711d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 mlen++;
712d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
713d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
714d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* The unused upper half. */
715d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen++;
7164eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke   }
717d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
7184eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke   if (simd16) {
719d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* Now, since we're doing simd16, the return is 2 interleaved
720d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * vec4s where the odd-indexed ones are junk. We'll need to move
721d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * this weirdness around to the expected layout.
722d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       */
723d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      orig_dst = dst;
7244eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke      const glsl_type *vec_type =
7254eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke	 glsl_type::get_instance(ir->type->base_type, 4, 1);
7264eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke      dst = fs_reg(this, glsl_type::get_array_instance(vec_type, 2));
7274eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke      dst.type = intel->is_g4x ? brw_type_for_base_type(ir->type)
7284eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke			       : BRW_REGISTER_TYPE_F;
729d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
730d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
731d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *inst = NULL;
732d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   switch (ir->op) {
733d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_tex:
734d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(FS_OPCODE_TEX, dst);
735d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
736d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_txb:
737d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(FS_OPCODE_TXB, dst);
738d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
739d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_txl:
740d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(FS_OPCODE_TXL, dst);
741d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
742d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_txd:
743d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(FS_OPCODE_TXD, dst);
744d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
7451e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke   case ir_txs:
7464eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke      inst = emit(FS_OPCODE_TXS, dst);
7474eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke      break;
7484eeb4c150598605d1be3ce6674fa63076a720ae9Kenneth Graunke   case ir_txf:
74947b556fbcaea4660b21481e40d89167d883d47f5Kenneth Graunke      inst = emit(FS_OPCODE_TXF, dst);
750d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
751d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
752d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->base_mrf = base_mrf;
753d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->mlen = mlen;
754d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->header_present = true;
755d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
756d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (simd16) {
757d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (int i = 0; i < 4; i++) {
758d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 emit(BRW_OPCODE_MOV, orig_dst, dst);
759d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 orig_dst.reg_offset++;
760d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 dst.reg_offset += 2;
761d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
762d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
763d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
764d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   return inst;
765d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
766d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
767d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/* gen5's sampler has slots for u, v, r, array index, then optional
768d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * parameters like shadow comparitor or LOD bias.  If optional
769d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * parameters aren't present, those base slots are optional and don't
770d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * need to be included in the message.
771d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt *
772d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * We don't fill in the unnecessary slots regardless, which may look
773d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * surprising in the disassembly.
774d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */
775d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_inst *
776d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate,
777d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt			      int sampler)
778d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
779d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int mlen = 0;
780d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int base_mrf = 2;
781d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int reg_width = c->dispatch_width / 8;
782d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   bool header_present = false;
783ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke   const int vector_elements =
784ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke      ir->coordinate ? ir->coordinate->type->vector_elements : 0;
785d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
786d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->offset) {
787d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* The offsets set up by the ir_texture visitor are in the
788d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m1 header, so we can't go headerless.
789d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       */
790d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      header_present = true;
791d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen++;
792d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      base_mrf--;
793d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
794d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
795ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke   for (int i = 0; i < vector_elements; i++) {
796d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_inst *inst = emit(BRW_OPCODE_MOV,
79730be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke			   fs_reg(MRF, base_mrf + mlen + i * reg_width,
79830be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke				  coordinate.type),
799d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt			   coordinate);
800d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler))
801d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->saturate = true;
802d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      coordinate.reg_offset++;
803d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
804ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke   mlen += vector_elements * reg_width;
805d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
8066430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke   if (ir->shadow_comparitor && ir->op != ir_txd) {
807d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen = MAX2(mlen, header_present + 4 * reg_width);
808d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
809d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->shadow_comparitor->accept(this);
810d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
811d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen += reg_width;
812d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
813d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
814d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *inst = NULL;
815d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   switch (ir->op) {
816d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_tex:
817d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(FS_OPCODE_TEX, dst);
818d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
819d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_txb:
820d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->lod_info.bias->accept(this);
821d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen = MAX2(mlen, header_present + 4 * reg_width);
822d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
823d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen += reg_width;
824d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
825d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(FS_OPCODE_TXB, dst);
826d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
827d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
828d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_txl:
829d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->lod_info.lod->accept(this);
830d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen = MAX2(mlen, header_present + 4 * reg_width);
831d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
832d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen += reg_width;
833d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
834d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(FS_OPCODE_TXL, dst);
835d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
8362f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke   case ir_txd: {
8372f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke      ir->lod_info.grad.dPdx->accept(this);
8382f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke      fs_reg dPdx = this->result;
8392f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke
8402f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke      ir->lod_info.grad.dPdy->accept(this);
8412f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke      fs_reg dPdy = this->result;
8422f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke
8432f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke      mlen = MAX2(mlen, header_present + 4 * reg_width); /* skip over 'ai' */
8442f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke
8452f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke      /**
8462f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke       *  P   =  u,    v,    r
8472f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke       * dPdx = dudx, dvdx, drdx
8482f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke       * dPdy = dudy, dvdy, drdy
8492f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke       *
8502f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke       * Load up these values:
8512f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke       * - dudx   dudy   dvdx   dvdy   drdx   drdy
8522f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke       * - dPdx.x dPdy.x dPdx.y dPdy.y dPdx.z dPdy.z
8532f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke       */
8542f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke      for (int i = 0; i < ir->lod_info.grad.dPdx->type->vector_elements; i++) {
8552f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdx);
8562f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke	 dPdx.reg_offset++;
8572f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke	 mlen += reg_width;
8582f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke
8592f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdy);
8602f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke	 dPdy.reg_offset++;
8612f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke	 mlen += reg_width;
8622f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke      }
8632f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke
8642f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke      inst = emit(FS_OPCODE_TXD, dst);
8652f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke      break;
8662f4a4b943f1cad9bbbb8f66c34dca506503ba5bbKenneth Graunke   }
8671e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke   case ir_txs:
868ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke      ir->lod_info.lod->accept(this);
869ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), this->result);
870ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke      mlen += reg_width;
871ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke      inst = emit(FS_OPCODE_TXS, dst);
872ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke      break;
873ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke   case ir_txf:
87430be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke      mlen = header_present + 4 * reg_width;
87530be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke
87630be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke      ir->lod_info.lod->accept(this);
87730be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke      emit(BRW_OPCODE_MOV,
87830be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke	   fs_reg(MRF, base_mrf + mlen - reg_width, BRW_REGISTER_TYPE_UD),
87930be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke	   this->result);
88030be2cc6c7c3378ee17885b5bf41d7ae53bf6fe0Kenneth Graunke      inst = emit(FS_OPCODE_TXF, dst);
881d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
882d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
883d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->base_mrf = base_mrf;
884d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->mlen = mlen;
885d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->header_present = header_present;
886d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
887d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (mlen > 11) {
888d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fail("Message length >11 disallowed by hardware\n");
889d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
890d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
891d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   return inst;
892d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
893d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
894d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_inst *
895d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
896d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt			      int sampler)
897d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
898d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int mlen = 0;
899d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int base_mrf = 2;
900d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int reg_width = c->dispatch_width / 8;
901d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   bool header_present = false;
902d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
903d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->offset) {
904d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* The offsets set up by the ir_texture visitor are in the
905d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m1 header, so we can't go headerless.
906d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       */
907d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      header_present = true;
908d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen++;
909d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      base_mrf--;
910d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
911d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
9126430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke   if (ir->shadow_comparitor && ir->op != ir_txd) {
913d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->shadow_comparitor->accept(this);
914d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
915d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen += reg_width;
916d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
917d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
918d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Set up the LOD info */
919d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   switch (ir->op) {
920d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_tex:
921d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
922d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_txb:
923d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->lod_info.bias->accept(this);
924d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
925d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen += reg_width;
926d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
927d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_txl:
928d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->lod_info.lod->accept(this);
929d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
930d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      mlen += reg_width;
931d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
9323fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke   case ir_txd: {
9333fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke      if (c->dispatch_width == 16)
9343fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 fail("Gen7 does not support sample_d/sample_d_c in SIMD16 mode.");
9353fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke
9363fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke      ir->lod_info.grad.dPdx->accept(this);
9373fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke      fs_reg dPdx = this->result;
9383fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke
9393fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke      ir->lod_info.grad.dPdy->accept(this);
9403fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke      fs_reg dPdy = this->result;
9413fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke
9423fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke      /* Load dPdx and the coordinate together:
9433fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke       * [hdr], [ref], x, dPdx.x, dPdy.x, y, dPdx.y, dPdy.y, z, dPdx.z, dPdy.z
9443fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke       */
9453fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke      for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
9463fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen),
9473fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke			      coordinate);
9483fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler))
9493fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	    inst->saturate = true;
9503fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 coordinate.reg_offset++;
9513fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 mlen += reg_width;
9523fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke
9533fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdx);
9543fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 dPdx.reg_offset++;
9553fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 mlen += reg_width;
9563fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke
9573fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdy);
9583fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 dPdy.reg_offset++;
9593fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 mlen += reg_width;
9603fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke      }
9613fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke      break;
9623fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke   }
9631e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke   case ir_txs:
964ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke      ir->lod_info.lod->accept(this);
965ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), this->result);
966ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke      mlen += reg_width;
967ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke      break;
968ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke   case ir_txf:
9690edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke      /* Unfortunately, the parameters for LD are intermixed: u, lod, v, r. */
970c310c35a754be835c9ceafe578c4974a667b9a77Eric Anholt      emit(BRW_OPCODE_MOV,
971c310c35a754be835c9ceafe578c4974a667b9a77Eric Anholt	   fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_D), coordinate);
9720edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke      coordinate.reg_offset++;
9730edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke      mlen += reg_width;
9740edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke
9750edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke      ir->lod_info.lod->accept(this);
9760edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_D), this->result);
9770edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke      mlen += reg_width;
9780edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke
9790edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke      for (int i = 1; i < ir->coordinate->type->vector_elements; i++) {
980c310c35a754be835c9ceafe578c4974a667b9a77Eric Anholt	 emit(BRW_OPCODE_MOV,
981c310c35a754be835c9ceafe578c4974a667b9a77Eric Anholt	      fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_D), coordinate);
9820edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke	 coordinate.reg_offset++;
9830edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke	 mlen += reg_width;
9840edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke      }
985d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
986d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
987d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
9880edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke   /* Set up the coordinate (except for cases where it was done above) */
9890edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke   if (ir->op != ir_txd && ir->op != ir_txs && ir->op != ir_txf) {
9903fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke      for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
9913fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen),
9923fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke			      coordinate);
9933fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler))
9943fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	    inst->saturate = true;
9953fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 coordinate.reg_offset++;
9963fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke	 mlen += reg_width;
9973fa910fff9f72d1adf33f0f4dea3d790a9ce04abKenneth Graunke      }
998d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
999d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1000d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Generate the SEND */
1001d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *inst = NULL;
1002d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   switch (ir->op) {
1003d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_tex: inst = emit(FS_OPCODE_TEX, dst); break;
1004d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_txb: inst = emit(FS_OPCODE_TXB, dst); break;
1005d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_txl: inst = emit(FS_OPCODE_TXL, dst); break;
1006d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_txd: inst = emit(FS_OPCODE_TXD, dst); break;
10070edf5d63d60100cc2b7467da78ce811c4824b760Kenneth Graunke   case ir_txf: inst = emit(FS_OPCODE_TXF, dst); break;
1008ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke   case ir_txs: inst = emit(FS_OPCODE_TXS, dst); break;
1009d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1010d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->base_mrf = base_mrf;
1011d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->mlen = mlen;
1012d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->header_present = header_present;
1013d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1014d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (mlen > 11) {
1015d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fail("Message length >11 disallowed by hardware\n");
1016d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1017d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1018d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   return inst;
1019d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1020d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1021d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1022d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_texture *ir)
1023d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1024d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *inst = NULL;
1025d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1026f1622cfe9c0f37a9b452be1297f187cba8c46e6aKenneth Graunke   int sampler = _mesa_get_sampler_uniform_value(ir->sampler, prog, &fp->Base);
1027f1622cfe9c0f37a9b452be1297f187cba8c46e6aKenneth Graunke   sampler = fp->Base.SamplerUnits[sampler];
1028f1622cfe9c0f37a9b452be1297f187cba8c46e6aKenneth Graunke
10296430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke   /* Our hardware doesn't have a sample_d_c message, so shadow compares
10306430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke    * for textureGrad/TXD need to be emulated with instructions.
10316430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke    */
10326430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke   bool hw_compare_supported = ir->op != ir_txd;
10336430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke   if (ir->shadow_comparitor && !hw_compare_supported) {
10346430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke      assert(c->key.compare_funcs[sampler] != GL_NONE);
10356430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke      /* No need to even sample for GL_ALWAYS or GL_NEVER...bail early */
10366430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke      if (c->key.compare_funcs[sampler] == GL_ALWAYS)
10376430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 return swizzle_result(ir, fs_reg(1.0f), sampler);
10386430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke      else if (c->key.compare_funcs[sampler] == GL_NEVER)
10396430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 return swizzle_result(ir, fs_reg(0.0f), sampler);
10406430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke   }
10416430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke
1042ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke   if (ir->coordinate)
1043ecf8963754489abfb5097c130a9bcd4cdb76b6bdKenneth Graunke      ir->coordinate->accept(this);
1044d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg coordinate = this->result;
1045d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1046d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->offset != NULL) {
1047d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir_constant *offset = ir->offset->as_constant();
1048d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(offset != NULL);
1049d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1050d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      signed char offsets[3];
1051d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (unsigned i = 0; i < ir->offset->type->vector_elements; i++)
1052d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 offsets[i] = (signed char) offset->value.i[i];
1053d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1054d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* Combine all three offsets into a single unsigned dword:
1055d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       *
1056d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       *    bits 11:8 - U Offset (X component)
1057d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       *    bits  7:4 - V Offset (Y component)
1058d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       *    bits  3:0 - R Offset (Z component)
1059d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       */
1060d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      unsigned offset_bits = 0;
1061d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (unsigned i = 0; i < ir->offset->type->vector_elements; i++) {
1062d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 const unsigned shift = 4 * (2 - i);
1063d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 offset_bits |= (offsets[i] << shift) & (0xF << shift);
1064d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1065d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1066d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* Explicitly set up the message header by copying g0 to msg reg m1. */
1067d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, fs_reg(MRF, 1, BRW_REGISTER_TYPE_UD),
1068d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	   fs_reg(GRF, 0, BRW_REGISTER_TYPE_UD));
1069d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1070d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* Then set the offset bits in DWord 2 of the message header. */
1071d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV,
1072d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	   fs_reg(retype(brw_vec1_reg(BRW_MESSAGE_REGISTER_FILE, 1, 2),
1073d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt			 BRW_REGISTER_TYPE_UD)),
1074d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	   fs_reg(brw_imm_uw(offset_bits)));
1075d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1076d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1077d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Should be lowered by do_lower_texture_projection */
1078d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   assert(!ir->projector);
1079d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1080d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* The 965 requires the EU to do the normalization of GL rectangle
1081d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * texture coordinates.  We use the program parameter state
1082d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * tracking to get the scaling factor.
1083d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    */
10849d4b98eb9eadecc17cd1cda0074b420a39e74647Eric Anholt   if (intel->gen < 6 &&
10859d4b98eb9eadecc17cd1cda0074b420a39e74647Eric Anholt       ir->sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_RECT) {
1086d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      struct gl_program_parameter_list *params = c->fp->program.Base.Parameters;
1087d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      int tokens[STATE_LENGTH] = {
1088d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 STATE_INTERNAL,
1089d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 STATE_TEXRECT_SCALE,
1090d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 sampler,
1091d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 0,
1092d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 0
1093d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      };
1094d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1095d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (c->dispatch_width == 16) {
1096d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 fail("rectangle scale uniform setup not supported on 16-wide\n");
1097d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 this->result = fs_reg(this, ir->type);
1098d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 return;
1099d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1100d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1101d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      c->prog_data.param_convert[c->prog_data.nr_params] =
1102d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 PARAM_NO_CONVERT;
1103d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      c->prog_data.param_convert[c->prog_data.nr_params + 1] =
1104d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 PARAM_NO_CONVERT;
1105d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1106d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_reg scale_x = fs_reg(UNIFORM, c->prog_data.nr_params);
1107d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_reg scale_y = fs_reg(UNIFORM, c->prog_data.nr_params + 1);
1108d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      GLuint index = _mesa_add_state_reference(params,
1109d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt					       (gl_state_index *)tokens);
1110d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1111d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->param_index[c->prog_data.nr_params] = index;
1112d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->param_offset[c->prog_data.nr_params] = 0;
1113d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      c->prog_data.nr_params++;
1114d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->param_index[c->prog_data.nr_params] = index;
1115d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->param_offset[c->prog_data.nr_params] = 1;
1116d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      c->prog_data.nr_params++;
1117d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1118d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_reg dst = fs_reg(this, ir->coordinate->type);
1119d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_reg src = coordinate;
1120d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      coordinate = dst;
1121d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1122d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MUL, dst, src, scale_x);
1123d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      dst.reg_offset++;
1124d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      src.reg_offset++;
1125d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MUL, dst, src, scale_y);
1126d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1127d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1128d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Writemasking doesn't eliminate channels on SIMD8 texture
1129d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * samples, so don't worry about them.
1130d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    */
1131b6bdcf2a908889532ef6d5eb643791176dffcb9dKenneth Graunke   fs_reg dst = fs_reg(this, glsl_type::get_instance(ir->type->base_type, 4, 1));
1132d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1133d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (intel->gen >= 7) {
1134d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit_texture_gen7(ir, dst, coordinate, sampler);
1135d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else if (intel->gen >= 5) {
1136d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit_texture_gen5(ir, dst, coordinate, sampler);
1137d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else {
1138d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit_texture_gen4(ir, dst, coordinate, sampler);
1139d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1140d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1141d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* If there's an offset, we already set up m1.  To avoid the implied move,
1142d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * use the null register.  Otherwise, we want an implied move from g0.
1143d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    */
1144d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->offset != NULL || !inst->header_present)
1145d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->src[0] = reg_undef;
1146d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   else
1147d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->src[0] = fs_reg(retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW));
1148d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1149d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->sampler = sampler;
1150d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
11516430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke   if (ir->shadow_comparitor) {
11526430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke      if (hw_compare_supported) {
11536430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 inst->shadow_compare = true;
11546430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke      } else {
11556430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 ir->shadow_comparitor->accept(this);
11566430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 fs_reg ref = this->result;
11576430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke
11586430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 fs_reg value = dst;
11596430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 dst = fs_reg(this, glsl_type::vec4_type);
11606430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke
11616430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 /* FINISHME: This needs to be done pre-filtering. */
11626430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke
11636430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 uint32_t conditional = 0;
11646430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 switch (c->key.compare_funcs[sampler]) {
11656430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 /* GL_ALWAYS and GL_NEVER were handled at the top of the function */
11666430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 case GL_LESS:     conditional = BRW_CONDITIONAL_L;   break;
11676430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 case GL_GREATER:  conditional = BRW_CONDITIONAL_G;   break;
11686430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 case GL_LEQUAL:   conditional = BRW_CONDITIONAL_LE;  break;
11696430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 case GL_GEQUAL:   conditional = BRW_CONDITIONAL_GE;  break;
11706430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 case GL_EQUAL:    conditional = BRW_CONDITIONAL_EQ;  break;
11716430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 case GL_NOTEQUAL: conditional = BRW_CONDITIONAL_NEQ; break;
11726430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 default: assert(!"Should not get here: bad shadow compare function");
11736430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 }
11746430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke
11756430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 /* Use conditional moves to load 0 or 1 as the result */
11766430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 this->current_annotation = "manual shadow comparison";
11776430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 for (int i = 0; i < 4; i++) {
11786430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	    inst = emit(BRW_OPCODE_MOV, dst, fs_reg(0.0f));
11796430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke
11806430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	    inst = emit(BRW_OPCODE_CMP, reg_null_f, ref, value);
11816430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	    inst->conditional_mod = conditional;
11826430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke
11836430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	    inst = emit(BRW_OPCODE_MOV, dst, fs_reg(1.0f));
11846430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	    inst->predicated = true;
11856430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke
11866430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	    dst.reg_offset++;
11876430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	    value.reg_offset++;
11886430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 }
11896430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke	 dst.reg_offset = 0;
11906430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke      }
11916430df37736d71dd2bd6f1fe447d39f0b68cb567Kenneth Graunke   }
1192d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
119301fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke   swizzle_result(ir, dst, sampler);
119401fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke}
119501fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke
119601fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke/**
119701fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke * Swizzle the result of a texture result.  This is necessary for
119801fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke * EXT_texture_swizzle as well as DEPTH_TEXTURE_MODE for shadow comparisons.
119901fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke */
120001fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunkevoid
120101fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunkefs_visitor::swizzle_result(ir_texture *ir, fs_reg orig_val, int sampler)
120201fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke{
120301fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke   this->result = orig_val;
120401fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke
1205d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->type == glsl_type::float_type) {
1206d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* Ignore DEPTH_TEXTURE_MODE swizzling. */
1207d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(ir->sampler->type->sampler_shadow);
120801fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke   } else if (c->key.tex_swizzles[sampler] != SWIZZLE_NOOP) {
120901fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke      fs_reg swizzled_result = fs_reg(this, glsl_type::vec4_type);
1210d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1211d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (int i = 0; i < 4; i++) {
121201fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke	 int swiz = GET_SWZ(c->key.tex_swizzles[sampler], i);
121301fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke	 fs_reg l = swizzled_result;
1214d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 l.reg_offset += i;
1215d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1216d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 if (swiz == SWIZZLE_ZERO) {
1217d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    emit(BRW_OPCODE_MOV, l, fs_reg(0.0f));
1218d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 } else if (swiz == SWIZZLE_ONE) {
1219d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    emit(BRW_OPCODE_MOV, l, fs_reg(1.0f));
1220d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 } else {
122101fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke	    fs_reg r = orig_val;
122201fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke	    r.reg_offset += GET_SWZ(c->key.tex_swizzles[sampler], i);
1223d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    emit(BRW_OPCODE_MOV, l, r);
1224d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 }
1225d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
122601fa9addf447120e994415ad8fc8246ac234ec27Kenneth Graunke      this->result = swizzled_result;
1227d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1228d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1229d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1230d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1231d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_swizzle *ir)
1232d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1233d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir->val->accept(this);
1234d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg val = this->result;
1235d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1236d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->type->vector_elements == 1) {
1237d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->result.reg_offset += ir->mask.x;
1238d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      return;
1239d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1240d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1241d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg result = fs_reg(this, ir->type);
1242d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->result = result;
1243d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1244d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   for (unsigned int i = 0; i < ir->type->vector_elements; i++) {
1245d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_reg channel = val;
1246d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      int swiz = 0;
1247d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1248d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      switch (i) {
1249d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case 0:
1250d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 swiz = ir->mask.x;
1251d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1252d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case 1:
1253d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 swiz = ir->mask.y;
1254d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1255d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case 2:
1256d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 swiz = ir->mask.z;
1257d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1258d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case 3:
1259d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 swiz = ir->mask.w;
1260d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1261d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1262d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1263d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      channel.reg_offset += swiz;
1264d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, result, channel);
1265d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      result.reg_offset++;
1266d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1267d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1268d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1269d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1270d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_discard *ir)
1271d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1272d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   assert(ir->condition == NULL); /* FINISHME */
1273d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1274d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(FS_OPCODE_DISCARD);
1275d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   kill_emitted = true;
1276d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1277d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1278d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1279d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_constant *ir)
1280d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1281d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Set this->result to reg at the bottom of the function because some code
1282d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * paths will cause this visitor to be applied to other fields.  This will
1283d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * cause the value stored in this->result to be modified.
1284d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    *
1285d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * Make reg constant so that it doesn't get accidentally modified along the
1286d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * way.  Yes, I actually had this problem. :(
1287d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    */
1288d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   const fs_reg reg(this, ir->type);
1289d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg dst_reg = reg;
1290d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1291d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->type->is_array()) {
1292d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      const unsigned size = type_size(ir->type->fields.array);
1293d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1294d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (unsigned i = 0; i < ir->type->length; i++) {
1295d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 ir->array_elements[i]->accept(this);
1296d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 fs_reg src_reg = this->result;
1297d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1298d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 dst_reg.type = src_reg.type;
1299d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 for (unsigned j = 0; j < size; j++) {
1300d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    emit(BRW_OPCODE_MOV, dst_reg, src_reg);
1301d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    src_reg.reg_offset++;
1302d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    dst_reg.reg_offset++;
1303d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 }
1304d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1305d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else if (ir->type->is_record()) {
1306d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      foreach_list(node, &ir->components) {
1307d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 ir_instruction *const field = (ir_instruction *) node;
1308d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 const unsigned size = type_size(field->type);
1309d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1310d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 field->accept(this);
1311d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 fs_reg src_reg = this->result;
1312d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1313d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 dst_reg.type = src_reg.type;
1314d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 for (unsigned j = 0; j < size; j++) {
1315d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    emit(BRW_OPCODE_MOV, dst_reg, src_reg);
1316d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    src_reg.reg_offset++;
1317d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    dst_reg.reg_offset++;
1318d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 }
1319d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1320d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else {
1321d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      const unsigned size = type_size(ir->type);
1322d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1323d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (unsigned i = 0; i < size; i++) {
1324d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 switch (ir->type->base_type) {
1325d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 case GLSL_TYPE_FLOAT:
1326d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    emit(BRW_OPCODE_MOV, dst_reg, fs_reg(ir->value.f[i]));
1327d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    break;
1328d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 case GLSL_TYPE_UINT:
1329d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    emit(BRW_OPCODE_MOV, dst_reg, fs_reg(ir->value.u[i]));
1330d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    break;
1331d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 case GLSL_TYPE_INT:
1332d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    emit(BRW_OPCODE_MOV, dst_reg, fs_reg(ir->value.i[i]));
1333d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    break;
1334d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 case GLSL_TYPE_BOOL:
1335d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    emit(BRW_OPCODE_MOV, dst_reg, fs_reg((int)ir->value.b[i]));
1336d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    break;
1337d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 default:
1338d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    assert(!"Non-float/uint/int/bool constant");
1339d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 }
1340d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 dst_reg.reg_offset++;
1341d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1342d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1343d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1344d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->result = reg;
1345d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1346d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1347d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1348d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_bool_to_cond_code(ir_rvalue *ir)
1349d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1350d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir_expression *expr = ir->as_expression();
1351d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1352d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (expr) {
1353d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_reg op[2];
1354d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_inst *inst;
1355d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1356d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(expr->get_num_operands() <= 2);
1357d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (unsigned int i = 0; i < expr->get_num_operands(); i++) {
1358d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 assert(expr->operands[i]->type->is_scalar());
1359d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1360d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 expr->operands[i]->accept(this);
1361d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 op[i] = this->result;
1362d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1363d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1364d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      switch (expr->operation) {
1365d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_unop_logic_not:
1366d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_AND, reg_null_d, op[0], fs_reg(1));
1367d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_Z;
1368d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1369d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1370d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_logic_xor:
1371d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_XOR, reg_null_d, op[0], op[1]);
1372d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_NZ;
1373d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1374d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1375d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_logic_or:
1376d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_OR, reg_null_d, op[0], op[1]);
1377d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_NZ;
1378d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1379d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1380d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_logic_and:
1381d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_AND, reg_null_d, op[0], op[1]);
1382d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_NZ;
1383d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1384d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1385d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_unop_f2b:
1386d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 if (intel->gen >= 6) {
1387d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    inst = emit(BRW_OPCODE_CMP, reg_null_d, op[0], fs_reg(0.0f));
1388d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 } else {
1389d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    inst = emit(BRW_OPCODE_MOV, reg_null_f, op[0]);
1390d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 }
1391d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_NZ;
1392d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1393d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1394d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_unop_i2b:
1395d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 if (intel->gen >= 6) {
1396d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    inst = emit(BRW_OPCODE_CMP, reg_null_d, op[0], fs_reg(0));
1397d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 } else {
1398d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    inst = emit(BRW_OPCODE_MOV, reg_null_d, op[0]);
1399d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 }
1400d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_NZ;
1401d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1402d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1403d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_greater:
1404d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_gequal:
1405d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_less:
1406d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_lequal:
1407d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_equal:
1408d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_all_equal:
1409d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_nequal:
1410d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_any_nequal:
1411d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_CMP, reg_null_cmp, op[0], op[1]);
1412d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod =
1413d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    brw_conditional_for_comparison(expr->operation);
1414d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1415d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1416d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      default:
1417d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 assert(!"not reached");
1418d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 fail("bad cond code\n");
1419d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 break;
1420d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1421d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      return;
1422d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1423d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1424d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir->accept(this);
1425d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1426d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (intel->gen >= 6) {
1427d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_inst *inst = emit(BRW_OPCODE_AND, reg_null_d, this->result, fs_reg(1));
1428d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->conditional_mod = BRW_CONDITIONAL_NZ;
1429d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else {
1430d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_inst *inst = emit(BRW_OPCODE_MOV, reg_null_d, this->result);
1431d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->conditional_mod = BRW_CONDITIONAL_NZ;
1432d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1433d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1434d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1435d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/**
1436d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * Emit a gen6 IF statement with the comparison folded into the IF
1437d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * instruction.
1438d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */
1439d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1440d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_if_gen6(ir_if *ir)
1441d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1442d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir_expression *expr = ir->condition->as_expression();
1443d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1444d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (expr) {
1445d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_reg op[2];
1446d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_inst *inst;
1447d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_reg temp;
1448d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1449d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(expr->get_num_operands() <= 2);
1450d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      for (unsigned int i = 0; i < expr->get_num_operands(); i++) {
1451d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 assert(expr->operands[i]->type->is_scalar());
1452d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1453d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 expr->operands[i]->accept(this);
1454d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 op[i] = this->result;
1455d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1456d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1457d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      switch (expr->operation) {
1458d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_unop_logic_not:
1459d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_IF, temp, op[0], fs_reg(0));
1460d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_Z;
1461d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 return;
1462d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1463d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_logic_xor:
1464d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_IF, reg_null_d, op[0], op[1]);
1465d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_NZ;
1466d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 return;
1467d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1468d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_logic_or:
1469d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 temp = fs_reg(this, glsl_type::bool_type);
1470d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 emit(BRW_OPCODE_OR, temp, op[0], op[1]);
1471d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_IF, reg_null_d, temp, fs_reg(0));
1472d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_NZ;
1473d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 return;
1474d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1475d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_logic_and:
1476d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 temp = fs_reg(this, glsl_type::bool_type);
1477d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 emit(BRW_OPCODE_AND, temp, op[0], op[1]);
1478d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_IF, reg_null_d, temp, fs_reg(0));
1479d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_NZ;
1480d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 return;
1481d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1482d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_unop_f2b:
1483d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_IF, reg_null_f, op[0], fs_reg(0));
1484d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_NZ;
1485d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 return;
1486d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1487d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_unop_i2b:
1488d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_IF, reg_null_d, op[0], fs_reg(0));
1489d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_NZ;
1490d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 return;
1491d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1492d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_greater:
1493d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_gequal:
1494d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_less:
1495d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_lequal:
1496d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_equal:
1497d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_all_equal:
1498d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_nequal:
1499d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      case ir_binop_any_nequal:
1500d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_IF, reg_null_d, op[0], op[1]);
1501d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod =
1502d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    brw_conditional_for_comparison(expr->operation);
1503d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 return;
1504d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      default:
1505d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 assert(!"not reached");
1506d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst = emit(BRW_OPCODE_IF, reg_null_d, op[0], fs_reg(0));
1507d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->conditional_mod = BRW_CONDITIONAL_NZ;
1508d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 fail("bad condition\n");
1509d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 return;
1510d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1511d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      return;
1512d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1513d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1514d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   ir->condition->accept(this);
1515d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1516d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *inst = emit(BRW_OPCODE_IF, reg_null_d, this->result, fs_reg(0));
1517d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   inst->conditional_mod = BRW_CONDITIONAL_NZ;
1518d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1519d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1520d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1521d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_if *ir)
1522d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1523d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *inst;
1524d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
152579cba4c2b17456e2b25ac555c45e1c106b4e3f6bKenneth Graunke   if (intel->gen < 6 && c->dispatch_width == 16) {
1526d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fail("Can't support (non-uniform) control flow on 16-wide\n");
1527d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1528d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1529d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Don't point the annotation at the if statement, because then it plus
1530d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * the then and else blocks get printed.
1531d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    */
1532d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->base_ir = ir->condition;
1533d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1534d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (intel->gen == 6) {
1535d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit_if_gen6(ir);
1536d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else {
1537d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit_bool_to_cond_code(ir->condition);
1538d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1539d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_IF);
1540d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->predicated = true;
1541d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1542d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
154344ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt   foreach_list(node, &ir->then_instructions) {
154444ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt      ir_instruction *ir = (ir_instruction *)node;
1545d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->base_ir = ir;
1546d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke
1547d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->accept(this);
1548d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1549d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1550d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (!ir->else_instructions.is_empty()) {
1551d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_ELSE);
1552d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
155344ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt      foreach_list(node, &ir->else_instructions) {
155444ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt	 ir_instruction *ir = (ir_instruction *)node;
1555d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 this->base_ir = ir;
1556d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke
1557d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 ir->accept(this);
1558d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1559d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1560d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1561d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_ENDIF);
1562d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1563d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1564d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1565d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_loop *ir)
1566d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1567d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg counter = reg_undef;
1568d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1569d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (c->dispatch_width == 16) {
1570d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fail("Can't support (non-uniform) control flow on 16-wide\n");
1571d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1572d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1573d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->counter) {
1574d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->base_ir = ir->counter;
1575d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->counter->accept(this);
1576d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      counter = *(variable_storage(ir->counter));
1577d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1578d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (ir->from) {
1579d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 this->base_ir = ir->from;
1580d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 ir->from->accept(this);
1581d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1582d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke	 emit(BRW_OPCODE_MOV, counter, this->result);
1583d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1584d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1585d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1586d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_DO);
1587d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1588d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->to) {
1589d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->base_ir = ir->to;
1590d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->to->accept(this);
1591d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1592d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_inst *inst = emit(BRW_OPCODE_CMP, reg_null_cmp, counter, this->result);
1593d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->conditional_mod = brw_conditional_for_comparison(ir->cmp);
1594d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1595d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst = emit(BRW_OPCODE_BREAK);
1596d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->predicated = true;
1597d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1598d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
159944ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt   foreach_list(node, &ir->body_instructions) {
160044ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt      ir_instruction *ir = (ir_instruction *)node;
1601d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1602d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->base_ir = ir;
1603d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->accept(this);
1604d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1605d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1606d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (ir->increment) {
1607d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->base_ir = ir->increment;
1608d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      ir->increment->accept(this);
1609d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_ADD, counter, counter, this->result);
1610d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1611d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1612d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_WHILE);
1613d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1614d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1615d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1616d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_loop_jump *ir)
1617d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1618d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   switch (ir->mode) {
1619d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_loop_jump::jump_break:
1620d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_BREAK);
1621d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
1622d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   case ir_loop_jump::jump_continue:
1623d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_CONTINUE);
1624d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      break;
1625d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1626d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1627d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1628d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1629d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_call *ir)
1630d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1631d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   assert(!"FINISHME");
1632d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1633d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1634d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1635d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_return *ir)
1636d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1637d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   assert(!"FINISHME");
1638d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1639d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1640d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1641d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_function *ir)
1642d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1643d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Ignore function bodies other than main() -- we shouldn't see calls to
1644d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * them since they should all be inlined before we get to ir_to_mesa.
1645d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    */
1646d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (strcmp(ir->name, "main") == 0) {
1647d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      const ir_function_signature *sig;
1648d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      exec_list empty;
1649d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1650d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      sig = ir->matching_signature(&empty);
1651d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1652d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      assert(sig);
1653d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
165444ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt      foreach_list(node, &sig->body) {
165544ffb4ae207e48f78fae55925601b8708ed09c1dEric Anholt	 ir_instruction *ir = (ir_instruction *)node;
1656d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 this->base_ir = ir;
1657d28a3bd4bf25157aff5379a003bbf4a66157ed06Kenneth Graunke
1658d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 ir->accept(this);
1659d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1660d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1661d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1662d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1663d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1664d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::visit(ir_function_signature *ir)
1665d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1666d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   assert(!"not reached");
1667d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   (void)ir;
1668d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1669d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1670d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_inst *
1671d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit(fs_inst inst)
1672d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1673d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *list_inst = new(mem_ctx) fs_inst;
1674d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   *list_inst = inst;
1675d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1676d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (force_uncompressed_stack > 0)
1677d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      list_inst->force_uncompressed = true;
1678d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   else if (force_sechalf_stack > 0)
1679d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      list_inst->force_sechalf = true;
1680d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1681d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   list_inst->annotation = this->current_annotation;
1682d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   list_inst->ir = this->base_ir;
1683d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1684d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->instructions.push_tail(list_inst);
1685d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1686d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   return list_inst;
1687d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1688d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1689d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/** Emits a dummy fragment shader consisting of magenta for bringup purposes. */
1690d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1691d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_dummy_fs()
1692d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1693d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Everyone's favorite color. */
1694d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_MOV, fs_reg(MRF, 2), fs_reg(1.0f));
1695d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_MOV, fs_reg(MRF, 3), fs_reg(0.0f));
1696d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_MOV, fs_reg(MRF, 4), fs_reg(1.0f));
1697d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_MOV, fs_reg(MRF, 5), fs_reg(0.0f));
1698d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1699d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_inst *write;
1700d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   write = emit(FS_OPCODE_FB_WRITE, fs_reg(0), fs_reg(0));
17016750226e6d915742ebf96bae2cfcdd287b85db35Ben Widawsky   write->base_mrf = 2;
1702d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1703d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1704d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/* The register location here is relative to the start of the URB
1705d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * data.  It will get adjusted to be a real location before
1706d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt * generate_code() time.
1707d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt */
1708d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtstruct brw_reg
1709d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::interp_reg(int location, int channel)
1710d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1711d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int regnr = urb_setup[location] * 2 + channel / 2;
1712d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int stride = (channel & 1) * 4;
1713d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1714d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   assert(urb_setup[location] != -1);
1715d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1716d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   return brw_vec1_grf(regnr, stride);
1717d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1718d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1719d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/** Emits the interpolation for the varying inputs. */
1720d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1721d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_interpolation_setup_gen4()
1722d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1723d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->current_annotation = "compute pixel centers";
1724d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->pixel_x = fs_reg(this, glsl_type::uint_type);
1725d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->pixel_y = fs_reg(this, glsl_type::uint_type);
1726d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->pixel_x.type = BRW_REGISTER_TYPE_UW;
1727d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->pixel_y.type = BRW_REGISTER_TYPE_UW;
1728d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1729d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(FS_OPCODE_PIXEL_X, this->pixel_x);
1730d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(FS_OPCODE_PIXEL_Y, this->pixel_y);
1731d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1732d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->current_annotation = "compute pixel deltas from v0";
1733d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (brw->has_pln) {
1734d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->delta_x = fs_reg(this, glsl_type::vec2_type);
1735d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->delta_y = this->delta_x;
1736d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->delta_y.reg_offset++;
1737d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else {
1738d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->delta_x = fs_reg(this, glsl_type::float_type);
1739d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->delta_y = fs_reg(this, glsl_type::float_type);
1740d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1741d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_ADD, this->delta_x,
1742d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	this->pixel_x, fs_reg(negate(brw_vec1_grf(1, 0))));
1743d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_ADD, this->delta_y,
1744d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	this->pixel_y, fs_reg(negate(brw_vec1_grf(1, 1))));
1745d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1746d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->current_annotation = "compute pos.w and 1/pos.w";
1747d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Compute wpos.w.  It's always in our setup, since it's needed to
1748d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * interpolate the other attributes.
1749d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    */
1750d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->wpos_w = fs_reg(this, glsl_type::float_type);
1751d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(FS_OPCODE_LINTERP, wpos_w, this->delta_x, this->delta_y,
1752d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	interp_reg(FRAG_ATTRIB_WPOS, 3));
1753d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Compute the pixel 1/W value from wpos.w. */
1754d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->pixel_w = fs_reg(this, glsl_type::float_type);
175565b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt   emit_math(SHADER_OPCODE_RCP, this->pixel_w, wpos_w);
1756d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->current_annotation = NULL;
1757d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1758d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1759d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt/** Emits the interpolation for the varying inputs. */
1760d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1761d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_interpolation_setup_gen6()
1762d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1763d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   struct brw_reg g1_uw = retype(brw_vec1_grf(1, 0), BRW_REGISTER_TYPE_UW);
1764d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1765d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* If the pixel centers end up used, the setup is the same as for gen4. */
1766d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->current_annotation = "compute pixel centers";
1767d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg int_pixel_x = fs_reg(this, glsl_type::uint_type);
1768d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg int_pixel_y = fs_reg(this, glsl_type::uint_type);
1769d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int_pixel_x.type = BRW_REGISTER_TYPE_UW;
1770d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int_pixel_y.type = BRW_REGISTER_TYPE_UW;
1771d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_ADD,
1772d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	int_pixel_x,
1773d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	fs_reg(stride(suboffset(g1_uw, 4), 2, 4, 0)),
1774d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	fs_reg(brw_imm_v(0x10101010)));
1775d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_ADD,
1776d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	int_pixel_y,
1777d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	fs_reg(stride(suboffset(g1_uw, 5), 2, 4, 0)),
1778d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	fs_reg(brw_imm_v(0x11001100)));
1779d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1780d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* As of gen6, we can no longer mix float and int sources.  We have
1781d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * to turn the integer pixel centers into floats for their actual
1782d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    * use.
1783d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt    */
1784d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->pixel_x = fs_reg(this, glsl_type::float_type);
1785d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->pixel_y = fs_reg(this, glsl_type::float_type);
1786d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_MOV, this->pixel_x, int_pixel_x);
1787d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   emit(BRW_OPCODE_MOV, this->pixel_y, int_pixel_y);
1788d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1789d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->current_annotation = "compute pos.w";
1790d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->pixel_w = fs_reg(brw_vec8_grf(c->source_w_reg, 0));
1791d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->wpos_w = fs_reg(this, glsl_type::float_type);
179265b5cbbcf783f6c668ab5b31a0734680dd396794Eric Anholt   emit_math(SHADER_OPCODE_RCP, this->wpos_w, this->pixel_w);
1793d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1794d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->delta_x = fs_reg(brw_vec8_grf(2, 0));
1795d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->delta_y = fs_reg(brw_vec8_grf(3, 0));
1796d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1797d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->current_annotation = NULL;
1798d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1799d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1800d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1801d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_color_write(int index, int first_color_mrf, fs_reg color)
1802d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1803d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int reg_width = c->dispatch_width / 8;
18044fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt   fs_inst *inst;
1805d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1806d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (c->dispatch_width == 8 || intel->gen == 6) {
1807d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* SIMD8 write looks like:
1808d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 0: r0
1809d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 1: r1
1810d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 2: g0
1811d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 3: g1
1812d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       *
1813d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * gen6 SIMD16 DP write looks like:
1814d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 0: r0
1815d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 1: r1
1816d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 2: g0
1817d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 3: g1
1818d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 4: b0
1819d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 5: b1
1820d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 6: a0
1821d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 7: a1
1822d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       */
18234fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt      inst = emit(BRW_OPCODE_MOV,
18244fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt		  fs_reg(MRF, first_color_mrf + index * reg_width),
18254fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt		  color);
18264fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt      inst->saturate = c->key.clamp_fragment_color;
1827d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   } else {
1828d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      /* pre-gen6 SIMD16 single source DP write looks like:
1829d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 0: r0
1830d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 1: g0
1831d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 2: b0
1832d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 3: a0
1833d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 4: r1
1834d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 5: g1
1835d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 6: b1
1836d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       * m + 7: a1
1837d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       */
1838d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (brw->has_compr4) {
1839d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 /* By setting the high bit of the MRF register number, we
1840d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  * indicate that we want COMPR4 mode - instead of doing the
1841d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  * usual destination + 1 for the second half we get
1842d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  * destination + 4.
1843d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  */
18444fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt	 inst = emit(BRW_OPCODE_MOV,
18454fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt		     fs_reg(MRF, BRW_MRF_COMPR4 + first_color_mrf + index),
18464fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt		     color);
18474fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt	 inst->saturate = c->key.clamp_fragment_color;
1848d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      } else {
1849d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 push_force_uncompressed();
18504fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt	 inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, first_color_mrf + index),
18514fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt		     color);
18524fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt	 inst->saturate = c->key.clamp_fragment_color;
1853d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 pop_force_uncompressed();
1854d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1855d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 push_force_sechalf();
1856d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 color.sechalf = true;
18574fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt	 inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, first_color_mrf + index + 4),
18584fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt		     color);
18594fdd289805d14d4f7a234f88cd375be1b3b96764Eric Anholt	 inst->saturate = c->key.clamp_fragment_color;
1860d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 pop_force_sechalf();
1861d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 color.sechalf = false;
1862d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1863d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1864d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1865d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1866d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtvoid
1867d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholtfs_visitor::emit_fb_writes()
1868d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt{
1869d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->current_annotation = "FB write header";
1870d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   GLboolean header_present = GL_TRUE;
1871eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke   int base_mrf = 2;
1872eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke   int nr = base_mrf;
1873d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int reg_width = c->dispatch_width / 8;
1874d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1875d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (intel->gen >= 6 &&
1876d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       !this->kill_emitted &&
1877d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt       c->key.nr_color_regions == 1) {
1878d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      header_present = false;
1879d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1880d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1881d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (header_present) {
18826750226e6d915742ebf96bae2cfcdd287b85db35Ben Widawsky      /* m2, m3 header */
1883d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      nr += 2;
1884d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1885d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1886d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (c->aa_dest_stencil_reg) {
1887d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      push_force_uncompressed();
1888d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, fs_reg(MRF, nr++),
1889d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	   fs_reg(brw_vec8_grf(c->aa_dest_stencil_reg, 0)));
1890d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      pop_force_uncompressed();
1891d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1892d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1893d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   /* Reserve space for color. It'll be filled in per MRT below. */
1894d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   int color_mrf = nr;
1895d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   nr += 4 * reg_width;
1896d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1897d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (c->source_depth_to_render_target) {
1898d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (intel->gen == 6 && c->dispatch_width == 16) {
1899d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 /* For outputting oDepth on gen6, SIMD8 writes have to be
1900d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  * used.  This would require 8-wide moves of each half to
1901d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  * message regs, kind of like pre-gen5 SIMD16 FB writes.
1902d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  * Just bail on doing so for now.
1903d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  */
1904d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 fail("Missing support for simd16 depth writes on gen6\n");
1905d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1906d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1907d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (c->computes_depth) {
1908d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 /* Hand over gl_FragDepth. */
1909d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 assert(this->frag_depth);
1910d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 fs_reg depth = *(variable_storage(this->frag_depth));
1911d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1912d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 emit(BRW_OPCODE_MOV, fs_reg(MRF, nr), depth);
1913d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      } else {
1914d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 /* Pass through the payload depth. */
1915d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 emit(BRW_OPCODE_MOV, fs_reg(MRF, nr),
1916d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	      fs_reg(brw_vec8_grf(c->source_depth_reg, 0)));
1917d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1918d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      nr += reg_width;
1919d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1920d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1921d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (c->dest_depth_reg) {
1922d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      emit(BRW_OPCODE_MOV, fs_reg(MRF, nr),
1923d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	   fs_reg(brw_vec8_grf(c->dest_depth_reg, 0)));
1924d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      nr += reg_width;
1925d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1926d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1927d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   fs_reg color = reg_undef;
1928d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (this->frag_color)
1929d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      color = *(variable_storage(this->frag_color));
1930d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   else if (this->frag_data) {
1931d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      color = *(variable_storage(this->frag_data));
1932d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      color.type = BRW_REGISTER_TYPE_F;
1933d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1934d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1935d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   for (int target = 0; target < c->key.nr_color_regions; target++) {
1936d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      this->current_annotation = ralloc_asprintf(this->mem_ctx,
1937d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt						 "FB write target %d",
1938d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt						 target);
1939d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (this->frag_color || this->frag_data) {
1940d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 for (int i = 0; i < 4; i++) {
1941d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    emit_color_write(i, color_mrf, color);
1942d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	    color.reg_offset++;
1943d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 }
1944d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1945d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1946d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (this->frag_color)
1947d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 color.reg_offset -= 4;
1948d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1949d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_inst *inst = emit(FS_OPCODE_FB_WRITE);
1950d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->target = target;
1951eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke      inst->base_mrf = base_mrf;
1952eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke      inst->mlen = nr - base_mrf;
1953d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (target == c->key.nr_color_regions - 1)
1954d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 inst->eot = true;
1955d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->header_present = header_present;
1956d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1957d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1958d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   if (c->key.nr_color_regions == 0) {
1959d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      if (c->key.alpha_test && (this->frag_color || this->frag_data)) {
1960d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 /* If the alpha test is enabled but there's no color buffer,
1961d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  * we still need to send alpha out the pipeline to our null
1962d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  * renderbuffer.
1963d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	  */
1964d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 color.reg_offset += 3;
1965d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt	 emit_color_write(3, color_mrf, color);
1966d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      }
1967d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1968d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      fs_inst *inst = emit(FS_OPCODE_FB_WRITE);
1969eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke      inst->base_mrf = base_mrf;
1970eafc74d7d4982a835ac43c73963dda9982652464Kenneth Graunke      inst->mlen = nr - base_mrf;
1971d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->eot = true;
1972d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt      inst->header_present = header_present;
1973d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   }
1974d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt
1975d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt   this->current_annotation = NULL;
1976d1f70a8a6c6ec7007bad22d3d6013415be2d243aEric Anholt}
1977