d3f0d61b55bc92e99293aff952647e6ed98e0f34
[mesa.git] / src / mesa / drivers / dri / i965 / brw_ir_vec4.h
1 /* -*- c++ -*- */
2 /*
3 * Copyright © 2011-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_VEC4_H
26 #define BRW_IR_VEC4_H
27
28 #include "brw_shader.h"
29 #include "brw_context.h"
30
31 namespace brw {
32
33 class dst_reg;
34
35 class src_reg : public backend_reg
36 {
37 public:
38 DECLARE_RALLOC_CXX_OPERATORS(src_reg)
39
40 void init();
41
42 src_reg(register_file file, int nr, const glsl_type *type);
43 src_reg();
44 src_reg(float f);
45 src_reg(uint32_t u);
46 src_reg(int32_t i);
47 src_reg(uint8_t vf[4]);
48 src_reg(uint8_t vf0, uint8_t vf1, uint8_t vf2, uint8_t vf3);
49 src_reg(struct brw_reg reg);
50
51 bool equals(const src_reg &r) const;
52
53 src_reg(class vec4_visitor *v, const struct glsl_type *type);
54 src_reg(class vec4_visitor *v, const struct glsl_type *type, int size);
55
56 explicit src_reg(const dst_reg &reg);
57
58 src_reg *reladdr;
59 };
60
61 static inline src_reg
62 retype(src_reg reg, enum brw_reg_type type)
63 {
64 reg.type = type;
65 return reg;
66 }
67
68 static inline src_reg
69 offset(src_reg reg, unsigned delta)
70 {
71 assert(delta == 0 || (reg.file != HW_REG && reg.file != IMM));
72 reg.reg_offset += delta;
73 return reg;
74 }
75
76 /**
77 * Reswizzle a given source register.
78 * \sa brw_swizzle().
79 */
80 static inline src_reg
81 swizzle(src_reg reg, unsigned swizzle)
82 {
83 reg.swizzle = brw_compose_swizzle(swizzle, reg.swizzle);
84 return reg;
85 }
86
87 static inline src_reg
88 negate(src_reg reg)
89 {
90 assert(reg.file != IMM);
91 reg.negate = !reg.negate;
92 return reg;
93 }
94
95 static inline bool
96 is_uniform(const src_reg &reg)
97 {
98 return (reg.file == IMM || reg.file == UNIFORM || reg.is_null()) &&
99 (!reg.reladdr || is_uniform(*reg.reladdr));
100 }
101
102 class dst_reg : public backend_reg
103 {
104 public:
105 DECLARE_RALLOC_CXX_OPERATORS(dst_reg)
106
107 void init();
108
109 dst_reg();
110 dst_reg(register_file file, int nr);
111 dst_reg(register_file file, int nr, const glsl_type *type,
112 unsigned writemask);
113 dst_reg(register_file file, int nr, brw_reg_type type,
114 unsigned writemask);
115 dst_reg(struct brw_reg reg);
116 dst_reg(class vec4_visitor *v, const struct glsl_type *type);
117
118 explicit dst_reg(const src_reg &reg);
119
120 bool equals(const dst_reg &r) const;
121
122 src_reg *reladdr;
123 };
124
125 static inline dst_reg
126 retype(dst_reg reg, enum brw_reg_type type)
127 {
128 reg.type = type;
129 return reg;
130 }
131
132 static inline dst_reg
133 offset(dst_reg reg, unsigned delta)
134 {
135 assert(delta == 0 || (reg.file != HW_REG && reg.file != IMM));
136 reg.reg_offset += delta;
137 return reg;
138 }
139
140 static inline dst_reg
141 writemask(dst_reg reg, unsigned mask)
142 {
143 assert(reg.file != IMM);
144 assert((reg.writemask & mask) != 0);
145 reg.writemask &= mask;
146 return reg;
147 }
148
149 class vec4_instruction : public backend_instruction {
150 public:
151 DECLARE_RALLOC_CXX_OPERATORS(vec4_instruction)
152
153 vec4_instruction(enum opcode opcode,
154 const dst_reg &dst = dst_reg(),
155 const src_reg &src0 = src_reg(),
156 const src_reg &src1 = src_reg(),
157 const src_reg &src2 = src_reg());
158
159 dst_reg dst;
160 src_reg src[3];
161
162 enum brw_urb_write_flags urb_write_flags;
163
164 unsigned sol_binding; /**< gen6: SOL binding table index */
165 bool sol_final_write; /**< gen6: send commit message */
166 unsigned sol_vertex; /**< gen6: used for setting dst index in SVB header */
167
168 bool is_send_from_grf();
169 unsigned regs_read(unsigned arg) const;
170 bool can_reswizzle(const struct brw_device_info *devinfo, int dst_writemask,
171 int swizzle, int swizzle_mask);
172 void reswizzle(int dst_writemask, int swizzle);
173 bool can_do_source_mods(const struct brw_device_info *devinfo);
174 bool can_change_types() const;
175
176 bool reads_flag()
177 {
178 return predicate || opcode == VS_OPCODE_UNPACK_FLAGS_SIMD4X2;
179 }
180
181 bool reads_flag(unsigned c)
182 {
183 if (opcode == VS_OPCODE_UNPACK_FLAGS_SIMD4X2)
184 return true;
185
186 switch (predicate) {
187 case BRW_PREDICATE_NONE:
188 return false;
189 case BRW_PREDICATE_ALIGN16_REPLICATE_X:
190 return c == 0;
191 case BRW_PREDICATE_ALIGN16_REPLICATE_Y:
192 return c == 1;
193 case BRW_PREDICATE_ALIGN16_REPLICATE_Z:
194 return c == 2;
195 case BRW_PREDICATE_ALIGN16_REPLICATE_W:
196 return c == 3;
197 default:
198 return true;
199 }
200 }
201
202 bool writes_flag()
203 {
204 return (conditional_mod && (opcode != BRW_OPCODE_SEL &&
205 opcode != BRW_OPCODE_IF &&
206 opcode != BRW_OPCODE_WHILE));
207 }
208 };
209
210 /**
211 * Make the execution of \p inst dependent on the evaluation of a possibly
212 * inverted predicate.
213 */
214 inline vec4_instruction *
215 set_predicate_inv(enum brw_predicate pred, bool inverse,
216 vec4_instruction *inst)
217 {
218 inst->predicate = pred;
219 inst->predicate_inverse = inverse;
220 return inst;
221 }
222
223 /**
224 * Make the execution of \p inst dependent on the evaluation of a predicate.
225 */
226 inline vec4_instruction *
227 set_predicate(enum brw_predicate pred, vec4_instruction *inst)
228 {
229 return set_predicate_inv(pred, false, inst);
230 }
231
232 /**
233 * Write the result of evaluating the condition given by \p mod to a flag
234 * register.
235 */
236 inline vec4_instruction *
237 set_condmod(enum brw_conditional_mod mod, vec4_instruction *inst)
238 {
239 inst->conditional_mod = mod;
240 return inst;
241 }
242
243 /**
244 * Clamp the result of \p inst to the saturation range of its destination
245 * datatype.
246 */
247 inline vec4_instruction *
248 set_saturate(bool saturate, vec4_instruction *inst)
249 {
250 inst->saturate = saturate;
251 return inst;
252 }
253
254 } /* namespace brw */
255
256 #endif