mesa: Add .gitignore entries for make check binaries
[mesa.git] / src / mesa / drivers / dri / i965 / brw_ir_fs.h
1 /* -*- c++ -*- */
2 /*
3 * Copyright © 2010-2015 Intel Corporation
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 */
24
25 #ifndef BRW_IR_FS_H
26 #define BRW_IR_FS_H
27
28 #include "brw_shader.h"
29
30 class fs_inst;
31
32 class fs_reg : public backend_reg {
33 public:
34 DECLARE_RALLOC_CXX_OPERATORS(fs_reg)
35
36 void init();
37
38 fs_reg();
39 fs_reg(struct ::brw_reg reg);
40 fs_reg(enum brw_reg_file file, int nr);
41 fs_reg(enum brw_reg_file file, int nr, enum brw_reg_type type);
42
43 bool equals(const fs_reg &r) const;
44 bool is_contiguous() const;
45
46 /**
47 * Return the size in bytes of a single logical component of the
48 * register assuming the given execution width.
49 */
50 unsigned component_size(unsigned width) const;
51
52 /** Smear a channel of the reg to all channels. */
53 fs_reg &set_smear(unsigned subreg);
54
55 /**
56 * Offset in bytes from the start of the register. Values up to a
57 * backend_reg::reg_offset unit are valid.
58 */
59 int subreg_offset;
60
61 /** Register region horizontal stride */
62 uint8_t stride;
63 };
64
65 static inline fs_reg
66 negate(fs_reg reg)
67 {
68 assert(reg.file != IMM);
69 reg.negate = !reg.negate;
70 return reg;
71 }
72
73 static inline fs_reg
74 retype(fs_reg reg, enum brw_reg_type type)
75 {
76 reg.type = type;
77 return reg;
78 }
79
80 static inline fs_reg
81 byte_offset(fs_reg reg, unsigned delta)
82 {
83 reg.subreg_offset += delta;
84
85 switch (reg.file) {
86 case BAD_FILE:
87 break;
88 case VGRF:
89 case ATTR:
90 reg.reg_offset += reg.subreg_offset / 32;
91 break;
92 case MRF:
93 reg.nr += delta / 32;
94 break;
95 case UNIFORM:
96 reg.reg_offset += reg.subreg_offset / 4;
97 reg.subreg_offset %= 4;
98 return reg;
99 case ARF:
100 case FIXED_GRF:
101 case IMM:
102 default:
103 assert(delta == 0);
104 }
105 reg.subreg_offset %= 32;
106 return reg;
107 }
108
109 static inline fs_reg
110 horiz_offset(fs_reg reg, unsigned delta)
111 {
112 switch (reg.file) {
113 case BAD_FILE:
114 case UNIFORM:
115 case IMM:
116 /* These only have a single component that is implicitly splatted. A
117 * horizontal offset should be a harmless no-op.
118 */
119 break;
120 case VGRF:
121 case MRF:
122 case ATTR:
123 return byte_offset(reg, delta * reg.stride * type_sz(reg.type));
124 case ARF:
125 case FIXED_GRF:
126 assert(delta == 0);
127 }
128 return reg;
129 }
130
131 /**
132 * Get the scalar channel of \p reg given by \p idx and replicate it to all
133 * channels of the result.
134 */
135 static inline fs_reg
136 component(fs_reg reg, unsigned idx)
137 {
138 reg = horiz_offset(reg, idx);
139 reg.stride = 0;
140 return reg;
141 }
142
143 static inline bool
144 is_uniform(const fs_reg &reg)
145 {
146 return (reg.stride == 0 || reg.is_null());
147 }
148
149 /**
150 * Get either of the 8-component halves of a 16-component register.
151 *
152 * Note: this also works if \c reg represents a SIMD16 pair of registers.
153 */
154 static inline fs_reg
155 half(fs_reg reg, unsigned idx)
156 {
157 assert(idx < 2);
158
159 switch (reg.file) {
160 case BAD_FILE:
161 case UNIFORM:
162 case IMM:
163 return reg;
164
165 case VGRF:
166 case MRF:
167 return horiz_offset(reg, 8 * idx);
168
169 case ARF:
170 case FIXED_GRF:
171 case ATTR:
172 unreachable("Cannot take half of this register type");
173 }
174 return reg;
175 }
176
177 /**
178 * Reinterpret each channel of register \p reg as a vector of values of the
179 * given smaller type and take the i-th subcomponent from each.
180 */
181 static inline fs_reg
182 subscript(fs_reg reg, brw_reg_type type, unsigned i)
183 {
184 assert((i + 1) * type_sz(type) <= type_sz(reg.type));
185
186 if (reg.file == ARF || reg.file == FIXED_GRF) {
187 /* The stride is encoded inconsistently for fixed GRF and ARF registers
188 * as the log2 of the actual vertical and horizontal strides.
189 */
190 const int delta = _mesa_logbase2(type_sz(reg.type)) -
191 _mesa_logbase2(type_sz(type));
192 reg.hstride += (reg.hstride ? delta : 0);
193 reg.vstride += (reg.vstride ? delta : 0);
194
195 } else if (reg.file == IMM) {
196 assert(reg.type == type);
197
198 } else {
199 reg.stride *= type_sz(reg.type) / type_sz(type);
200 }
201
202 return byte_offset(retype(reg, type), i * type_sz(type));
203 }
204
205 static const fs_reg reg_undef;
206
207 class fs_inst : public backend_instruction {
208 fs_inst &operator=(const fs_inst &);
209
210 void init(enum opcode opcode, uint8_t exec_width, const fs_reg &dst,
211 const fs_reg *src, unsigned sources);
212
213 public:
214 DECLARE_RALLOC_CXX_OPERATORS(fs_inst)
215
216 fs_inst();
217 fs_inst(enum opcode opcode, uint8_t exec_size);
218 fs_inst(enum opcode opcode, uint8_t exec_size, const fs_reg &dst);
219 fs_inst(enum opcode opcode, uint8_t exec_size, const fs_reg &dst,
220 const fs_reg &src0);
221 fs_inst(enum opcode opcode, uint8_t exec_size, const fs_reg &dst,
222 const fs_reg &src0, const fs_reg &src1);
223 fs_inst(enum opcode opcode, uint8_t exec_size, const fs_reg &dst,
224 const fs_reg &src0, const fs_reg &src1, const fs_reg &src2);
225 fs_inst(enum opcode opcode, uint8_t exec_size, const fs_reg &dst,
226 const fs_reg src[], unsigned sources);
227 fs_inst(const fs_inst &that);
228 ~fs_inst();
229
230 void resize_sources(uint8_t num_sources);
231
232 bool equals(fs_inst *inst) const;
233 bool overwrites_reg(const fs_reg &reg) const;
234 bool is_send_from_grf() const;
235 bool is_partial_write() const;
236 bool is_copy_payload(const brw::simple_allocator &grf_alloc) const;
237 unsigned components_read(unsigned i) const;
238 int regs_read(int arg) const;
239 bool can_do_source_mods(const struct brw_device_info *devinfo);
240 bool can_change_types() const;
241 bool has_side_effects() const;
242 bool has_source_and_destination_hazard() const;
243
244 bool reads_flag() const;
245 bool writes_flag() const;
246
247 fs_reg dst;
248 fs_reg *src;
249
250 uint8_t sources; /**< Number of fs_reg sources. */
251
252 /**
253 * Execution size of the instruction. This is used by the generator to
254 * generate the correct binary for the given fs_inst. Current valid
255 * values are 1, 8, 16.
256 */
257 uint8_t exec_size;
258
259 bool eot:1;
260 bool force_sechalf:1;
261 bool pi_noperspective:1; /**< Pixel interpolator noperspective flag */
262 };
263
264 /**
265 * Set second-half quarter control on \p inst.
266 */
267 static inline fs_inst *
268 set_sechalf(fs_inst *inst)
269 {
270 inst->force_sechalf = true;
271 return inst;
272 }
273
274 /**
275 * Make the execution of \p inst dependent on the evaluation of a possibly
276 * inverted predicate.
277 */
278 static inline fs_inst *
279 set_predicate_inv(enum brw_predicate pred, bool inverse,
280 fs_inst *inst)
281 {
282 inst->predicate = pred;
283 inst->predicate_inverse = inverse;
284 return inst;
285 }
286
287 /**
288 * Make the execution of \p inst dependent on the evaluation of a predicate.
289 */
290 static inline fs_inst *
291 set_predicate(enum brw_predicate pred, fs_inst *inst)
292 {
293 return set_predicate_inv(pred, false, inst);
294 }
295
296 /**
297 * Write the result of evaluating the condition given by \p mod to a flag
298 * register.
299 */
300 static inline fs_inst *
301 set_condmod(enum brw_conditional_mod mod, fs_inst *inst)
302 {
303 inst->conditional_mod = mod;
304 return inst;
305 }
306
307 /**
308 * Clamp the result of \p inst to the saturation range of its destination
309 * datatype.
310 */
311 static inline fs_inst *
312 set_saturate(bool saturate, fs_inst *inst)
313 {
314 inst->saturate = saturate;
315 return inst;
316 }
317
318 #endif