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