glsl: Lower UBO and SSBO access in glsl linker
[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 dst_reg dst;
165 src_reg src[3];
166
167 enum brw_urb_write_flags urb_write_flags;
168
169 unsigned sol_binding; /**< gen6: SOL binding table index */
170 bool sol_final_write; /**< gen6: send commit message */
171 unsigned sol_vertex; /**< gen6: used for setting dst index in SVB header */
172
173 bool is_send_from_grf();
174 unsigned regs_read(unsigned arg) const;
175 bool can_reswizzle(const struct brw_device_info *devinfo, int dst_writemask,
176 int swizzle, int swizzle_mask);
177 void reswizzle(int dst_writemask, int swizzle);
178 bool can_do_source_mods(const struct brw_device_info *devinfo);
179 bool can_change_types() const;
180
181 bool reads_flag()
182 {
183 return predicate || opcode == VS_OPCODE_UNPACK_FLAGS_SIMD4X2;
184 }
185
186 bool reads_flag(unsigned c)
187 {
188 if (opcode == VS_OPCODE_UNPACK_FLAGS_SIMD4X2)
189 return true;
190
191 switch (predicate) {
192 case BRW_PREDICATE_NONE:
193 return false;
194 case BRW_PREDICATE_ALIGN16_REPLICATE_X:
195 return c == 0;
196 case BRW_PREDICATE_ALIGN16_REPLICATE_Y:
197 return c == 1;
198 case BRW_PREDICATE_ALIGN16_REPLICATE_Z:
199 return c == 2;
200 case BRW_PREDICATE_ALIGN16_REPLICATE_W:
201 return c == 3;
202 default:
203 return true;
204 }
205 }
206
207 bool writes_flag()
208 {
209 return (conditional_mod && (opcode != BRW_OPCODE_SEL &&
210 opcode != BRW_OPCODE_IF &&
211 opcode != BRW_OPCODE_WHILE));
212 }
213 };
214
215 /**
216 * Make the execution of \p inst dependent on the evaluation of a possibly
217 * inverted predicate.
218 */
219 inline vec4_instruction *
220 set_predicate_inv(enum brw_predicate pred, bool inverse,
221 vec4_instruction *inst)
222 {
223 inst->predicate = pred;
224 inst->predicate_inverse = inverse;
225 return inst;
226 }
227
228 /**
229 * Make the execution of \p inst dependent on the evaluation of a predicate.
230 */
231 inline vec4_instruction *
232 set_predicate(enum brw_predicate pred, vec4_instruction *inst)
233 {
234 return set_predicate_inv(pred, false, inst);
235 }
236
237 /**
238 * Write the result of evaluating the condition given by \p mod to a flag
239 * register.
240 */
241 inline vec4_instruction *
242 set_condmod(enum brw_conditional_mod mod, vec4_instruction *inst)
243 {
244 inst->conditional_mod = mod;
245 return inst;
246 }
247
248 /**
249 * Clamp the result of \p inst to the saturation range of its destination
250 * datatype.
251 */
252 inline vec4_instruction *
253 set_saturate(bool saturate, vec4_instruction *inst)
254 {
255 inst->saturate = saturate;
256 return inst;
257 }
258
259 } /* namespace brw */
260
261 #endif