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"
11 #include "util/u_memory.h"
12 #include "util/u_format.h"
13 #include "pipe/p_state.h"
19 from_64_float(LLVMBuilderRef builder
, LLVMValueRef val
)
21 LLVMValueRef bc
= LLVMBuildBitCast(builder
, val
,
22 LLVMPointerType(LLVMDoubleType(), 0) , "");
23 LLVMValueRef l
= LLVMBuildLoad(builder
, bc
, "");
24 return LLVMBuildFPTrunc(builder
, l
, LLVMFloatType(), "");
28 from_32_float(LLVMBuilderRef builder
, LLVMValueRef val
)
30 LLVMValueRef bc
= LLVMBuildBitCast(builder
, val
,
31 LLVMPointerType(LLVMFloatType(), 0) , "");
32 return LLVMBuildLoad(builder
, bc
, "");
35 static INLINE LLVMValueRef
36 from_8_uscaled(LLVMBuilderRef builder
, LLVMValueRef val
)
38 LLVMValueRef l
= LLVMBuildLoad(builder
, val
, "");
39 return LLVMBuildUIToFP(builder
, l
, LLVMFloatType(), "");
42 static INLINE LLVMValueRef
43 from_16_uscaled(LLVMBuilderRef builder
, LLVMValueRef val
)
45 LLVMValueRef bc
= LLVMBuildBitCast(builder
, val
,
46 LLVMPointerType(LLVMIntType(16), 0) , "");
47 LLVMValueRef l
= LLVMBuildLoad(builder
, bc
, "");
48 return LLVMBuildUIToFP(builder
, l
, LLVMFloatType(), "");
51 static INLINE LLVMValueRef
52 from_32_uscaled(LLVMBuilderRef builder
, LLVMValueRef val
)
54 LLVMValueRef bc
= LLVMBuildBitCast(builder
, val
,
55 LLVMPointerType(LLVMIntType(32), 0) , "");
56 LLVMValueRef l
= LLVMBuildLoad(builder
, bc
, "");
57 return LLVMBuildUIToFP(builder
, l
, LLVMFloatType(), "");
60 static INLINE LLVMValueRef
61 from_8_sscaled(LLVMBuilderRef builder
, LLVMValueRef val
)
63 LLVMValueRef l
= LLVMBuildLoad(builder
, val
, "");
64 return LLVMBuildSIToFP(builder
, l
, LLVMFloatType(), "");
67 static INLINE LLVMValueRef
68 from_16_sscaled(LLVMBuilderRef builder
, LLVMValueRef val
)
70 LLVMValueRef bc
= LLVMBuildBitCast(builder
, val
,
71 LLVMPointerType(LLVMIntType(16), 0) , "");
72 LLVMValueRef l
= LLVMBuildLoad(builder
, bc
, "");
73 return LLVMBuildSIToFP(builder
, l
, LLVMFloatType(), "");
76 static INLINE LLVMValueRef
77 from_32_sscaled(LLVMBuilderRef builder
, LLVMValueRef val
)
79 LLVMValueRef bc
= LLVMBuildBitCast(builder
, val
,
80 LLVMPointerType(LLVMIntType(32), 0) , "");
81 LLVMValueRef l
= LLVMBuildLoad(builder
, bc
, "");
82 return LLVMBuildSIToFP(builder
, l
, LLVMFloatType(), "");
86 static INLINE LLVMValueRef
87 from_8_unorm(LLVMBuilderRef builder
, LLVMValueRef val
)
89 LLVMValueRef l
= LLVMBuildLoad(builder
, val
, "");
90 LLVMValueRef uscaled
= LLVMBuildUIToFP(builder
, l
, LLVMFloatType(), "");
91 return LLVMBuildFDiv(builder
, uscaled
,
92 LLVMConstReal(LLVMFloatType(), 255.), "");
95 static INLINE LLVMValueRef
96 from_16_unorm(LLVMBuilderRef builder
, LLVMValueRef val
)
98 LLVMValueRef bc
= LLVMBuildBitCast(builder
, val
,
99 LLVMPointerType(LLVMIntType(16), 0) , "");
100 LLVMValueRef l
= LLVMBuildLoad(builder
, bc
, "");
101 LLVMValueRef uscaled
= LLVMBuildUIToFP(builder
, l
, LLVMFloatType(), "");
102 return LLVMBuildFDiv(builder
, uscaled
,
103 LLVMConstReal(LLVMFloatType(), 65535.), "");
106 static INLINE LLVMValueRef
107 from_32_unorm(LLVMBuilderRef builder
, LLVMValueRef val
)
109 LLVMValueRef bc
= LLVMBuildBitCast(builder
, val
,
110 LLVMPointerType(LLVMIntType(32), 0) , "");
111 LLVMValueRef l
= LLVMBuildLoad(builder
, bc
, "");
112 LLVMValueRef uscaled
= LLVMBuildUIToFP(builder
, l
, LLVMFloatType(), "");
114 return LLVMBuildFDiv(builder
, uscaled
,
115 LLVMConstReal(LLVMFloatType(), 4294967295.), "");
118 static INLINE LLVMValueRef
119 from_8_snorm(LLVMBuilderRef builder
, LLVMValueRef val
)
121 LLVMValueRef l
= LLVMBuildLoad(builder
, val
, "");
122 LLVMValueRef uscaled
= LLVMBuildSIToFP(builder
, l
, LLVMFloatType(), "");
123 return LLVMBuildFDiv(builder
, uscaled
,
124 LLVMConstReal(LLVMFloatType(), 127.0), "");
127 static INLINE LLVMValueRef
128 from_16_snorm(LLVMBuilderRef builder
, LLVMValueRef val
)
130 LLVMValueRef bc
= LLVMBuildBitCast(builder
, val
,
131 LLVMPointerType(LLVMIntType(16), 0) , "");
132 LLVMValueRef l
= LLVMBuildLoad(builder
, bc
, "");
133 LLVMValueRef uscaled
= LLVMBuildSIToFP(builder
, l
, LLVMFloatType(), "");
134 return LLVMBuildFDiv(builder
, uscaled
,
135 LLVMConstReal(LLVMFloatType(), 32767.0f
), "");
138 static INLINE LLVMValueRef
139 from_32_snorm(LLVMBuilderRef builder
, LLVMValueRef val
)
141 LLVMValueRef bc
= LLVMBuildBitCast(builder
, val
,
142 LLVMPointerType(LLVMIntType(32), 0) , "");
143 LLVMValueRef l
= LLVMBuildLoad(builder
, bc
, "");
144 LLVMValueRef uscaled
= LLVMBuildSIToFP(builder
, l
, LLVMFloatType(), "");
146 return LLVMBuildFDiv(builder
, uscaled
,
147 LLVMConstReal(LLVMFloatType(), 2147483647.0), "");
150 static INLINE LLVMValueRef
151 from_32_fixed(LLVMBuilderRef builder
, LLVMValueRef val
)
153 LLVMValueRef bc
= LLVMBuildBitCast(builder
, val
,
154 LLVMPointerType(LLVMIntType(32), 0) , "");
155 LLVMValueRef l
= LLVMBuildLoad(builder
, bc
, "");
156 LLVMValueRef uscaled
= LLVMBuildSIToFP(builder
, l
, LLVMFloatType(), "");
158 return LLVMBuildFDiv(builder
, uscaled
,
159 LLVMConstReal(LLVMFloatType(), 65536.0), "");
163 to_64_float(LLVMBuilderRef builder
, LLVMValueRef fp
)
165 LLVMValueRef l
= LLVMBuildLoad(builder
, fp
, "");
166 return LLVMBuildFPExt(builder
, l
, LLVMDoubleType(), "");
170 to_32_float(LLVMBuilderRef builder
, LLVMValueRef fp
)
172 return LLVMBuildLoad(builder
, fp
, "");
175 static INLINE LLVMValueRef
176 to_8_uscaled(LLVMBuilderRef builder
, LLVMValueRef fp
)
178 LLVMValueRef l
= LLVMBuildLoad(builder
, fp
, "");
179 return LLVMBuildFPToUI(builder
, l
, LLVMIntType(8), "");
182 static INLINE LLVMValueRef
183 to_16_uscaled(LLVMBuilderRef builder
, LLVMValueRef fp
)
185 LLVMValueRef l
= LLVMBuildLoad(builder
, fp
, "");
186 return LLVMBuildFPToUI(builder
, l
, LLVMIntType(16), "");
189 static INLINE LLVMValueRef
190 to_32_uscaled(LLVMBuilderRef builder
, LLVMValueRef fp
)
192 LLVMValueRef l
= LLVMBuildLoad(builder
, fp
, "");
193 return LLVMBuildFPToUI(builder
, l
, LLVMIntType(32), "");
196 static INLINE LLVMValueRef
197 to_8_sscaled(LLVMBuilderRef builder
, LLVMValueRef fp
)
199 LLVMValueRef l
= LLVMBuildLoad(builder
, fp
, "");
200 return LLVMBuildFPToSI(builder
, l
, LLVMIntType(8), "");
203 static INLINE LLVMValueRef
204 to_16_sscaled(LLVMBuilderRef builder
, LLVMValueRef fp
)
206 LLVMValueRef l
= LLVMBuildLoad(builder
, fp
, "");
207 return LLVMBuildFPToSI(builder
, l
, LLVMIntType(16), "");
210 static INLINE LLVMValueRef
211 to_32_sscaled(LLVMBuilderRef builder
, LLVMValueRef fp
)
213 LLVMValueRef l
= LLVMBuildLoad(builder
, fp
, "");
214 return LLVMBuildFPToSI(builder
, l
, LLVMIntType(32), "");
217 static INLINE LLVMValueRef
218 to_8_unorm(LLVMBuilderRef builder
, LLVMValueRef fp
)
220 LLVMValueRef l
= LLVMBuildLoad(builder
, fp
, "");
221 LLVMValueRef uscaled
= LLVMBuildFPToUI(builder
, l
, LLVMIntType(8), "");
222 return LLVMBuildFMul(builder
, uscaled
,
223 LLVMConstReal(LLVMFloatType(), 255.), "");
226 static INLINE LLVMValueRef
227 to_16_unorm(LLVMBuilderRef builder
, LLVMValueRef fp
)
229 LLVMValueRef l
= LLVMBuildLoad(builder
, fp
, "");
230 LLVMValueRef uscaled
= LLVMBuildFPToUI(builder
, l
, LLVMIntType(32), "");
231 return LLVMBuildFMul(builder
, uscaled
,
232 LLVMConstReal(LLVMFloatType(), 65535.), "");
235 static INLINE LLVMValueRef
236 to_32_unorm(LLVMBuilderRef builder
, LLVMValueRef fp
)
238 LLVMValueRef l
= LLVMBuildLoad(builder
, fp
, "");
239 LLVMValueRef uscaled
= LLVMBuildFPToUI(builder
, l
, LLVMIntType(32), "");
241 return LLVMBuildFMul(builder
, uscaled
,
242 LLVMConstReal(LLVMFloatType(), 4294967295.), "");
245 static INLINE LLVMValueRef
246 to_8_snorm(LLVMBuilderRef builder
, LLVMValueRef val
)
248 LLVMValueRef l
= LLVMBuildLoad(builder
, val
, "");
249 LLVMValueRef uscaled
= LLVMBuildFPToSI(builder
, l
, LLVMIntType(8), "");
250 return LLVMBuildFMul(builder
, uscaled
,
251 LLVMConstReal(LLVMFloatType(), 127.0), "");
254 static INLINE LLVMValueRef
255 to_16_snorm(LLVMBuilderRef builder
, LLVMValueRef fp
)
257 LLVMValueRef l
= LLVMBuildLoad(builder
, fp
, "");
258 LLVMValueRef uscaled
= LLVMBuildFPToSI(builder
, l
, LLVMIntType(16), "");
259 return LLVMBuildFMul(builder
, uscaled
,
260 LLVMConstReal(LLVMFloatType(), 32767.0f
), "");
263 static INLINE LLVMValueRef
264 to_32_snorm(LLVMBuilderRef builder
, LLVMValueRef fp
)
266 LLVMValueRef l
= LLVMBuildLoad(builder
, fp
, "");
267 LLVMValueRef uscaled
= LLVMBuildFPToSI(builder
, l
, LLVMIntType(32), "");
269 return LLVMBuildFMul(builder
, uscaled
,
270 LLVMConstReal(LLVMFloatType(), 2147483647.0), "");
273 static INLINE LLVMValueRef
274 to_32_fixed(LLVMBuilderRef builder
, LLVMValueRef fp
)
276 LLVMValueRef l
= LLVMBuildLoad(builder
, fp
, "");
277 LLVMValueRef uscaled
= LLVMBuildFPToSI(builder
, l
, LLVMIntType(32), "");
279 return LLVMBuildFMul(builder
, uscaled
,
280 LLVMConstReal(LLVMFloatType(), 65536.0), "");
283 typedef LLVMValueRef (*from_func
)(LLVMBuilderRef
, LLVMValueRef
);
284 typedef LLVMValueRef (*to_func
)(LLVMBuilderRef
, LLVMValueRef
);
286 /* so that underneath can avoid function calls which are prohibited
287 * for static initialization we need this conversion */
296 static INLINE LLVMTypeRef
297 ll_type_to_llvm(enum ll_type type
)
301 return LLVMDoubleType();
303 return LLVMFloatType();
305 return LLVMInt32Type();
307 return LLVMIntType(16);
309 return LLVMIntType(8);
311 return LLVMIntType(8);
315 ll_type_size(enum ll_type type
)
332 struct draw_llvm_translate
{
340 {PIPE_FORMAT_R64_FLOAT
, from_64_float
, to_64_float
, LL_Double
, 1},
341 {PIPE_FORMAT_R64G64_FLOAT
, from_64_float
, to_64_float
, LL_Double
, 2},
342 {PIPE_FORMAT_R64G64B64_FLOAT
, from_64_float
, to_64_float
, LL_Double
, 3},
343 {PIPE_FORMAT_R64G64B64A64_FLOAT
, from_64_float
, to_64_float
, LL_Double
, 4},
344 {PIPE_FORMAT_R32_FLOAT
, from_32_float
, to_32_float
, LL_Float
, 1},
345 {PIPE_FORMAT_R32G32_FLOAT
, from_32_float
, to_32_float
, LL_Float
, 2},
346 {PIPE_FORMAT_R32G32B32_FLOAT
, from_32_float
, to_32_float
, LL_Float
, 3},
347 {PIPE_FORMAT_R32G32B32A32_FLOAT
, from_32_float
, to_32_float
, LL_Float
, 4},
349 {PIPE_FORMAT_R32_UNORM
, from_32_unorm
, to_32_unorm
, LL_Int32
, 1},
350 {PIPE_FORMAT_R32G32_UNORM
, from_32_unorm
, to_32_unorm
, LL_Int32
, 2},
351 {PIPE_FORMAT_R32G32B32_UNORM
, from_32_unorm
, to_32_unorm
, LL_Int32
, 3},
352 {PIPE_FORMAT_R32G32B32A32_UNORM
, from_32_unorm
, to_32_unorm
, LL_Int32
, 4},
354 {PIPE_FORMAT_R32_USCALED
, from_32_uscaled
, to_32_uscaled
, LL_Int32
, 1},
355 {PIPE_FORMAT_R32G32_USCALED
, from_32_uscaled
, to_32_uscaled
, LL_Int32
, 2},
356 {PIPE_FORMAT_R32G32B32_USCALED
, from_32_uscaled
, to_32_uscaled
, LL_Int32
, 3},
357 {PIPE_FORMAT_R32G32B32A32_USCALED
, from_32_uscaled
, to_32_uscaled
, LL_Int32
, 4},
359 {PIPE_FORMAT_R32_SNORM
, from_32_snorm
, to_32_snorm
, LL_Int32
, 1},
360 {PIPE_FORMAT_R32G32_SNORM
, from_32_snorm
, to_32_snorm
, LL_Int32
, 2},
361 {PIPE_FORMAT_R32G32B32_SNORM
, from_32_snorm
, to_32_snorm
, LL_Int32
, 3},
362 {PIPE_FORMAT_R32G32B32A32_SNORM
, from_32_snorm
, to_32_snorm
, LL_Int32
, 4},
364 {PIPE_FORMAT_R32_SSCALED
, from_32_sscaled
, to_32_sscaled
, LL_Int32
, 1},
365 {PIPE_FORMAT_R32G32_SSCALED
, from_32_sscaled
, to_32_sscaled
, LL_Int32
, 2},
366 {PIPE_FORMAT_R32G32B32_SSCALED
, from_32_sscaled
, to_32_sscaled
, LL_Int32
, 3},
367 {PIPE_FORMAT_R32G32B32A32_SSCALED
, from_32_sscaled
, to_32_sscaled
, LL_Int32
, 4},
369 {PIPE_FORMAT_R16_UNORM
, from_16_unorm
, to_16_unorm
, LL_Int16
, 1},
370 {PIPE_FORMAT_R16G16_UNORM
, from_16_unorm
, to_16_unorm
, LL_Int16
, 2},
371 {PIPE_FORMAT_R16G16B16_UNORM
, from_16_unorm
, to_16_unorm
, LL_Int16
, 3},
372 {PIPE_FORMAT_R16G16B16A16_UNORM
, from_16_unorm
, to_16_unorm
, LL_Int16
, 4},
374 {PIPE_FORMAT_R16_USCALED
, from_16_uscaled
, to_16_uscaled
, LL_Int16
, 1},
375 {PIPE_FORMAT_R16G16_USCALED
, from_16_uscaled
, to_16_uscaled
, LL_Int16
, 2},
376 {PIPE_FORMAT_R16G16B16_USCALED
, from_16_uscaled
, to_16_uscaled
, LL_Int16
, 3},
377 {PIPE_FORMAT_R16G16B16A16_USCALED
, from_16_uscaled
, to_16_uscaled
, LL_Int16
, 4},
379 {PIPE_FORMAT_R16_SNORM
, from_16_snorm
, to_16_snorm
, LL_Int16
, 1},
380 {PIPE_FORMAT_R16G16_SNORM
, from_16_snorm
, to_16_snorm
, LL_Int16
, 2},
381 {PIPE_FORMAT_R16G16B16_SNORM
, from_16_snorm
, to_16_snorm
, LL_Int16
, 3},
382 {PIPE_FORMAT_R16G16B16A16_SNORM
, from_16_snorm
, to_16_snorm
, LL_Int16
, 4},
384 {PIPE_FORMAT_R16_SSCALED
, from_16_sscaled
, to_16_sscaled
, LL_Int16
, 1},
385 {PIPE_FORMAT_R16G16_SSCALED
, from_16_sscaled
, to_16_sscaled
, LL_Int16
, 2},
386 {PIPE_FORMAT_R16G16B16_SSCALED
, from_16_sscaled
, to_16_sscaled
, LL_Int16
, 3},
387 {PIPE_FORMAT_R16G16B16A16_SSCALED
, from_16_sscaled
, to_16_sscaled
, LL_Int16
, 4},
389 {PIPE_FORMAT_R8_UNORM
, from_8_unorm
, to_8_unorm
, LL_Int8
, 1},
390 {PIPE_FORMAT_R8G8_UNORM
, from_8_unorm
, to_8_unorm
, LL_Int8
, 2},
391 {PIPE_FORMAT_R8G8B8_UNORM
, from_8_unorm
, to_8_unorm
, LL_Int8
, 3},
392 {PIPE_FORMAT_R8G8B8A8_UNORM
, from_8_unorm
, to_8_unorm
, LL_Int8
, 4},
394 {PIPE_FORMAT_R8_USCALED
, from_8_uscaled
, to_8_uscaled
, LL_Int8
, 1},
395 {PIPE_FORMAT_R8G8_USCALED
, from_8_uscaled
, to_8_uscaled
, LL_Int8
, 2},
396 {PIPE_FORMAT_R8G8B8_USCALED
, from_8_uscaled
, to_8_uscaled
, LL_Int8
, 3},
397 {PIPE_FORMAT_R8G8B8A8_USCALED
, from_8_uscaled
, to_8_uscaled
, LL_Int8
, 4},
399 {PIPE_FORMAT_R8_SNORM
, from_8_snorm
, to_8_snorm
, LL_Int8
, 1},
400 {PIPE_FORMAT_R8G8_SNORM
, from_8_snorm
, to_8_snorm
, LL_Int8
, 2},
401 {PIPE_FORMAT_R8G8B8_SNORM
, from_8_snorm
, to_8_snorm
, LL_Int8
, 3},
402 {PIPE_FORMAT_R8G8B8A8_SNORM
, from_8_snorm
, to_8_snorm
, LL_Int8
, 4},
404 {PIPE_FORMAT_R8_SSCALED
, from_8_sscaled
, to_8_sscaled
, LL_Int8
, 1},
405 {PIPE_FORMAT_R8G8_SSCALED
, from_8_sscaled
, to_8_sscaled
, LL_Int8
, 2},
406 {PIPE_FORMAT_R8G8B8_SSCALED
, from_8_sscaled
, to_8_sscaled
, LL_Int8
, 3},
407 {PIPE_FORMAT_R8G8B8A8_SSCALED
, from_8_sscaled
, to_8_sscaled
, LL_Int8
, 4},
409 {PIPE_FORMAT_R32_FIXED
, from_32_fixed
, to_32_fixed
, LL_Int32
, 1},
410 {PIPE_FORMAT_R32G32_FIXED
, from_32_fixed
, to_32_fixed
, LL_Int32
, 2},
411 {PIPE_FORMAT_R32G32B32_FIXED
, from_32_fixed
, to_32_fixed
, LL_Int32
, 3},
412 {PIPE_FORMAT_R32G32B32A32_FIXED
, from_32_fixed
, to_32_fixed
, LL_Int32
, 4},
417 fetch(LLVMBuilderRef builder
,
418 LLVMValueRef ptr
, int val_size
, int nr_components
,
423 LLVMValueRef res
= LLVMConstNull(
424 LLVMVectorType(LLVMFloatType(), 4));
425 LLVMValueRef defaults
[4];
427 defaults
[0] = LLVMConstReal(LLVMFloatType(), 0);
428 defaults
[1] = LLVMConstReal(LLVMFloatType(), 0);
429 defaults
[2] = LLVMConstReal(LLVMFloatType(), 0);
430 defaults
[3] = LLVMConstReal(LLVMFloatType(), 1);
432 for (i
= 0; i
< nr_components
; ++i
) {
433 LLVMValueRef src_index
= LLVMConstInt(LLVMInt32Type(), offset
, 0);
434 LLVMValueRef dst_index
= LLVMConstInt(LLVMInt32Type(), i
, 0);
435 LLVMValueRef src_tmp
;
436 LLVMValueRef component
;
438 src_tmp
= LLVMBuildGEP(builder
, ptr
, &src_index
, 1, "src_tmp");
440 /* convert src_tmp to float */
441 component
= func(builder
, src_tmp
);
443 /* vec.comp = component */
444 res
= LLVMBuildInsertElement(builder
,
451 LLVMValueRef dst_index
= LLVMConstInt(LLVMInt32Type(), i
, 0);
452 res
= LLVMBuildInsertElement(builder
,
462 draw_llvm_translate_from(LLVMBuilderRef builder
,
463 LLVMValueRef vbuffer
,
464 enum pipe_format from_format
)
466 const struct util_format_description
*format_desc
;
471 * The above can only cope with straight arrays: no bitfields,
472 * swizzles, or half floats.
475 for (i
= 0; i
< Elements(translates
); ++i
) {
476 if (translates
[i
].format
== from_format
) {
477 /*LLVMTypeRef type = ll_type_to_llvm(translates[i].type);*/
478 return fetch(builder
,
480 ll_type_size(translates
[i
].type
),
481 translates
[i
].num_components
,
488 * This doesn't handle anything bigger than 32bits, or half floats
491 * TODO: unify all this code into lp_build_fetch_rgba_aos().
494 format_desc
= util_format_description(from_format
);
495 zero
= LLVMConstNull(LLVMInt32Type());
496 return lp_build_fetch_rgba_aos(builder
, format_desc
, vbuffer
, zero
, zero
);