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