1 #include "draw_private.h"
2 #include "draw_context.h"
6 #include "gallivm/lp_bld_arit.h"
7 #include "gallivm/lp_bld_struct.h"
8 #include "gallivm/lp_bld_format.h"
9 #include "gallivm/lp_bld_debug.h"
10 #include "gallivm/lp_bld_type.h"
12 #include "util/u_memory.h"
13 #include "util/u_format.h"
14 #include "pipe/p_state.h"
20 from_64_float(LLVMBuilderRef builder
, LLVMValueRef val
)
22 LLVMValueRef bc
= LLVMBuildBitCast(builder
, val
,
23 LLVMPointerType(LLVMDoubleType(), 0) , "");
24 LLVMValueRef l
= LLVMBuildLoad(builder
, bc
, "");
25 return LLVMBuildFPTrunc(builder
, l
, LLVMFloatType(), "");
29 from_32_float(LLVMBuilderRef builder
, LLVMValueRef val
)
31 LLVMValueRef bc
= LLVMBuildBitCast(builder
, val
,
32 LLVMPointerType(LLVMFloatType(), 0) , "");
33 return LLVMBuildLoad(builder
, bc
, "");
36 static INLINE LLVMValueRef
37 from_8_uscaled(LLVMBuilderRef builder
, LLVMValueRef val
)
39 LLVMValueRef l
= LLVMBuildLoad(builder
, val
, "");
40 return LLVMBuildUIToFP(builder
, l
, LLVMFloatType(), "");
43 static INLINE LLVMValueRef
44 from_16_uscaled(LLVMBuilderRef builder
, LLVMValueRef val
)
46 LLVMValueRef bc
= LLVMBuildBitCast(builder
, val
,
47 LLVMPointerType(LLVMIntType(16), 0) , "");
48 LLVMValueRef l
= LLVMBuildLoad(builder
, bc
, "");
49 return LLVMBuildUIToFP(builder
, l
, LLVMFloatType(), "");
52 static INLINE LLVMValueRef
53 from_32_uscaled(LLVMBuilderRef builder
, LLVMValueRef val
)
55 LLVMValueRef bc
= LLVMBuildBitCast(builder
, val
,
56 LLVMPointerType(LLVMIntType(32), 0) , "");
57 LLVMValueRef l
= LLVMBuildLoad(builder
, bc
, "");
58 return LLVMBuildUIToFP(builder
, l
, LLVMFloatType(), "");
61 static INLINE LLVMValueRef
62 from_8_sscaled(LLVMBuilderRef builder
, LLVMValueRef val
)
64 LLVMValueRef l
= LLVMBuildLoad(builder
, val
, "");
65 return LLVMBuildSIToFP(builder
, l
, LLVMFloatType(), "");
68 static INLINE LLVMValueRef
69 from_16_sscaled(LLVMBuilderRef builder
, LLVMValueRef val
)
71 LLVMValueRef bc
= LLVMBuildBitCast(builder
, val
,
72 LLVMPointerType(LLVMIntType(16), 0) , "");
73 LLVMValueRef l
= LLVMBuildLoad(builder
, bc
, "");
74 return LLVMBuildSIToFP(builder
, l
, LLVMFloatType(), "");
77 static INLINE LLVMValueRef
78 from_32_sscaled(LLVMBuilderRef builder
, LLVMValueRef val
)
80 LLVMValueRef bc
= LLVMBuildBitCast(builder
, val
,
81 LLVMPointerType(LLVMIntType(32), 0) , "");
82 LLVMValueRef l
= LLVMBuildLoad(builder
, bc
, "");
83 return LLVMBuildSIToFP(builder
, l
, LLVMFloatType(), "");
87 static INLINE LLVMValueRef
88 from_8_unorm(LLVMBuilderRef builder
, LLVMValueRef val
)
90 LLVMValueRef l
= LLVMBuildLoad(builder
, val
, "");
91 LLVMValueRef uscaled
= LLVMBuildUIToFP(builder
, l
, LLVMFloatType(), "");
92 return LLVMBuildFDiv(builder
, uscaled
,
93 LLVMConstReal(LLVMFloatType(), 255.), "");
96 static INLINE LLVMValueRef
97 from_16_unorm(LLVMBuilderRef builder
, LLVMValueRef val
)
99 LLVMValueRef bc
= LLVMBuildBitCast(builder
, val
,
100 LLVMPointerType(LLVMIntType(16), 0) , "");
101 LLVMValueRef l
= LLVMBuildLoad(builder
, bc
, "");
102 LLVMValueRef uscaled
= LLVMBuildUIToFP(builder
, l
, LLVMFloatType(), "");
103 return LLVMBuildFDiv(builder
, uscaled
,
104 LLVMConstReal(LLVMFloatType(), 65535.), "");
107 static INLINE LLVMValueRef
108 from_32_unorm(LLVMBuilderRef builder
, LLVMValueRef val
)
110 LLVMValueRef bc
= LLVMBuildBitCast(builder
, val
,
111 LLVMPointerType(LLVMIntType(32), 0) , "");
112 LLVMValueRef l
= LLVMBuildLoad(builder
, bc
, "");
113 LLVMValueRef uscaled
= LLVMBuildUIToFP(builder
, l
, LLVMFloatType(), "");
115 return LLVMBuildFDiv(builder
, uscaled
,
116 LLVMConstReal(LLVMFloatType(), 4294967295.), "");
119 static INLINE LLVMValueRef
120 from_8_snorm(LLVMBuilderRef builder
, LLVMValueRef val
)
122 LLVMValueRef l
= LLVMBuildLoad(builder
, val
, "");
123 LLVMValueRef uscaled
= LLVMBuildSIToFP(builder
, l
, LLVMFloatType(), "");
124 return LLVMBuildFDiv(builder
, uscaled
,
125 LLVMConstReal(LLVMFloatType(), 127.0), "");
128 static INLINE LLVMValueRef
129 from_16_snorm(LLVMBuilderRef builder
, LLVMValueRef val
)
131 LLVMValueRef bc
= LLVMBuildBitCast(builder
, val
,
132 LLVMPointerType(LLVMIntType(16), 0) , "");
133 LLVMValueRef l
= LLVMBuildLoad(builder
, bc
, "");
134 LLVMValueRef uscaled
= LLVMBuildSIToFP(builder
, l
, LLVMFloatType(), "");
135 return LLVMBuildFDiv(builder
, uscaled
,
136 LLVMConstReal(LLVMFloatType(), 32767.0f
), "");
139 static INLINE LLVMValueRef
140 from_32_snorm(LLVMBuilderRef builder
, LLVMValueRef val
)
142 LLVMValueRef bc
= LLVMBuildBitCast(builder
, val
,
143 LLVMPointerType(LLVMIntType(32), 0) , "");
144 LLVMValueRef l
= LLVMBuildLoad(builder
, bc
, "");
145 LLVMValueRef uscaled
= LLVMBuildSIToFP(builder
, l
, LLVMFloatType(), "");
147 return LLVMBuildFDiv(builder
, uscaled
,
148 LLVMConstReal(LLVMFloatType(), 2147483647.0), "");
151 static INLINE LLVMValueRef
152 from_32_fixed(LLVMBuilderRef builder
, LLVMValueRef val
)
154 LLVMValueRef bc
= LLVMBuildBitCast(builder
, val
,
155 LLVMPointerType(LLVMIntType(32), 0) , "");
156 LLVMValueRef l
= LLVMBuildLoad(builder
, bc
, "");
157 LLVMValueRef uscaled
= LLVMBuildSIToFP(builder
, l
, LLVMFloatType(), "");
159 return LLVMBuildFDiv(builder
, uscaled
,
160 LLVMConstReal(LLVMFloatType(), 65536.0), "");
164 to_64_float(LLVMBuilderRef builder
, LLVMValueRef fp
)
166 LLVMValueRef l
= LLVMBuildLoad(builder
, fp
, "");
167 return LLVMBuildFPExt(builder
, l
, LLVMDoubleType(), "");
171 to_32_float(LLVMBuilderRef builder
, LLVMValueRef fp
)
173 return LLVMBuildLoad(builder
, fp
, "");
176 static INLINE LLVMValueRef
177 to_8_uscaled(LLVMBuilderRef builder
, LLVMValueRef fp
)
179 LLVMValueRef l
= LLVMBuildLoad(builder
, fp
, "");
180 return LLVMBuildFPToUI(builder
, l
, LLVMIntType(8), "");
183 static INLINE LLVMValueRef
184 to_16_uscaled(LLVMBuilderRef builder
, LLVMValueRef fp
)
186 LLVMValueRef l
= LLVMBuildLoad(builder
, fp
, "");
187 return LLVMBuildFPToUI(builder
, l
, LLVMIntType(16), "");
190 static INLINE LLVMValueRef
191 to_32_uscaled(LLVMBuilderRef builder
, LLVMValueRef fp
)
193 LLVMValueRef l
= LLVMBuildLoad(builder
, fp
, "");
194 return LLVMBuildFPToUI(builder
, l
, LLVMIntType(32), "");
197 static INLINE LLVMValueRef
198 to_8_sscaled(LLVMBuilderRef builder
, LLVMValueRef fp
)
200 LLVMValueRef l
= LLVMBuildLoad(builder
, fp
, "");
201 return LLVMBuildFPToSI(builder
, l
, LLVMIntType(8), "");
204 static INLINE LLVMValueRef
205 to_16_sscaled(LLVMBuilderRef builder
, LLVMValueRef fp
)
207 LLVMValueRef l
= LLVMBuildLoad(builder
, fp
, "");
208 return LLVMBuildFPToSI(builder
, l
, LLVMIntType(16), "");
211 static INLINE LLVMValueRef
212 to_32_sscaled(LLVMBuilderRef builder
, LLVMValueRef fp
)
214 LLVMValueRef l
= LLVMBuildLoad(builder
, fp
, "");
215 return LLVMBuildFPToSI(builder
, l
, LLVMIntType(32), "");
218 static INLINE LLVMValueRef
219 to_8_unorm(LLVMBuilderRef builder
, LLVMValueRef fp
)
221 LLVMValueRef l
= LLVMBuildLoad(builder
, fp
, "");
222 LLVMValueRef uscaled
= LLVMBuildFPToUI(builder
, l
, LLVMIntType(8), "");
223 return LLVMBuildFMul(builder
, uscaled
,
224 LLVMConstReal(LLVMFloatType(), 255.), "");
227 static INLINE LLVMValueRef
228 to_16_unorm(LLVMBuilderRef builder
, LLVMValueRef fp
)
230 LLVMValueRef l
= LLVMBuildLoad(builder
, fp
, "");
231 LLVMValueRef uscaled
= LLVMBuildFPToUI(builder
, l
, LLVMIntType(32), "");
232 return LLVMBuildFMul(builder
, uscaled
,
233 LLVMConstReal(LLVMFloatType(), 65535.), "");
236 static INLINE LLVMValueRef
237 to_32_unorm(LLVMBuilderRef builder
, LLVMValueRef fp
)
239 LLVMValueRef l
= LLVMBuildLoad(builder
, fp
, "");
240 LLVMValueRef uscaled
= LLVMBuildFPToUI(builder
, l
, LLVMIntType(32), "");
242 return LLVMBuildFMul(builder
, uscaled
,
243 LLVMConstReal(LLVMFloatType(), 4294967295.), "");
246 static INLINE LLVMValueRef
247 to_8_snorm(LLVMBuilderRef builder
, LLVMValueRef val
)
249 LLVMValueRef l
= LLVMBuildLoad(builder
, val
, "");
250 LLVMValueRef uscaled
= LLVMBuildFPToSI(builder
, l
, LLVMIntType(8), "");
251 return LLVMBuildFMul(builder
, uscaled
,
252 LLVMConstReal(LLVMFloatType(), 127.0), "");
255 static INLINE LLVMValueRef
256 to_16_snorm(LLVMBuilderRef builder
, LLVMValueRef fp
)
258 LLVMValueRef l
= LLVMBuildLoad(builder
, fp
, "");
259 LLVMValueRef uscaled
= LLVMBuildFPToSI(builder
, l
, LLVMIntType(16), "");
260 return LLVMBuildFMul(builder
, uscaled
,
261 LLVMConstReal(LLVMFloatType(), 32767.0f
), "");
264 static INLINE LLVMValueRef
265 to_32_snorm(LLVMBuilderRef builder
, LLVMValueRef fp
)
267 LLVMValueRef l
= LLVMBuildLoad(builder
, fp
, "");
268 LLVMValueRef uscaled
= LLVMBuildFPToSI(builder
, l
, LLVMIntType(32), "");
270 return LLVMBuildFMul(builder
, uscaled
,
271 LLVMConstReal(LLVMFloatType(), 2147483647.0), "");
274 static INLINE LLVMValueRef
275 to_32_fixed(LLVMBuilderRef builder
, LLVMValueRef fp
)
277 LLVMValueRef l
= LLVMBuildLoad(builder
, fp
, "");
278 LLVMValueRef uscaled
= LLVMBuildFPToSI(builder
, l
, LLVMIntType(32), "");
280 return LLVMBuildFMul(builder
, uscaled
,
281 LLVMConstReal(LLVMFloatType(), 65536.0), "");
284 typedef LLVMValueRef (*from_func
)(LLVMBuilderRef
, LLVMValueRef
);
285 typedef LLVMValueRef (*to_func
)(LLVMBuilderRef
, LLVMValueRef
);
287 /* so that underneath can avoid function calls which are prohibited
288 * for static initialization we need this conversion */
297 static INLINE LLVMTypeRef
298 ll_type_to_llvm(enum ll_type type
)
302 return LLVMDoubleType();
304 return LLVMFloatType();
306 return LLVMInt32Type();
308 return LLVMIntType(16);
310 return LLVMIntType(8);
312 return LLVMIntType(8);
316 ll_type_size(enum ll_type type
)
333 struct draw_llvm_translate
{
341 {PIPE_FORMAT_R64_FLOAT
, from_64_float
, to_64_float
, LL_Double
, 1},
342 {PIPE_FORMAT_R64G64_FLOAT
, from_64_float
, to_64_float
, LL_Double
, 2},
343 {PIPE_FORMAT_R64G64B64_FLOAT
, from_64_float
, to_64_float
, LL_Double
, 3},
344 {PIPE_FORMAT_R64G64B64A64_FLOAT
, from_64_float
, to_64_float
, LL_Double
, 4},
345 {PIPE_FORMAT_R32_FLOAT
, from_32_float
, to_32_float
, LL_Float
, 1},
346 {PIPE_FORMAT_R32G32_FLOAT
, from_32_float
, to_32_float
, LL_Float
, 2},
347 {PIPE_FORMAT_R32G32B32_FLOAT
, from_32_float
, to_32_float
, LL_Float
, 3},
348 {PIPE_FORMAT_R32G32B32A32_FLOAT
, from_32_float
, to_32_float
, LL_Float
, 4},
350 {PIPE_FORMAT_R32_UNORM
, from_32_unorm
, to_32_unorm
, LL_Int32
, 1},
351 {PIPE_FORMAT_R32G32_UNORM
, from_32_unorm
, to_32_unorm
, LL_Int32
, 2},
352 {PIPE_FORMAT_R32G32B32_UNORM
, from_32_unorm
, to_32_unorm
, LL_Int32
, 3},
353 {PIPE_FORMAT_R32G32B32A32_UNORM
, from_32_unorm
, to_32_unorm
, LL_Int32
, 4},
355 {PIPE_FORMAT_R32_USCALED
, from_32_uscaled
, to_32_uscaled
, LL_Int32
, 1},
356 {PIPE_FORMAT_R32G32_USCALED
, from_32_uscaled
, to_32_uscaled
, LL_Int32
, 2},
357 {PIPE_FORMAT_R32G32B32_USCALED
, from_32_uscaled
, to_32_uscaled
, LL_Int32
, 3},
358 {PIPE_FORMAT_R32G32B32A32_USCALED
, from_32_uscaled
, to_32_uscaled
, LL_Int32
, 4},
360 {PIPE_FORMAT_R32_SNORM
, from_32_snorm
, to_32_snorm
, LL_Int32
, 1},
361 {PIPE_FORMAT_R32G32_SNORM
, from_32_snorm
, to_32_snorm
, LL_Int32
, 2},
362 {PIPE_FORMAT_R32G32B32_SNORM
, from_32_snorm
, to_32_snorm
, LL_Int32
, 3},
363 {PIPE_FORMAT_R32G32B32A32_SNORM
, from_32_snorm
, to_32_snorm
, LL_Int32
, 4},
365 {PIPE_FORMAT_R32_SSCALED
, from_32_sscaled
, to_32_sscaled
, LL_Int32
, 1},
366 {PIPE_FORMAT_R32G32_SSCALED
, from_32_sscaled
, to_32_sscaled
, LL_Int32
, 2},
367 {PIPE_FORMAT_R32G32B32_SSCALED
, from_32_sscaled
, to_32_sscaled
, LL_Int32
, 3},
368 {PIPE_FORMAT_R32G32B32A32_SSCALED
, from_32_sscaled
, to_32_sscaled
, LL_Int32
, 4},
370 {PIPE_FORMAT_R16_UNORM
, from_16_unorm
, to_16_unorm
, LL_Int16
, 1},
371 {PIPE_FORMAT_R16G16_UNORM
, from_16_unorm
, to_16_unorm
, LL_Int16
, 2},
372 {PIPE_FORMAT_R16G16B16_UNORM
, from_16_unorm
, to_16_unorm
, LL_Int16
, 3},
373 {PIPE_FORMAT_R16G16B16A16_UNORM
, from_16_unorm
, to_16_unorm
, LL_Int16
, 4},
375 {PIPE_FORMAT_R16_USCALED
, from_16_uscaled
, to_16_uscaled
, LL_Int16
, 1},
376 {PIPE_FORMAT_R16G16_USCALED
, from_16_uscaled
, to_16_uscaled
, LL_Int16
, 2},
377 {PIPE_FORMAT_R16G16B16_USCALED
, from_16_uscaled
, to_16_uscaled
, LL_Int16
, 3},
378 {PIPE_FORMAT_R16G16B16A16_USCALED
, from_16_uscaled
, to_16_uscaled
, LL_Int16
, 4},
380 {PIPE_FORMAT_R16_SNORM
, from_16_snorm
, to_16_snorm
, LL_Int16
, 1},
381 {PIPE_FORMAT_R16G16_SNORM
, from_16_snorm
, to_16_snorm
, LL_Int16
, 2},
382 {PIPE_FORMAT_R16G16B16_SNORM
, from_16_snorm
, to_16_snorm
, LL_Int16
, 3},
383 {PIPE_FORMAT_R16G16B16A16_SNORM
, from_16_snorm
, to_16_snorm
, LL_Int16
, 4},
385 {PIPE_FORMAT_R16_SSCALED
, from_16_sscaled
, to_16_sscaled
, LL_Int16
, 1},
386 {PIPE_FORMAT_R16G16_SSCALED
, from_16_sscaled
, to_16_sscaled
, LL_Int16
, 2},
387 {PIPE_FORMAT_R16G16B16_SSCALED
, from_16_sscaled
, to_16_sscaled
, LL_Int16
, 3},
388 {PIPE_FORMAT_R16G16B16A16_SSCALED
, from_16_sscaled
, to_16_sscaled
, LL_Int16
, 4},
390 {PIPE_FORMAT_R8_UNORM
, from_8_unorm
, to_8_unorm
, LL_Int8
, 1},
391 {PIPE_FORMAT_R8G8_UNORM
, from_8_unorm
, to_8_unorm
, LL_Int8
, 2},
392 {PIPE_FORMAT_R8G8B8_UNORM
, from_8_unorm
, to_8_unorm
, LL_Int8
, 3},
393 {PIPE_FORMAT_R8G8B8A8_UNORM
, from_8_unorm
, to_8_unorm
, LL_Int8
, 4},
395 {PIPE_FORMAT_R8_USCALED
, from_8_uscaled
, to_8_uscaled
, LL_Int8
, 1},
396 {PIPE_FORMAT_R8G8_USCALED
, from_8_uscaled
, to_8_uscaled
, LL_Int8
, 2},
397 {PIPE_FORMAT_R8G8B8_USCALED
, from_8_uscaled
, to_8_uscaled
, LL_Int8
, 3},
398 {PIPE_FORMAT_R8G8B8A8_USCALED
, from_8_uscaled
, to_8_uscaled
, LL_Int8
, 4},
400 {PIPE_FORMAT_R8_SNORM
, from_8_snorm
, to_8_snorm
, LL_Int8
, 1},
401 {PIPE_FORMAT_R8G8_SNORM
, from_8_snorm
, to_8_snorm
, LL_Int8
, 2},
402 {PIPE_FORMAT_R8G8B8_SNORM
, from_8_snorm
, to_8_snorm
, LL_Int8
, 3},
403 {PIPE_FORMAT_R8G8B8A8_SNORM
, from_8_snorm
, to_8_snorm
, LL_Int8
, 4},
405 {PIPE_FORMAT_R8_SSCALED
, from_8_sscaled
, to_8_sscaled
, LL_Int8
, 1},
406 {PIPE_FORMAT_R8G8_SSCALED
, from_8_sscaled
, to_8_sscaled
, LL_Int8
, 2},
407 {PIPE_FORMAT_R8G8B8_SSCALED
, from_8_sscaled
, to_8_sscaled
, LL_Int8
, 3},
408 {PIPE_FORMAT_R8G8B8A8_SSCALED
, from_8_sscaled
, to_8_sscaled
, LL_Int8
, 4},
410 {PIPE_FORMAT_R32_FIXED
, from_32_fixed
, to_32_fixed
, LL_Int32
, 1},
411 {PIPE_FORMAT_R32G32_FIXED
, from_32_fixed
, to_32_fixed
, LL_Int32
, 2},
412 {PIPE_FORMAT_R32G32B32_FIXED
, from_32_fixed
, to_32_fixed
, LL_Int32
, 3},
413 {PIPE_FORMAT_R32G32B32A32_FIXED
, from_32_fixed
, to_32_fixed
, LL_Int32
, 4},
418 fetch(LLVMBuilderRef builder
,
419 LLVMValueRef ptr
, int val_size
, int nr_components
,
424 LLVMValueRef res
= LLVMConstNull(
425 LLVMVectorType(LLVMFloatType(), 4));
426 LLVMValueRef defaults
[4];
428 defaults
[0] = LLVMConstReal(LLVMFloatType(), 0);
429 defaults
[1] = LLVMConstReal(LLVMFloatType(), 0);
430 defaults
[2] = LLVMConstReal(LLVMFloatType(), 0);
431 defaults
[3] = LLVMConstReal(LLVMFloatType(), 1);
433 for (i
= 0; i
< nr_components
; ++i
) {
434 LLVMValueRef src_index
= LLVMConstInt(LLVMInt32Type(), offset
, 0);
435 LLVMValueRef dst_index
= LLVMConstInt(LLVMInt32Type(), i
, 0);
436 LLVMValueRef src_tmp
;
437 LLVMValueRef component
;
439 src_tmp
= LLVMBuildGEP(builder
, ptr
, &src_index
, 1, "src_tmp");
441 /* convert src_tmp to float */
442 component
= func(builder
, src_tmp
);
444 /* vec.comp = component */
445 res
= LLVMBuildInsertElement(builder
,
452 LLVMValueRef dst_index
= LLVMConstInt(LLVMInt32Type(), i
, 0);
453 res
= LLVMBuildInsertElement(builder
,
463 draw_llvm_translate_from(LLVMBuilderRef builder
,
464 LLVMValueRef vbuffer
,
465 enum pipe_format from_format
)
467 const struct util_format_description
*format_desc
;
470 struct lp_type type
= lp_float32_vec4_type();
473 * The above can only cope with straight arrays: no bitfields,
474 * swizzles, or half floats.
477 for (i
= 0; i
< Elements(translates
); ++i
) {
478 if (translates
[i
].format
== from_format
) {
479 /*LLVMTypeRef type = ll_type_to_llvm(translates[i].type);*/
480 return fetch(builder
,
482 ll_type_size(translates
[i
].type
),
483 translates
[i
].num_components
,
490 * This doesn't handle anything bigger than 32bits, or half floats
493 * TODO: unify all this code into lp_build_fetch_rgba_aos().
496 format_desc
= util_format_description(from_format
);
497 zero
= LLVMConstNull(LLVMInt32Type());
498 return lp_build_fetch_rgba_aos(builder
, format_desc
, type
, vbuffer
, zero
, zero
, zero
);