gallivm,llvmpipe: fix float->srgb conversion to handle NaNs
[mesa.git] / src / gallium / auxiliary / gallivm / lp_bld_arit.h
1 /**************************************************************************
2 *
3 * Copyright 2009 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 /**
29 * @file
30 * Helper arithmetic functions.
31 *
32 * @author Jose Fonseca <jfonseca@vmware.com>
33 */
34
35
36 #ifndef LP_BLD_ARIT_H
37 #define LP_BLD_ARIT_H
38
39
40 #include "gallivm/lp_bld.h"
41
42
43 struct lp_type;
44 struct lp_build_context;
45 struct gallivm_state;
46
47
48 /**
49 * Complement, i.e., 1 - a.
50 */
51 LLVMValueRef
52 lp_build_comp(struct lp_build_context *bld,
53 LLVMValueRef a);
54
55 LLVMValueRef
56 lp_build_add(struct lp_build_context *bld,
57 LLVMValueRef a,
58 LLVMValueRef b);
59
60 LLVMValueRef
61 lp_build_horizontal_add(struct lp_build_context *bld,
62 LLVMValueRef a);
63
64 LLVMValueRef
65 lp_build_hadd_partial4(struct lp_build_context *bld,
66 LLVMValueRef vectors[],
67 unsigned num_vecs);
68
69 LLVMValueRef
70 lp_build_sub(struct lp_build_context *bld,
71 LLVMValueRef a,
72 LLVMValueRef b);
73
74 LLVMValueRef
75 lp_build_mul(struct lp_build_context *bld,
76 LLVMValueRef a,
77 LLVMValueRef b);
78
79 LLVMValueRef
80 lp_build_mul_imm(struct lp_build_context *bld,
81 LLVMValueRef a,
82 int b);
83
84 LLVMValueRef
85 lp_build_div(struct lp_build_context *bld,
86 LLVMValueRef a,
87 LLVMValueRef b);
88
89
90 /**
91 * Set when the weights for normalized are prescaled, that is, in range
92 * 0..2**n, as opposed to range 0..2**(n-1).
93 */
94 #define LP_BLD_LERP_PRESCALED_WEIGHTS (1 << 0)
95
96 /**
97 * Used internally when using wide intermediates for normalized lerps.
98 *
99 * Do not use.
100 */
101 #define LP_BLD_LERP_WIDE_NORMALIZED (1 << 1)
102
103 LLVMValueRef
104 lp_build_lerp(struct lp_build_context *bld,
105 LLVMValueRef x,
106 LLVMValueRef v0,
107 LLVMValueRef v1,
108 unsigned flags);
109
110 LLVMValueRef
111 lp_build_lerp_2d(struct lp_build_context *bld,
112 LLVMValueRef x,
113 LLVMValueRef y,
114 LLVMValueRef v00,
115 LLVMValueRef v01,
116 LLVMValueRef v10,
117 LLVMValueRef v11,
118 unsigned flags);
119
120 LLVMValueRef
121 lp_build_lerp_3d(struct lp_build_context *bld,
122 LLVMValueRef x,
123 LLVMValueRef y,
124 LLVMValueRef z,
125 LLVMValueRef v000,
126 LLVMValueRef v001,
127 LLVMValueRef v010,
128 LLVMValueRef v011,
129 LLVMValueRef v100,
130 LLVMValueRef v101,
131 LLVMValueRef v110,
132 LLVMValueRef v111,
133 unsigned flags);
134
135 /**
136 * Specifies floating point NaN behavior.
137 */
138 enum gallivm_nan_behavior {
139 /* Results are undefined with NaN. Results in fastest code */
140 GALLIVM_NAN_BEHAVIOR_UNDEFINED,
141 /* If input is NaN, NaN is returned */
142 GALLIVM_NAN_RETURN_NAN,
143 /* If one of the inputs is NaN, the other operand is returned */
144 GALLIVM_NAN_RETURN_OTHER,
145 /* If one of the inputs is NaN, the other operand is returned,
146 * but we guarantee the second operand is not a NaN.
147 * In min/max it will be as fast as undefined with sse opcodes,
148 * and archs having native return_other can benefit too. */
149 GALLIVM_NAN_RETURN_OTHER_SECOND_NONNAN
150 };
151
152 LLVMValueRef
153 lp_build_min(struct lp_build_context *bld,
154 LLVMValueRef a,
155 LLVMValueRef b);
156
157 LLVMValueRef
158 lp_build_min_ext(struct lp_build_context *bld,
159 LLVMValueRef a,
160 LLVMValueRef b,
161 enum gallivm_nan_behavior nan_behavior);
162
163 LLVMValueRef
164 lp_build_max(struct lp_build_context *bld,
165 LLVMValueRef a,
166 LLVMValueRef b);
167
168 LLVMValueRef
169 lp_build_max_ext(struct lp_build_context *bld,
170 LLVMValueRef a,
171 LLVMValueRef b,
172 enum gallivm_nan_behavior nan_behavior);
173
174 LLVMValueRef
175 lp_build_clamp(struct lp_build_context *bld,
176 LLVMValueRef a,
177 LLVMValueRef min,
178 LLVMValueRef max);
179
180 LLVMValueRef
181 lp_build_clamp_zero_one_nanzero(struct lp_build_context *bld,
182 LLVMValueRef a);
183
184 LLVMValueRef
185 lp_build_abs(struct lp_build_context *bld,
186 LLVMValueRef a);
187
188 LLVMValueRef
189 lp_build_negate(struct lp_build_context *bld,
190 LLVMValueRef a);
191
192 LLVMValueRef
193 lp_build_sgn(struct lp_build_context *bld,
194 LLVMValueRef a);
195
196 LLVMValueRef
197 lp_build_set_sign(struct lp_build_context *bld,
198 LLVMValueRef a, LLVMValueRef sign);
199
200 LLVMValueRef
201 lp_build_int_to_float(struct lp_build_context *bld,
202 LLVMValueRef a);
203
204 LLVMValueRef
205 lp_build_round(struct lp_build_context *bld,
206 LLVMValueRef a);
207
208 LLVMValueRef
209 lp_build_floor(struct lp_build_context *bld,
210 LLVMValueRef a);
211
212 LLVMValueRef
213 lp_build_ceil(struct lp_build_context *bld,
214 LLVMValueRef a);
215
216 LLVMValueRef
217 lp_build_trunc(struct lp_build_context *bld,
218 LLVMValueRef a);
219
220 LLVMValueRef
221 lp_build_fract(struct lp_build_context *bld,
222 LLVMValueRef a);
223
224 LLVMValueRef
225 lp_build_fract_safe(struct lp_build_context *bld,
226 LLVMValueRef a);
227
228 LLVMValueRef
229 lp_build_ifloor(struct lp_build_context *bld,
230 LLVMValueRef a);
231 LLVMValueRef
232 lp_build_iceil(struct lp_build_context *bld,
233 LLVMValueRef a);
234
235 LLVMValueRef
236 lp_build_iround(struct lp_build_context *bld,
237 LLVMValueRef a);
238
239 LLVMValueRef
240 lp_build_itrunc(struct lp_build_context *bld,
241 LLVMValueRef a);
242
243 void
244 lp_build_ifloor_fract(struct lp_build_context *bld,
245 LLVMValueRef a,
246 LLVMValueRef *out_ipart,
247 LLVMValueRef *out_fpart);
248
249 void
250 lp_build_ifloor_fract_safe(struct lp_build_context *bld,
251 LLVMValueRef a,
252 LLVMValueRef *out_ipart,
253 LLVMValueRef *out_fpart);
254
255 LLVMValueRef
256 lp_build_sqrt(struct lp_build_context *bld,
257 LLVMValueRef a);
258
259 LLVMValueRef
260 lp_build_rcp(struct lp_build_context *bld,
261 LLVMValueRef a);
262
263 LLVMValueRef
264 lp_build_rsqrt(struct lp_build_context *bld,
265 LLVMValueRef a);
266
267 boolean
268 lp_build_fast_rsqrt_available(struct lp_type type);
269
270 LLVMValueRef
271 lp_build_fast_rsqrt(struct lp_build_context *bld,
272 LLVMValueRef a);
273
274 LLVMValueRef
275 lp_build_polynomial(struct lp_build_context *bld,
276 LLVMValueRef x,
277 const double *coeffs,
278 unsigned num_coeffs);
279
280 LLVMValueRef
281 lp_build_cos(struct lp_build_context *bld,
282 LLVMValueRef a);
283
284 LLVMValueRef
285 lp_build_sin(struct lp_build_context *bld,
286 LLVMValueRef a);
287
288 LLVMValueRef
289 lp_build_pow(struct lp_build_context *bld,
290 LLVMValueRef a,
291 LLVMValueRef b);
292
293 LLVMValueRef
294 lp_build_exp(struct lp_build_context *bld,
295 LLVMValueRef a);
296
297 LLVMValueRef
298 lp_build_log(struct lp_build_context *bld,
299 LLVMValueRef a);
300
301 LLVMValueRef
302 lp_build_log_safe(struct lp_build_context *bld,
303 LLVMValueRef a);
304
305 LLVMValueRef
306 lp_build_exp2(struct lp_build_context *bld,
307 LLVMValueRef a);
308
309 LLVMValueRef
310 lp_build_extract_exponent(struct lp_build_context *bld,
311 LLVMValueRef x,
312 int bias);
313
314 LLVMValueRef
315 lp_build_extract_mantissa(struct lp_build_context *bld,
316 LLVMValueRef x);
317
318 LLVMValueRef
319 lp_build_log2(struct lp_build_context *bld,
320 LLVMValueRef a);
321
322 LLVMValueRef
323 lp_build_log2_safe(struct lp_build_context *bld,
324 LLVMValueRef a);
325
326 LLVMValueRef
327 lp_build_fast_log2(struct lp_build_context *bld,
328 LLVMValueRef a);
329
330 LLVMValueRef
331 lp_build_ilog2(struct lp_build_context *bld,
332 LLVMValueRef x);
333
334 void
335 lp_build_log2_approx(struct lp_build_context *bld,
336 LLVMValueRef x,
337 LLVMValueRef *p_exp,
338 LLVMValueRef *p_floor_log2,
339 LLVMValueRef *p_log2,
340 boolean handle_nans);
341
342 LLVMValueRef
343 lp_build_mod(struct lp_build_context *bld,
344 LLVMValueRef x,
345 LLVMValueRef y);
346
347 LLVMValueRef
348 lp_build_isnan(struct lp_build_context *bld,
349 LLVMValueRef x);
350
351 LLVMValueRef
352 lp_build_isfinite(struct lp_build_context *bld,
353 LLVMValueRef x);
354
355
356 LLVMValueRef
357 lp_build_is_inf_or_nan(struct gallivm_state *gallivm,
358 const struct lp_type type,
359 LLVMValueRef x);
360
361 #endif /* !LP_BLD_ARIT_H */