i965/nir/vec4: Implement load_const intrinsic
[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 explicit fs_reg(float f);
40 explicit fs_reg(int32_t i);
41 explicit fs_reg(uint32_t u);
42 explicit fs_reg(uint8_t vf[4]);
43 explicit fs_reg(uint8_t vf0, uint8_t vf1, uint8_t vf2, uint8_t vf3);
44 fs_reg(struct brw_reg fixed_hw_reg);
45 fs_reg(enum register_file file, int reg);
46 fs_reg(enum register_file file, int reg, enum brw_reg_type type);
47
48 bool equals(const fs_reg &r) const;
49 bool is_contiguous() const;
50
51 /**
52 * Return the size in bytes of a single logical component of the
53 * register assuming the given execution width.
54 */
55 unsigned component_size(unsigned width) const;
56
57 /** Smear a channel of the reg to all channels. */
58 fs_reg &set_smear(unsigned subreg);
59
60 /**
61 * Offset in bytes from the start of the register. Values up to a
62 * backend_reg::reg_offset unit are valid.
63 */
64 int subreg_offset;
65
66 fs_reg *reladdr;
67
68 /** Register region horizontal stride */
69 uint8_t stride;
70 };
71
72 static inline fs_reg
73 negate(fs_reg reg)
74 {
75 assert(reg.file != HW_REG && reg.file != IMM);
76 reg.negate = !reg.negate;
77 return reg;
78 }
79
80 static inline fs_reg
81 retype(fs_reg reg, enum brw_reg_type type)
82 {
83 reg.fixed_hw_reg.type = reg.type = type;
84 return reg;
85 }
86
87 static inline fs_reg
88 byte_offset(fs_reg reg, unsigned delta)
89 {
90 switch (reg.file) {
91 case BAD_FILE:
92 break;
93 case GRF:
94 case ATTR:
95 reg.reg_offset += delta / 32;
96 break;
97 case MRF:
98 reg.reg += delta / 32;
99 break;
100 default:
101 assert(delta == 0);
102 }
103 reg.subreg_offset += delta % 32;
104 return reg;
105 }
106
107 static inline fs_reg
108 horiz_offset(fs_reg reg, unsigned delta)
109 {
110 switch (reg.file) {
111 case BAD_FILE:
112 case UNIFORM:
113 case IMM:
114 /* These only have a single component that is implicitly splatted. A
115 * horizontal offset should be a harmless no-op.
116 */
117 break;
118 case GRF:
119 case MRF:
120 case ATTR:
121 return byte_offset(reg, delta * reg.stride * type_sz(reg.type));
122 default:
123 assert(delta == 0);
124 }
125 return reg;
126 }
127
128 static inline fs_reg
129 component(fs_reg reg, unsigned idx)
130 {
131 assert(reg.subreg_offset == 0);
132 reg.subreg_offset = idx * type_sz(reg.type);
133 reg.stride = 0;
134 return reg;
135 }
136
137 static inline bool
138 is_uniform(const fs_reg &reg)
139 {
140 return (reg.stride == 0 || reg.is_null()) &&
141 (!reg.reladdr || is_uniform(*reg.reladdr));
142 }
143
144 /**
145 * Get either of the 8-component halves of a 16-component register.
146 *
147 * Note: this also works if \c reg represents a SIMD16 pair of registers.
148 */
149 static inline fs_reg
150 half(fs_reg reg, unsigned idx)
151 {
152 assert(idx < 2);
153
154 switch (reg.file) {
155 case BAD_FILE:
156 case UNIFORM:
157 case IMM:
158 return reg;
159
160 case GRF:
161 case MRF:
162 return horiz_offset(reg, 8 * idx);
163
164 case ATTR:
165 case HW_REG:
166 default:
167 unreachable("Cannot take half of this register type");
168 }
169 return reg;
170 }
171
172 static const fs_reg reg_undef;
173
174 class fs_inst : public backend_instruction {
175 fs_inst &operator=(const fs_inst &);
176
177 void init(enum opcode opcode, uint8_t exec_width, const fs_reg &dst,
178 const fs_reg *src, unsigned sources);
179
180 public:
181 DECLARE_RALLOC_CXX_OPERATORS(fs_inst)
182
183 fs_inst();
184 fs_inst(enum opcode opcode, uint8_t exec_size);
185 fs_inst(enum opcode opcode, uint8_t exec_size, const fs_reg &dst);
186 fs_inst(enum opcode opcode, uint8_t exec_size, const fs_reg &dst,
187 const fs_reg &src0);
188 fs_inst(enum opcode opcode, uint8_t exec_size, const fs_reg &dst,
189 const fs_reg &src0, const fs_reg &src1);
190 fs_inst(enum opcode opcode, uint8_t exec_size, const fs_reg &dst,
191 const fs_reg &src0, const fs_reg &src1, const fs_reg &src2);
192 fs_inst(enum opcode opcode, uint8_t exec_size, const fs_reg &dst,
193 const fs_reg src[], unsigned sources);
194 fs_inst(const fs_inst &that);
195 ~fs_inst();
196
197 void resize_sources(uint8_t num_sources);
198
199 bool equals(fs_inst *inst) const;
200 bool overwrites_reg(const fs_reg &reg) const;
201 bool is_send_from_grf() const;
202 bool is_partial_write() const;
203 bool is_copy_payload(const brw::simple_allocator &grf_alloc) const;
204 unsigned components_read(unsigned i) const;
205 int regs_read(int arg) const;
206 bool can_do_source_mods(const struct brw_device_info *devinfo);
207 bool has_side_effects() const;
208
209 bool reads_flag() const;
210 bool writes_flag() const;
211
212 fs_reg dst;
213 fs_reg *src;
214
215 uint8_t sources; /**< Number of fs_reg sources. */
216
217 /**
218 * Execution size of the instruction. This is used by the generator to
219 * generate the correct binary for the given fs_inst. Current valid
220 * values are 1, 8, 16.
221 */
222 uint8_t exec_size;
223
224 bool eot:1;
225 bool force_sechalf:1;
226 bool pi_noperspective:1; /**< Pixel interpolator noperspective flag */
227 };
228
229 /**
230 * Set second-half quarter control on \p inst.
231 */
232 static inline fs_inst *
233 set_sechalf(fs_inst *inst)
234 {
235 inst->force_sechalf = true;
236 return inst;
237 }
238
239 /**
240 * Make the execution of \p inst dependent on the evaluation of a possibly
241 * inverted predicate.
242 */
243 static inline fs_inst *
244 set_predicate_inv(enum brw_predicate pred, bool inverse,
245 fs_inst *inst)
246 {
247 inst->predicate = pred;
248 inst->predicate_inverse = inverse;
249 return inst;
250 }
251
252 /**
253 * Make the execution of \p inst dependent on the evaluation of a predicate.
254 */
255 static inline fs_inst *
256 set_predicate(enum brw_predicate pred, fs_inst *inst)
257 {
258 return set_predicate_inv(pred, false, inst);
259 }
260
261 /**
262 * Write the result of evaluating the condition given by \p mod to a flag
263 * register.
264 */
265 static inline fs_inst *
266 set_condmod(enum brw_conditional_mod mod, fs_inst *inst)
267 {
268 inst->conditional_mod = mod;
269 return inst;
270 }
271
272 /**
273 * Clamp the result of \p inst to the saturation range of its destination
274 * datatype.
275 */
276 static inline fs_inst *
277 set_saturate(bool saturate, fs_inst *inst)
278 {
279 inst->saturate = saturate;
280 return inst;
281 }
282
283 #endif