1 /*
2 * Copyright © 2018 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #ifndef NIR_BUILTIN_BUILDER_H
25 #define NIR_BUILTIN_BUILDER_H
26
27 #include "util/u_math.h"
28 #include "nir_builder.h"
29
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33
34 /*
35 * Functions are sorted alphabetically with removed type and "fast" prefix.
36 * Definitions for functions in the C file come first.
37 */
38
39 nir_def *nir_cross3(nir_builder *b, nir_def *x, nir_def *y);
40 nir_def *nir_cross4(nir_builder *b, nir_def *x, nir_def *y);
41 nir_def *nir_fast_length(nir_builder *b, nir_def *vec);
42 nir_def *nir_nextafter(nir_builder *b, nir_def *x, nir_def *y);
43 nir_def *nir_normalize(nir_builder *b, nir_def *vec);
44 nir_def *nir_smoothstep(nir_builder *b, nir_def *edge0,
45 nir_def *edge1, nir_def *x);
46 nir_def *nir_upsample(nir_builder *b, nir_def *hi, nir_def *lo);
47 nir_def *nir_atan(nir_builder *b, nir_def *y_over_x);
48 nir_def *nir_atan2(nir_builder *b, nir_def *y, nir_def *x);
49
50 nir_def *
51 nir_get_texture_lod(nir_builder *b, nir_tex_instr *tex);
52
53 nir_def *
54 nir_get_texture_size(nir_builder *b, nir_tex_instr *tex);
55
56 static inline nir_def *
nir_fisnan(nir_builder * b,nir_def * x)57 nir_fisnan(nir_builder *b, nir_def *x)
58 {
59 bool old_exact = b->exact;
60 b->exact = true;
61 nir_def *res = nir_fneu(b, x, x);
62 b->exact = old_exact;
63 return res;
64 }
65
66 static inline nir_def *
nir_nan_check2(nir_builder * b,nir_def * x,nir_def * y,nir_def * res)67 nir_nan_check2(nir_builder *b, nir_def *x, nir_def *y, nir_def *res)
68 {
69 return nir_bcsel(b, nir_fisnan(b, x), x, nir_bcsel(b, nir_fisnan(b, y), y, res));
70 }
71
72 static inline nir_def *
nir_fmax_abs_vec_comp(nir_builder * b,nir_def * vec)73 nir_fmax_abs_vec_comp(nir_builder *b, nir_def *vec)
74 {
75 nir_def *abs = nir_fabs(b, vec);
76 nir_def *res = nir_channel(b, abs, 0);
77 for (unsigned i = 1; i < vec->num_components; ++i)
78 res = nir_fmax(b, res, nir_channel(b, abs, i));
79 return res;
80 }
81
82 static inline nir_def *
nir_iabs_diff(nir_builder * b,nir_def * x,nir_def * y)83 nir_iabs_diff(nir_builder *b, nir_def *x, nir_def *y)
84 {
85 nir_def *cond = nir_ige(b, x, y);
86 nir_def *res0 = nir_isub(b, x, y);
87 nir_def *res1 = nir_isub(b, y, x);
88 return nir_bcsel(b, cond, res0, res1);
89 }
90
91 static inline nir_def *
nir_uabs_diff(nir_builder * b,nir_def * x,nir_def * y)92 nir_uabs_diff(nir_builder *b, nir_def *x, nir_def *y)
93 {
94 nir_def *cond = nir_uge(b, x, y);
95 nir_def *res0 = nir_isub(b, x, y);
96 nir_def *res1 = nir_isub(b, y, x);
97 return nir_bcsel(b, cond, res0, res1);
98 }
99
100 static inline nir_def *
nir_fexp(nir_builder * b,nir_def * x)101 nir_fexp(nir_builder *b, nir_def *x)
102 {
103 return nir_fexp2(b, nir_fmul_imm(b, x, M_LOG2E));
104 }
105
106 static inline nir_def *
nir_flog(nir_builder * b,nir_def * x)107 nir_flog(nir_builder *b, nir_def *x)
108 {
109 return nir_fmul_imm(b, nir_flog2(b, x), 1.0 / M_LOG2E);
110 }
111
112 static inline nir_def *
nir_imad24(nir_builder * b,nir_def * x,nir_def * y,nir_def * z)113 nir_imad24(nir_builder *b, nir_def *x, nir_def *y, nir_def *z)
114 {
115 nir_def *temp = nir_imul24(b, x, y);
116 return nir_iadd(b, temp, z);
117 }
118
119 static inline nir_def *
nir_imad_hi(nir_builder * b,nir_def * x,nir_def * y,nir_def * z)120 nir_imad_hi(nir_builder *b, nir_def *x, nir_def *y, nir_def *z)
121 {
122 nir_def *temp = nir_imul_high(b, x, y);
123 return nir_iadd(b, temp, z);
124 }
125
126 static inline nir_def *
nir_umad_hi(nir_builder * b,nir_def * x,nir_def * y,nir_def * z)127 nir_umad_hi(nir_builder *b, nir_def *x, nir_def *y, nir_def *z)
128 {
129 nir_def *temp = nir_umul_high(b, x, y);
130 return nir_iadd(b, temp, z);
131 }
132
133 static inline nir_def *
nir_bitselect(nir_builder * b,nir_def * x,nir_def * y,nir_def * s)134 nir_bitselect(nir_builder *b, nir_def *x, nir_def *y, nir_def *s)
135 {
136 return nir_ior(b, nir_iand(b, nir_inot(b, s), x), nir_iand(b, s, y));
137 }
138
139 static inline nir_def *
nir_copysign(nir_builder * b,nir_def * x,nir_def * y)140 nir_copysign(nir_builder *b, nir_def *x, nir_def *y)
141 {
142 uint64_t masks = 1ull << (x->bit_size - 1);
143 uint64_t maskv = ~masks;
144
145 nir_def *s = nir_imm_intN_t(b, masks, x->bit_size);
146 nir_def *v = nir_imm_intN_t(b, maskv, x->bit_size);
147
148 return nir_ior(b, nir_iand(b, x, v), nir_iand(b, y, s));
149 }
150
151 static inline nir_def *
nir_degrees(nir_builder * b,nir_def * val)152 nir_degrees(nir_builder *b, nir_def *val)
153 {
154 return nir_fmul_imm(b, val, 180.0 / M_PI);
155 }
156
157 static inline nir_def *
nir_fdim(nir_builder * b,nir_def * x,nir_def * y)158 nir_fdim(nir_builder *b, nir_def *x, nir_def *y)
159 {
160 nir_def *cond = nir_flt(b, y, x);
161 nir_def *res = nir_fsub(b, x, y);
162 nir_def *zero = nir_imm_floatN_t(b, 0.0, x->bit_size);
163
164 // return NaN if either x or y are NaN, else x-y if x>y, else +0.0
165 return nir_nan_check2(b, x, y, nir_bcsel(b, cond, res, zero));
166 }
167
168 static inline nir_def *
nir_fast_distance(nir_builder * b,nir_def * x,nir_def * y)169 nir_fast_distance(nir_builder *b, nir_def *x, nir_def *y)
170 {
171 return nir_fast_length(b, nir_fsub(b, x, y));
172 }
173
174 static inline nir_def *
nir_fast_normalize(nir_builder * b,nir_def * vec)175 nir_fast_normalize(nir_builder *b, nir_def *vec)
176 {
177 return nir_fdiv(b, vec, nir_fast_length(b, vec));
178 }
179
180 static inline nir_def *
nir_fmad(nir_builder * b,nir_def * x,nir_def * y,nir_def * z)181 nir_fmad(nir_builder *b, nir_def *x, nir_def *y, nir_def *z)
182 {
183 return nir_fadd(b, nir_fmul(b, x, y), z);
184 }
185
186 static inline nir_def *
nir_maxmag(nir_builder * b,nir_def * x,nir_def * y)187 nir_maxmag(nir_builder *b, nir_def *x, nir_def *y)
188 {
189 nir_def *xabs = nir_fabs(b, x);
190 nir_def *yabs = nir_fabs(b, y);
191
192 nir_def *condy = nir_flt(b, xabs, yabs);
193 nir_def *condx = nir_flt(b, yabs, xabs);
194
195 return nir_bcsel(b, condy, y, nir_bcsel(b, condx, x, nir_fmax(b, x, y)));
196 }
197
198 static inline nir_def *
nir_minmag(nir_builder * b,nir_def * x,nir_def * y)199 nir_minmag(nir_builder *b, nir_def *x, nir_def *y)
200 {
201 nir_def *xabs = nir_fabs(b, x);
202 nir_def *yabs = nir_fabs(b, y);
203
204 nir_def *condx = nir_flt(b, xabs, yabs);
205 nir_def *condy = nir_flt(b, yabs, xabs);
206
207 return nir_bcsel(b, condy, y, nir_bcsel(b, condx, x, nir_fmin(b, x, y)));
208 }
209
210 static inline nir_def *
nir_nan(nir_builder * b,nir_def * x)211 nir_nan(nir_builder *b, nir_def *x)
212 {
213 nir_def *nan = nir_imm_floatN_t(b, NAN, x->bit_size);
214 if (x->num_components == 1)
215 return nan;
216
217 nir_def *nans[NIR_MAX_VEC_COMPONENTS];
218 for (unsigned i = 0; i < x->num_components; ++i)
219 nans[i] = nan;
220
221 return nir_vec(b, nans, x->num_components);
222 }
223
224 static inline nir_def *
nir_radians(nir_builder * b,nir_def * val)225 nir_radians(nir_builder *b, nir_def *val)
226 {
227 return nir_fmul_imm(b, val, M_PI / 180.0);
228 }
229
230 static inline nir_def *
nir_select(nir_builder * b,nir_def * x,nir_def * y,nir_def * s)231 nir_select(nir_builder *b, nir_def *x, nir_def *y, nir_def *s)
232 {
233 if (s->num_components != 1) {
234 uint64_t mask = 1ull << (s->bit_size - 1);
235 s = nir_iand_imm(b, s, mask);
236 }
237 return nir_bcsel(b, nir_ieq_imm(b, s, 0), x, y);
238 }
239
240 static inline nir_def *
nir_ftan(nir_builder * b,nir_def * x)241 nir_ftan(nir_builder *b, nir_def *x)
242 {
243 return nir_fdiv(b, nir_fsin(b, x), nir_fcos(b, x));
244 }
245
246 static inline nir_def *
nir_clz_u(nir_builder * b,nir_def * a)247 nir_clz_u(nir_builder *b, nir_def *a)
248 {
249 nir_def *val;
250 val = nir_isub_imm(b, a->bit_size - 1,
251 nir_ufind_msb(b, nir_u2uN(b, a,
252 MAX2(a->bit_size, 32))));
253 return nir_u2uN(b, val, a->bit_size);
254 }
255
256 static inline nir_def *
nir_ctz_u(nir_builder * b,nir_def * a)257 nir_ctz_u(nir_builder *b, nir_def *a)
258 {
259 nir_def *cond = nir_ieq_imm(b, a, 0);
260
261 return nir_bcsel(b, cond,
262 nir_imm_intN_t(b, a->bit_size, a->bit_size),
263 nir_u2uN(b, nir_find_lsb(b, a), a->bit_size));
264 }
265
266 #ifdef __cplusplus
267 }
268 #endif
269
270 #endif /* NIR_BUILTIN_BUILDER_H */
271