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_ssa_def* nir_cross3(nir_builder *b, nir_ssa_def *x, nir_ssa_def *y);
40 nir_ssa_def* nir_cross4(nir_builder *b, nir_ssa_def *x, nir_ssa_def *y);
41 nir_ssa_def* nir_fast_length(nir_builder *b, nir_ssa_def *vec);
42 nir_ssa_def* nir_nextafter(nir_builder *b, nir_ssa_def *x, nir_ssa_def *y);
43 nir_ssa_def* nir_normalize(nir_builder *b, nir_ssa_def *vec);
44 nir_ssa_def* nir_smoothstep(nir_builder *b, nir_ssa_def *edge0,
45                             nir_ssa_def *edge1, nir_ssa_def *x);
46 nir_ssa_def* nir_upsample(nir_builder *b, nir_ssa_def *hi, nir_ssa_def *lo);
47 nir_ssa_def* nir_atan(nir_builder *b, nir_ssa_def *y_over_x);
48 nir_ssa_def* nir_atan2(nir_builder *b, nir_ssa_def *y, nir_ssa_def *x);
49 
50 nir_ssa_def *
51 nir_get_texture_lod(nir_builder *b, nir_tex_instr *tex);
52 
53 nir_ssa_def *
54 nir_get_texture_size(nir_builder *b, nir_tex_instr *tex);
55 
56 static inline nir_ssa_def *
nir_nan_check2(nir_builder * b,nir_ssa_def * x,nir_ssa_def * y,nir_ssa_def * res)57 nir_nan_check2(nir_builder *b, nir_ssa_def *x, nir_ssa_def *y, nir_ssa_def *res)
58 {
59    return nir_bcsel(b, nir_fneu(b, x, x), x, nir_bcsel(b, nir_fneu(b, y, y), y, res));
60 }
61 
62 static inline nir_ssa_def *
nir_fmax_abs_vec_comp(nir_builder * b,nir_ssa_def * vec)63 nir_fmax_abs_vec_comp(nir_builder *b, nir_ssa_def *vec)
64 {
65    nir_ssa_def *res = nir_channel(b, vec, 0);
66    for (unsigned i = 1; i < vec->num_components; ++i)
67       res = nir_fmax(b, res, nir_fabs(b, nir_channel(b, vec, i)));
68    return res;
69 }
70 
71 static inline nir_ssa_def *
nir_iabs_diff(nir_builder * b,nir_ssa_def * x,nir_ssa_def * y)72 nir_iabs_diff(nir_builder *b, nir_ssa_def *x, nir_ssa_def *y)
73 {
74    nir_ssa_def *cond = nir_ige(b, x, y);
75    nir_ssa_def *res0 = nir_isub(b, x, y);
76    nir_ssa_def *res1 = nir_isub(b, y, x);
77    return nir_bcsel(b, cond, res0, res1);
78 }
79 
80 static inline nir_ssa_def *
nir_uabs_diff(nir_builder * b,nir_ssa_def * x,nir_ssa_def * y)81 nir_uabs_diff(nir_builder *b, nir_ssa_def *x, nir_ssa_def *y)
82 {
83    nir_ssa_def *cond = nir_uge(b, x, y);
84    nir_ssa_def *res0 = nir_isub(b, x, y);
85    nir_ssa_def *res1 = nir_isub(b, y, x);
86    return nir_bcsel(b, cond, res0, res1);
87 }
88 
89 static inline nir_ssa_def *
nir_fexp(nir_builder * b,nir_ssa_def * x)90 nir_fexp(nir_builder *b, nir_ssa_def *x)
91 {
92    return nir_fexp2(b, nir_fmul_imm(b, x, M_LOG2E));
93 }
94 
95 static inline nir_ssa_def *
nir_flog(nir_builder * b,nir_ssa_def * x)96 nir_flog(nir_builder *b, nir_ssa_def *x)
97 {
98    return nir_fmul_imm(b, nir_flog2(b, x), 1.0 / M_LOG2E);
99 }
100 
101 static inline nir_ssa_def *
nir_imad24(nir_builder * b,nir_ssa_def * x,nir_ssa_def * y,nir_ssa_def * z)102 nir_imad24(nir_builder *b, nir_ssa_def *x, nir_ssa_def *y, nir_ssa_def *z)
103 {
104    nir_ssa_def *temp = nir_imul24(b, x, y);
105    return nir_iadd(b, temp, z);
106 }
107 
108 static inline nir_ssa_def *
nir_imad_hi(nir_builder * b,nir_ssa_def * x,nir_ssa_def * y,nir_ssa_def * z)109 nir_imad_hi(nir_builder *b, nir_ssa_def *x, nir_ssa_def *y, nir_ssa_def *z)
110 {
111    nir_ssa_def *temp = nir_imul_high(b, x, y);
112    return nir_iadd(b, temp, z);
113 }
114 
115 static inline nir_ssa_def *
nir_umad_hi(nir_builder * b,nir_ssa_def * x,nir_ssa_def * y,nir_ssa_def * z)116 nir_umad_hi(nir_builder *b, nir_ssa_def *x, nir_ssa_def *y, nir_ssa_def *z)
117 {
118    nir_ssa_def *temp = nir_umul_high(b, x, y);
119    return nir_iadd(b, temp, z);
120 }
121 
122 static inline nir_ssa_def *
nir_bitselect(nir_builder * b,nir_ssa_def * x,nir_ssa_def * y,nir_ssa_def * s)123 nir_bitselect(nir_builder *b, nir_ssa_def *x, nir_ssa_def *y, nir_ssa_def *s)
124 {
125    return nir_ior(b, nir_iand(b, nir_inot(b, s), x), nir_iand(b, s, y));
126 }
127 
128 static inline nir_ssa_def *
nir_fclamp(nir_builder * b,nir_ssa_def * x,nir_ssa_def * min_val,nir_ssa_def * max_val)129 nir_fclamp(nir_builder *b,
130            nir_ssa_def *x, nir_ssa_def *min_val, nir_ssa_def *max_val)
131 {
132    return nir_fmin(b, nir_fmax(b, x, min_val), max_val);
133 }
134 
135 static inline nir_ssa_def *
nir_iclamp(nir_builder * b,nir_ssa_def * x,nir_ssa_def * min_val,nir_ssa_def * max_val)136 nir_iclamp(nir_builder *b,
137            nir_ssa_def *x, nir_ssa_def *min_val, nir_ssa_def *max_val)
138 {
139    return nir_imin(b, nir_imax(b, x, min_val), max_val);
140 }
141 
142 static inline nir_ssa_def *
nir_uclamp(nir_builder * b,nir_ssa_def * x,nir_ssa_def * min_val,nir_ssa_def * max_val)143 nir_uclamp(nir_builder *b,
144            nir_ssa_def *x, nir_ssa_def *min_val, nir_ssa_def *max_val)
145 {
146    return nir_umin(b, nir_umax(b, x, min_val), max_val);
147 }
148 
149 static inline nir_ssa_def *
nir_copysign(nir_builder * b,nir_ssa_def * x,nir_ssa_def * y)150 nir_copysign(nir_builder *b, nir_ssa_def *x, nir_ssa_def *y)
151 {
152    uint64_t masks = 1ull << (x->bit_size - 1);
153    uint64_t maskv = ~masks;
154 
155    nir_ssa_def *s = nir_imm_intN_t(b, masks, x->bit_size);
156    nir_ssa_def *v = nir_imm_intN_t(b, maskv, x->bit_size);
157 
158    return nir_ior(b, nir_iand(b, x, v), nir_iand(b, y, s));
159 }
160 
161 static inline nir_ssa_def *
nir_degrees(nir_builder * b,nir_ssa_def * val)162 nir_degrees(nir_builder *b, nir_ssa_def *val)
163 {
164    return nir_fmul_imm(b, val, 180.0 / M_PI);
165 }
166 
167 static inline nir_ssa_def *
nir_fdim(nir_builder * b,nir_ssa_def * x,nir_ssa_def * y)168 nir_fdim(nir_builder *b, nir_ssa_def *x, nir_ssa_def *y)
169 {
170    nir_ssa_def *cond = nir_flt(b, y, x);
171    nir_ssa_def *res = nir_fsub(b, x, y);
172    nir_ssa_def *zero = nir_imm_floatN_t(b, 0.0, x->bit_size);
173 
174    // return NaN if either x or y are NaN, else x-y if x>y, else +0.0
175    return nir_nan_check2(b, x, y, nir_bcsel(b, cond, res, zero));
176 }
177 
178 static inline nir_ssa_def *
nir_fast_distance(nir_builder * b,nir_ssa_def * x,nir_ssa_def * y)179 nir_fast_distance(nir_builder *b, nir_ssa_def *x, nir_ssa_def *y)
180 {
181    return nir_fast_length(b, nir_fsub(b, x, y));
182 }
183 
184 static inline nir_ssa_def*
nir_fast_normalize(nir_builder * b,nir_ssa_def * vec)185 nir_fast_normalize(nir_builder *b, nir_ssa_def *vec)
186 {
187    return nir_fdiv(b, vec, nir_fast_length(b, vec));
188 }
189 
190 static inline nir_ssa_def*
nir_fmad(nir_builder * b,nir_ssa_def * x,nir_ssa_def * y,nir_ssa_def * z)191 nir_fmad(nir_builder *b, nir_ssa_def *x, nir_ssa_def *y, nir_ssa_def *z)
192 {
193    return nir_fadd(b, nir_fmul(b, x, y), z);
194 }
195 
196 static inline nir_ssa_def*
nir_maxmag(nir_builder * b,nir_ssa_def * x,nir_ssa_def * y)197 nir_maxmag(nir_builder *b, nir_ssa_def *x, nir_ssa_def *y)
198 {
199    nir_ssa_def *xabs = nir_fabs(b, x);
200    nir_ssa_def *yabs = nir_fabs(b, y);
201 
202    nir_ssa_def *condy = nir_flt(b, xabs, yabs);
203    nir_ssa_def *condx = nir_flt(b, yabs, xabs);
204 
205    return nir_bcsel(b, condy, y, nir_bcsel(b, condx, x, nir_fmax(b, x, y)));
206 }
207 
208 static inline nir_ssa_def*
nir_minmag(nir_builder * b,nir_ssa_def * x,nir_ssa_def * y)209 nir_minmag(nir_builder *b, nir_ssa_def *x, nir_ssa_def *y)
210 {
211    nir_ssa_def *xabs = nir_fabs(b, x);
212    nir_ssa_def *yabs = nir_fabs(b, y);
213 
214    nir_ssa_def *condx = nir_flt(b, xabs, yabs);
215    nir_ssa_def *condy = nir_flt(b, yabs, xabs);
216 
217    return nir_bcsel(b, condy, y, nir_bcsel(b, condx, x, nir_fmin(b, x, y)));
218 }
219 
220 static inline nir_ssa_def*
nir_nan(nir_builder * b,nir_ssa_def * x)221 nir_nan(nir_builder *b, nir_ssa_def *x)
222 {
223    nir_ssa_def *nan = nir_imm_floatN_t(b, NAN, x->bit_size);
224    if (x->num_components == 1)
225       return nan;
226 
227    nir_ssa_def *nans[NIR_MAX_VEC_COMPONENTS];
228    for (unsigned i = 0; i < x->num_components; ++i)
229       nans[i] = nan;
230 
231    return nir_vec(b, nans, x->num_components);
232 }
233 
234 static inline nir_ssa_def *
nir_radians(nir_builder * b,nir_ssa_def * val)235 nir_radians(nir_builder *b, nir_ssa_def *val)
236 {
237    return nir_fmul_imm(b, val, M_PI / 180.0);
238 }
239 
240 static inline nir_ssa_def *
nir_select(nir_builder * b,nir_ssa_def * x,nir_ssa_def * y,nir_ssa_def * s)241 nir_select(nir_builder *b, nir_ssa_def *x, nir_ssa_def *y, nir_ssa_def *s)
242 {
243    if (s->num_components != 1) {
244       uint64_t mask = 1ull << (s->bit_size - 1);
245       s = nir_iand(b, s, nir_imm_intN_t(b, mask, s->bit_size));
246    }
247    return nir_bcsel(b, nir_ieq_imm(b, s, 0), x, y);
248 }
249 
250 static inline nir_ssa_def *
nir_ftan(nir_builder * b,nir_ssa_def * x)251 nir_ftan(nir_builder *b, nir_ssa_def *x)
252 {
253    return nir_fdiv(b, nir_fsin(b, x), nir_fcos(b, x));
254 }
255 
256 static inline nir_ssa_def *
nir_clz_u(nir_builder * b,nir_ssa_def * a)257 nir_clz_u(nir_builder *b, nir_ssa_def *a)
258 {
259    nir_ssa_def *val;
260    val = nir_isub(b, nir_imm_intN_t(b, a->bit_size - 1, 32), nir_ufind_msb(b, a));
261    return nir_u2u(b, val, a->bit_size);
262 }
263 
264 static inline nir_ssa_def *
nir_ctz_u(nir_builder * b,nir_ssa_def * a)265 nir_ctz_u(nir_builder *b, nir_ssa_def *a)
266 {
267    nir_ssa_def *cond = nir_ieq(b, a, nir_imm_intN_t(b, 0, a->bit_size));
268 
269    return nir_bcsel(b, cond,
270                     nir_imm_intN_t(b, a->bit_size, a->bit_size),
271                     nir_u2u(b, nir_find_lsb(b, a), a->bit_size));
272 }
273 
274 #ifdef __cplusplus
275 }
276 #endif
277 
278 #endif /* NIR_BUILTIN_BUILDER_H */
279