Merge remote-tracking branch 'mesa-public/master' into vulkan
[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 reg, 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 unsigned swizzle; /**< BRW_SWIZZLE_XYZW macros from brw_reg.h. */
59
60 src_reg *reladdr;
61 };
62
63 static inline src_reg
64 retype(src_reg reg, enum brw_reg_type type)
65 {
66 reg.fixed_hw_reg.type = reg.type = type;
67 return reg;
68 }
69
70 static inline src_reg
71 offset(src_reg reg, unsigned delta)
72 {
73 assert(delta == 0 || (reg.file != HW_REG && reg.file != IMM));
74 reg.reg_offset += delta;
75 return reg;
76 }
77
78 /**
79 * Reswizzle a given source register.
80 * \sa brw_swizzle().
81 */
82 static inline src_reg
83 swizzle(src_reg reg, unsigned swizzle)
84 {
85 assert(reg.file != HW_REG);
86 reg.swizzle = brw_compose_swizzle(swizzle, reg.swizzle);
87 return reg;
88 }
89
90 static inline src_reg
91 negate(src_reg reg)
92 {
93 assert(reg.file != HW_REG && reg.file != IMM);
94 reg.negate = !reg.negate;
95 return reg;
96 }
97
98 static inline bool
99 is_uniform(const src_reg &reg)
100 {
101 return (reg.file == IMM || reg.file == UNIFORM || reg.is_null()) &&
102 (!reg.reladdr || is_uniform(*reg.reladdr));
103 }
104
105 class dst_reg : public backend_reg
106 {
107 public:
108 DECLARE_RALLOC_CXX_OPERATORS(dst_reg)
109
110 void init();
111
112 dst_reg();
113 dst_reg(register_file file, int reg);
114 dst_reg(register_file file, int reg, const glsl_type *type,
115 unsigned writemask);
116 dst_reg(register_file file, int reg, brw_reg_type type,
117 unsigned writemask);
118 dst_reg(struct brw_reg reg);
119 dst_reg(class vec4_visitor *v, const struct glsl_type *type);
120
121 explicit dst_reg(const src_reg &reg);
122
123 bool equals(const dst_reg &r) const;
124
125 unsigned writemask; /**< Bitfield of WRITEMASK_[XYZW] */
126
127 src_reg *reladdr;
128 };
129
130 static inline dst_reg
131 retype(dst_reg reg, enum brw_reg_type type)
132 {
133 reg.fixed_hw_reg.type = reg.type = type;
134 return reg;
135 }
136
137 static inline dst_reg
138 offset(dst_reg reg, unsigned delta)
139 {
140 assert(delta == 0 || (reg.file != HW_REG && reg.file != IMM));
141 reg.reg_offset += delta;
142 return reg;
143 }
144
145 static inline dst_reg
146 writemask(dst_reg reg, unsigned mask)
147 {
148 assert(reg.file != HW_REG && reg.file != IMM);
149 assert((reg.writemask & mask) != 0);
150 reg.writemask &= mask;
151 return reg;
152 }
153
154 class vec4_instruction : public backend_instruction {
155 public:
156 DECLARE_RALLOC_CXX_OPERATORS(vec4_instruction)
157
158 vec4_instruction(enum opcode opcode,
159 const dst_reg &dst = dst_reg(),
160 const src_reg &src0 = src_reg(),
161 const src_reg &src1 = src_reg(),
162 const src_reg &src2 = src_reg());
163
164 struct brw_reg get_dst(unsigned gen);
165 struct brw_reg get_src(const struct brw_vue_prog_data *prog_data, int i);
166
167 dst_reg dst;
168 src_reg src[3];
169
170 enum brw_urb_write_flags urb_write_flags;
171
172 unsigned sol_binding; /**< gen6: SOL binding table index */
173 bool sol_final_write; /**< gen6: send commit message */
174 unsigned sol_vertex; /**< gen6: used for setting dst index in SVB header */
175
176 bool is_send_from_grf();
177 unsigned regs_read(unsigned arg) const;
178 bool can_reswizzle(const struct brw_device_info *devinfo, int dst_writemask,
179 int swizzle, int swizzle_mask);
180 void reswizzle(int dst_writemask, int swizzle);
181 bool can_do_source_mods(const struct brw_device_info *devinfo);
182 bool can_change_types() const;
183
184 bool reads_flag()
185 {
186 return predicate || opcode == VS_OPCODE_UNPACK_FLAGS_SIMD4X2;
187 }
188
189 bool writes_flag()
190 {
191 return (conditional_mod && (opcode != BRW_OPCODE_SEL &&
192 opcode != BRW_OPCODE_IF &&
193 opcode != BRW_OPCODE_WHILE));
194 }
195 };
196
197 /**
198 * Make the execution of \p inst dependent on the evaluation of a possibly
199 * inverted predicate.
200 */
201 inline vec4_instruction *
202 set_predicate_inv(enum brw_predicate pred, bool inverse,
203 vec4_instruction *inst)
204 {
205 inst->predicate = pred;
206 inst->predicate_inverse = inverse;
207 return inst;
208 }
209
210 /**
211 * Make the execution of \p inst dependent on the evaluation of a predicate.
212 */
213 inline vec4_instruction *
214 set_predicate(enum brw_predicate pred, vec4_instruction *inst)
215 {
216 return set_predicate_inv(pred, false, inst);
217 }
218
219 /**
220 * Write the result of evaluating the condition given by \p mod to a flag
221 * register.
222 */
223 inline vec4_instruction *
224 set_condmod(enum brw_conditional_mod mod, vec4_instruction *inst)
225 {
226 inst->conditional_mod = mod;
227 return inst;
228 }
229
230 /**
231 * Clamp the result of \p inst to the saturation range of its destination
232 * datatype.
233 */
234 inline vec4_instruction *
235 set_saturate(bool saturate, vec4_instruction *inst)
236 {
237 inst->saturate = saturate;
238 return inst;
239 }
240
241 } /* namespace brw */
242
243 #endif