draw llvm: we translate between pointers, not values directly
[mesa.git] / src / gallium / auxiliary / draw / draw_llvm_translate.c
1 #include "draw_private.h"
2 #include "draw_context.h"
3
4 #include "draw_llvm.h"
5
6 #include "gallivm/lp_bld_arit.h"
7 #include "gallivm/lp_bld_interp.h"
8 #include "gallivm/lp_bld_struct.h"
9 #include "gallivm/lp_bld_type.h"
10 #include "gallivm/lp_bld_flow.h"
11 #include "gallivm/lp_bld_debug.h"
12 #include "gallivm/lp_bld_tgsi.h"
13
14 #include "util/u_memory.h"
15 #include "pipe/p_state.h"
16
17
18 #define DRAW_DBG 0
19
20 static LLVMValueRef
21 from_64_float(LLVMBuilderRef builder, LLVMValueRef val)
22 {
23 LLVMValueRef bc = LLVMBuildBitCast(builder, val,
24 LLVMPointerType(LLVMDoubleType(), 0) , "");
25 LLVMValueRef l = LLVMBuildLoad(builder, bc, "");
26 return LLVMBuildFPTrunc(builder, l, LLVMFloatType(), "");
27 }
28
29 static LLVMValueRef
30 from_32_float(LLVMBuilderRef builder, LLVMValueRef val)
31 {
32 LLVMValueRef bc = LLVMBuildBitCast(builder, val,
33 LLVMPointerType(LLVMFloatType(), 0) , "");
34 return LLVMBuildLoad(builder, bc, "");
35 }
36
37 static INLINE LLVMValueRef
38 from_8_uscaled(LLVMBuilderRef builder, LLVMValueRef val)
39 {
40 LLVMValueRef l = LLVMBuildLoad(builder, val, "");
41 return LLVMBuildUIToFP(builder, l, LLVMFloatType(), "");
42 }
43
44 static INLINE LLVMValueRef
45 from_16_uscaled(LLVMBuilderRef builder, LLVMValueRef val)
46 {
47 LLVMValueRef bc = LLVMBuildBitCast(builder, val,
48 LLVMPointerType(LLVMIntType(16), 0) , "");
49 LLVMValueRef l = LLVMBuildLoad(builder, bc, "");
50 return LLVMBuildUIToFP(builder, l, LLVMFloatType(), "");
51 }
52
53 static INLINE LLVMValueRef
54 from_32_uscaled(LLVMBuilderRef builder, LLVMValueRef val)
55 {
56 LLVMValueRef bc = LLVMBuildBitCast(builder, val,
57 LLVMPointerType(LLVMIntType(32), 0) , "");
58 LLVMValueRef l = LLVMBuildLoad(builder, bc, "");
59 return LLVMBuildUIToFP(builder, l, LLVMFloatType(), "");
60 }
61
62 static INLINE LLVMValueRef
63 from_8_sscaled(LLVMBuilderRef builder, LLVMValueRef val)
64 {
65 LLVMValueRef l = LLVMBuildLoad(builder, val, "");
66 return LLVMBuildSIToFP(builder, l, LLVMFloatType(), "");
67 }
68
69 static INLINE LLVMValueRef
70 from_16_sscaled(LLVMBuilderRef builder, LLVMValueRef val)
71 {
72 LLVMValueRef bc = LLVMBuildBitCast(builder, val,
73 LLVMPointerType(LLVMIntType(16), 0) , "");
74 LLVMValueRef l = LLVMBuildLoad(builder, bc, "");
75 return LLVMBuildSIToFP(builder, l, LLVMFloatType(), "");
76 }
77
78 static INLINE LLVMValueRef
79 from_32_sscaled(LLVMBuilderRef builder, LLVMValueRef val)
80 {
81 LLVMValueRef bc = LLVMBuildBitCast(builder, val,
82 LLVMPointerType(LLVMIntType(32), 0) , "");
83 LLVMValueRef l = LLVMBuildLoad(builder, bc, "");
84 return LLVMBuildSIToFP(builder, l, LLVMFloatType(), "");
85 }
86
87
88 static INLINE LLVMValueRef
89 from_8_unorm(LLVMBuilderRef builder, LLVMValueRef val)
90 {
91 LLVMValueRef l = LLVMBuildLoad(builder, val, "");
92 LLVMValueRef uscaled = LLVMBuildUIToFP(builder, l, LLVMFloatType(), "");
93 return LLVMBuildFDiv(builder, uscaled,
94 LLVMConstReal(LLVMFloatType(), 255.), "");
95 }
96
97 static INLINE LLVMValueRef
98 from_16_unorm(LLVMBuilderRef builder, LLVMValueRef val)
99 {
100 LLVMValueRef bc = LLVMBuildBitCast(builder, val,
101 LLVMPointerType(LLVMIntType(16), 0) , "");
102 LLVMValueRef l = LLVMBuildLoad(builder, bc, "");
103 LLVMValueRef uscaled = LLVMBuildUIToFP(builder, l, LLVMFloatType(), "");
104 return LLVMBuildFDiv(builder, uscaled,
105 LLVMConstReal(LLVMFloatType(), 65535.), "");
106 }
107
108 static INLINE LLVMValueRef
109 from_32_unorm(LLVMBuilderRef builder, LLVMValueRef val)
110 {
111 LLVMValueRef bc = LLVMBuildBitCast(builder, val,
112 LLVMPointerType(LLVMIntType(32), 0) , "");
113 LLVMValueRef l = LLVMBuildLoad(builder, bc, "");
114 LLVMValueRef uscaled = LLVMBuildUIToFP(builder, l, LLVMFloatType(), "");
115
116 return LLVMBuildFDiv(builder, uscaled,
117 LLVMConstReal(LLVMFloatType(), 4294967295.), "");
118 }
119
120 static INLINE LLVMValueRef
121 from_8_snorm(LLVMBuilderRef builder, LLVMValueRef val)
122 {
123 LLVMValueRef l = LLVMBuildLoad(builder, val, "");
124 LLVMValueRef uscaled = LLVMBuildSIToFP(builder, l, LLVMFloatType(), "");
125 return LLVMBuildFDiv(builder, uscaled,
126 LLVMConstReal(LLVMFloatType(), 127.0), "");
127 }
128
129 static INLINE LLVMValueRef
130 from_16_snorm(LLVMBuilderRef builder, LLVMValueRef val)
131 {
132 LLVMValueRef bc = LLVMBuildBitCast(builder, val,
133 LLVMPointerType(LLVMIntType(16), 0) , "");
134 LLVMValueRef l = LLVMBuildLoad(builder, bc, "");
135 LLVMValueRef uscaled = LLVMBuildSIToFP(builder, l, LLVMFloatType(), "");
136 return LLVMBuildFDiv(builder, uscaled,
137 LLVMConstReal(LLVMFloatType(), 32767.0f), "");
138 }
139
140 static INLINE LLVMValueRef
141 from_32_snorm(LLVMBuilderRef builder, LLVMValueRef val)
142 {
143 LLVMValueRef bc = LLVMBuildBitCast(builder, val,
144 LLVMPointerType(LLVMIntType(32), 0) , "");
145 LLVMValueRef l = LLVMBuildLoad(builder, bc, "");
146 LLVMValueRef uscaled = LLVMBuildSIToFP(builder, l, LLVMFloatType(), "");
147
148 return LLVMBuildFDiv(builder, uscaled,
149 LLVMConstReal(LLVMFloatType(), 2147483647.0), "");
150 }
151
152 static INLINE LLVMValueRef
153 from_32_fixed(LLVMBuilderRef builder, LLVMValueRef val)
154 {
155 LLVMValueRef bc = LLVMBuildBitCast(builder, val,
156 LLVMPointerType(LLVMIntType(32), 0) , "");
157 LLVMValueRef l = LLVMBuildLoad(builder, bc, "");
158 LLVMValueRef uscaled = LLVMBuildSIToFP(builder, l, LLVMFloatType(), "");
159
160 return LLVMBuildFDiv(builder, uscaled,
161 LLVMConstReal(LLVMFloatType(), 65536.0), "");
162 }
163
164 static LLVMValueRef
165 to_64_float(LLVMBuilderRef builder, LLVMValueRef fp)
166 {
167 LLVMValueRef l = LLVMBuildLoad(builder, fp, "");
168 return LLVMBuildFPExt(builder, l, LLVMDoubleType(), "");
169 }
170
171 static LLVMValueRef
172 to_32_float(LLVMBuilderRef builder, LLVMValueRef fp)
173 {
174 return LLVMBuildLoad(builder, fp, "");
175 }
176
177 static INLINE LLVMValueRef
178 to_8_uscaled(LLVMBuilderRef builder, LLVMValueRef fp)
179 {
180 LLVMValueRef l = LLVMBuildLoad(builder, fp, "");
181 return LLVMBuildFPToUI(builder, l, LLVMIntType(8), "");
182 }
183
184 static INLINE LLVMValueRef
185 to_16_uscaled(LLVMBuilderRef builder, LLVMValueRef fp)
186 {
187 LLVMValueRef l = LLVMBuildLoad(builder, fp, "");
188 return LLVMBuildFPToUI(builder, l, LLVMIntType(16), "");
189 }
190
191 static INLINE LLVMValueRef
192 to_32_uscaled(LLVMBuilderRef builder, LLVMValueRef fp)
193 {
194 LLVMValueRef l = LLVMBuildLoad(builder, fp, "");
195 return LLVMBuildFPToUI(builder, l, LLVMIntType(32), "");
196 }
197
198 static INLINE LLVMValueRef
199 to_8_sscaled(LLVMBuilderRef builder, LLVMValueRef fp)
200 {
201 LLVMValueRef l = LLVMBuildLoad(builder, fp, "");
202 return LLVMBuildFPToSI(builder, l, LLVMIntType(8), "");
203 }
204
205 static INLINE LLVMValueRef
206 to_16_sscaled(LLVMBuilderRef builder, LLVMValueRef fp)
207 {
208 LLVMValueRef l = LLVMBuildLoad(builder, fp, "");
209 return LLVMBuildFPToSI(builder, l, LLVMIntType(16), "");
210 }
211
212 static INLINE LLVMValueRef
213 to_32_sscaled(LLVMBuilderRef builder, LLVMValueRef fp)
214 {
215 LLVMValueRef l = LLVMBuildLoad(builder, fp, "");
216 return LLVMBuildFPToSI(builder, l, LLVMIntType(32), "");
217 }
218
219 static INLINE LLVMValueRef
220 to_8_unorm(LLVMBuilderRef builder, LLVMValueRef fp)
221 {
222 LLVMValueRef l = LLVMBuildLoad(builder, fp, "");
223 LLVMValueRef uscaled = LLVMBuildFPToUI(builder, l, LLVMIntType(8), "");
224 return LLVMBuildFMul(builder, uscaled,
225 LLVMConstReal(LLVMFloatType(), 255.), "");
226 }
227
228 static INLINE LLVMValueRef
229 to_16_unorm(LLVMBuilderRef builder, LLVMValueRef fp)
230 {
231 LLVMValueRef l = LLVMBuildLoad(builder, fp, "");
232 LLVMValueRef uscaled = LLVMBuildFPToUI(builder, l, LLVMIntType(32), "");
233 return LLVMBuildFMul(builder, uscaled,
234 LLVMConstReal(LLVMFloatType(), 65535.), "");
235 }
236
237 static INLINE LLVMValueRef
238 to_32_unorm(LLVMBuilderRef builder, LLVMValueRef fp)
239 {
240 LLVMValueRef l = LLVMBuildLoad(builder, fp, "");
241 LLVMValueRef uscaled = LLVMBuildFPToUI(builder, l, LLVMIntType(32), "");
242
243 return LLVMBuildFMul(builder, uscaled,
244 LLVMConstReal(LLVMFloatType(), 4294967295.), "");
245 }
246
247 static INLINE LLVMValueRef
248 to_8_snorm(LLVMBuilderRef builder, LLVMValueRef val)
249 {
250 LLVMValueRef l = LLVMBuildLoad(builder, val, "");
251 LLVMValueRef uscaled = LLVMBuildFPToSI(builder, l, LLVMIntType(8), "");
252 return LLVMBuildFMul(builder, uscaled,
253 LLVMConstReal(LLVMFloatType(), 127.0), "");
254 }
255
256 static INLINE LLVMValueRef
257 to_16_snorm(LLVMBuilderRef builder, LLVMValueRef fp)
258 {
259 LLVMValueRef l = LLVMBuildLoad(builder, fp, "");
260 LLVMValueRef uscaled = LLVMBuildFPToSI(builder, l, LLVMIntType(16), "");
261 return LLVMBuildFMul(builder, uscaled,
262 LLVMConstReal(LLVMFloatType(), 32767.0f), "");
263 }
264
265 static INLINE LLVMValueRef
266 to_32_snorm(LLVMBuilderRef builder, LLVMValueRef fp)
267 {
268 LLVMValueRef l = LLVMBuildLoad(builder, fp, "");
269 LLVMValueRef uscaled = LLVMBuildFPToSI(builder, l, LLVMIntType(32), "");
270
271 return LLVMBuildFMul(builder, uscaled,
272 LLVMConstReal(LLVMFloatType(), 2147483647.0), "");
273 }
274
275 static INLINE LLVMValueRef
276 to_32_fixed(LLVMBuilderRef builder, LLVMValueRef fp)
277 {
278 LLVMValueRef l = LLVMBuildLoad(builder, fp, "");
279 LLVMValueRef uscaled = LLVMBuildFPToSI(builder, l, LLVMIntType(32), "");
280
281 return LLVMBuildFMul(builder, uscaled,
282 LLVMConstReal(LLVMFloatType(), 65536.0), "");
283 }
284
285 typedef LLVMValueRef (*from_func)(LLVMBuilderRef, LLVMValueRef);
286 typedef LLVMValueRef (*to_func)(LLVMBuilderRef, LLVMValueRef);
287
288 /* so that underneath can avoid function calls which are prohibited
289 * for static initialization we need this conversion */
290 enum ll_type {
291 LL_Double,
292 LL_Float,
293 LL_Int32,
294 LL_Int16,
295 LL_Int8
296 };
297
298 static INLINE LLVMTypeRef
299 ll_type_to_llvm(enum ll_type type)
300 {
301 switch (type) {
302 case LL_Double:
303 return LLVMDoubleType();
304 case LL_Float:
305 return LLVMFloatType();
306 case LL_Int32:
307 return LLVMInt32Type();
308 case LL_Int16:
309 return LLVMIntType(16);
310 case LL_Int8:
311 return LLVMIntType(8);
312 }
313 return LLVMIntType(8);
314 }
315
316 static INLINE int
317 ll_type_size(enum ll_type type)
318 {
319 switch (type) {
320 case LL_Double:
321 return 8;
322 case LL_Float:
323 return 4;
324 case LL_Int32:
325 return 4;
326 case LL_Int16:
327 return 2;
328 case LL_Int8:
329 return 1;
330 }
331 return 1;
332 }
333
334 struct draw_llvm_translate {
335 int format;
336 from_func from;
337 to_func to;
338 enum ll_type type;
339 int num_components;
340 } translates[] =
341 {
342 {PIPE_FORMAT_R64_FLOAT, from_64_float, to_64_float, LL_Double, 1},
343 {PIPE_FORMAT_R64G64_FLOAT, from_64_float, to_64_float, LL_Double, 2},
344 {PIPE_FORMAT_R64G64B64_FLOAT, from_64_float, to_64_float, LL_Double, 3},
345 {PIPE_FORMAT_R64G64B64A64_FLOAT, from_64_float, to_64_float, LL_Double, 4},
346 {PIPE_FORMAT_R32_FLOAT, from_32_float, to_32_float, LL_Float, 1},
347 {PIPE_FORMAT_R32G32_FLOAT, from_32_float, to_32_float, LL_Float, 2},
348 {PIPE_FORMAT_R32G32B32_FLOAT, from_32_float, to_32_float, LL_Float, 3},
349 {PIPE_FORMAT_R32G32B32A32_FLOAT, from_32_float, to_32_float, LL_Float, 4},
350
351 {PIPE_FORMAT_R32_UNORM, from_32_unorm, to_32_unorm, LL_Int32, 1},
352 {PIPE_FORMAT_R32G32_UNORM, from_32_unorm, to_32_unorm, LL_Int32, 2},
353 {PIPE_FORMAT_R32G32B32_UNORM, from_32_unorm, to_32_unorm, LL_Int32, 3},
354 {PIPE_FORMAT_R32G32B32A32_UNORM, from_32_unorm, to_32_unorm, LL_Int32, 4},
355
356 {PIPE_FORMAT_R32_USCALED, from_32_uscaled, to_32_uscaled, LL_Int32, 1},
357 {PIPE_FORMAT_R32G32_USCALED, from_32_uscaled, to_32_uscaled, LL_Int32, 2},
358 {PIPE_FORMAT_R32G32B32_USCALED, from_32_uscaled, to_32_uscaled, LL_Int32, 3},
359 {PIPE_FORMAT_R32G32B32A32_USCALED, from_32_uscaled, to_32_uscaled, LL_Int32, 4},
360
361 {PIPE_FORMAT_R32_SNORM, from_32_snorm, to_32_snorm, LL_Int32, 1},
362 {PIPE_FORMAT_R32G32_SNORM, from_32_snorm, to_32_snorm, LL_Int32, 2},
363 {PIPE_FORMAT_R32G32B32_SNORM, from_32_snorm, to_32_snorm, LL_Int32, 3},
364 {PIPE_FORMAT_R32G32B32A32_SNORM, from_32_snorm, to_32_snorm, LL_Int32, 4},
365
366 {PIPE_FORMAT_R32_SSCALED, from_32_sscaled, to_32_sscaled, LL_Int32, 1},
367 {PIPE_FORMAT_R32G32_SSCALED, from_32_sscaled, to_32_sscaled, LL_Int32, 2},
368 {PIPE_FORMAT_R32G32B32_SSCALED, from_32_sscaled, to_32_sscaled, LL_Int32, 3},
369 {PIPE_FORMAT_R32G32B32A32_SSCALED, from_32_sscaled, to_32_sscaled, LL_Int32, 4},
370
371 {PIPE_FORMAT_R16_UNORM, from_16_unorm, to_16_unorm, LL_Int16, 1},
372 {PIPE_FORMAT_R16G16_UNORM, from_16_unorm, to_16_unorm, LL_Int16, 2},
373 {PIPE_FORMAT_R16G16B16_UNORM, from_16_unorm, to_16_unorm, LL_Int16, 3},
374 {PIPE_FORMAT_R16G16B16A16_UNORM, from_16_unorm, to_16_unorm, LL_Int16, 4},
375
376 {PIPE_FORMAT_R16_USCALED, from_16_uscaled, to_16_uscaled, LL_Int16, 1},
377 {PIPE_FORMAT_R16G16_USCALED, from_16_uscaled, to_16_uscaled, LL_Int16, 2},
378 {PIPE_FORMAT_R16G16B16_USCALED, from_16_uscaled, to_16_uscaled, LL_Int16, 3},
379 {PIPE_FORMAT_R16G16B16A16_USCALED, from_16_uscaled, to_16_uscaled, LL_Int16, 4},
380
381 {PIPE_FORMAT_R16_SNORM, from_16_snorm, to_16_snorm, LL_Int16, 1},
382 {PIPE_FORMAT_R16G16_SNORM, from_16_snorm, to_16_snorm, LL_Int16, 2},
383 {PIPE_FORMAT_R16G16B16_SNORM, from_16_snorm, to_16_snorm, LL_Int16, 3},
384 {PIPE_FORMAT_R16G16B16A16_SNORM, from_16_snorm, to_16_snorm, LL_Int16, 4},
385
386 {PIPE_FORMAT_R16_SSCALED, from_16_sscaled, to_16_sscaled, LL_Int16, 1},
387 {PIPE_FORMAT_R16G16_SSCALED, from_16_sscaled, to_16_sscaled, LL_Int16, 2},
388 {PIPE_FORMAT_R16G16B16_SSCALED, from_16_sscaled, to_16_sscaled, LL_Int16, 3},
389 {PIPE_FORMAT_R16G16B16A16_SSCALED, from_16_sscaled, to_16_sscaled, LL_Int16, 4},
390
391 {PIPE_FORMAT_R8_UNORM, from_8_unorm, to_8_unorm, LL_Int8, 1},
392 {PIPE_FORMAT_R8G8_UNORM, from_8_unorm, to_8_unorm, LL_Int8, 2},
393 {PIPE_FORMAT_R8G8B8_UNORM, from_8_unorm, to_8_unorm, LL_Int8, 3},
394 {PIPE_FORMAT_R8G8B8A8_UNORM, from_8_unorm, to_8_unorm, LL_Int8, 4},
395
396 {PIPE_FORMAT_R8_USCALED, from_8_uscaled, to_8_uscaled, LL_Int8, 1},
397 {PIPE_FORMAT_R8G8_USCALED, from_8_uscaled, to_8_uscaled, LL_Int8, 2},
398 {PIPE_FORMAT_R8G8B8_USCALED, from_8_uscaled, to_8_uscaled, LL_Int8, 3},
399 {PIPE_FORMAT_R8G8B8A8_USCALED, from_8_uscaled, to_8_uscaled, LL_Int8, 4},
400
401 {PIPE_FORMAT_R8_SNORM, from_8_snorm, to_8_snorm, LL_Int8, 1},
402 {PIPE_FORMAT_R8G8_SNORM, from_8_snorm, to_8_snorm, LL_Int8, 2},
403 {PIPE_FORMAT_R8G8B8_SNORM, from_8_snorm, to_8_snorm, LL_Int8, 3},
404 {PIPE_FORMAT_R8G8B8A8_SNORM, from_8_snorm, to_8_snorm, LL_Int8, 4},
405
406 {PIPE_FORMAT_R8_SSCALED, from_8_sscaled, to_8_sscaled, LL_Int8, 1},
407 {PIPE_FORMAT_R8G8_SSCALED, from_8_sscaled, to_8_sscaled, LL_Int8, 2},
408 {PIPE_FORMAT_R8G8B8_SSCALED, from_8_sscaled, to_8_sscaled, LL_Int8, 3},
409 {PIPE_FORMAT_R8G8B8A8_SSCALED, from_8_sscaled, to_8_sscaled, LL_Int8, 4},
410
411 {PIPE_FORMAT_R32_FIXED, from_32_fixed, to_32_fixed, LL_Int32, 1},
412 {PIPE_FORMAT_R32G32_FIXED, from_32_fixed, to_32_fixed, LL_Int32, 2},
413 {PIPE_FORMAT_R32G32B32_FIXED, from_32_fixed, to_32_fixed, LL_Int32, 3},
414 {PIPE_FORMAT_R32G32B32A32_FIXED, from_32_fixed, to_32_fixed, LL_Int32, 4},
415
416 {PIPE_FORMAT_A8R8G8B8_UNORM, from_8_unorm, to_8_unorm, LL_Int8, 4},
417 {PIPE_FORMAT_B8G8R8A8_UNORM, from_8_unorm, to_8_unorm, LL_Int8, 4},
418 };
419
420
421 static LLVMValueRef
422 fetch(LLVMBuilderRef builder,
423 LLVMValueRef ptr, int val_size, int nr_components,
424 from_func func)
425 {
426 int i;
427 int offset = 0;
428 LLVMValueRef res = LLVMConstNull(
429 LLVMVectorType(LLVMFloatType(), 4));
430
431 for (i = 0; i < nr_components; ++i) {
432 LLVMValueRef src_index = LLVMConstInt(LLVMInt32Type(), offset, 0);
433 LLVMValueRef dst_index = LLVMConstInt(LLVMInt32Type(), i, 0);
434 LLVMValueRef src_tmp = LLVMBuildGEP(builder, ptr, &src_index, 1, "");
435 LLVMValueRef component;
436
437 src_tmp = LLVMBuildLoad(builder, src_tmp, "");
438
439 LLVMDumpValue(src_tmp);
440 /* convert src_tmp to float */
441 component = func(builder, src_tmp);
442
443 /* vec.comp = component */
444 res = LLVMBuildInsertElement(builder,
445 res,
446 component,
447 dst_index, "");
448 offset += val_size;
449 }
450 return res;
451 }
452
453
454 LLVMValueRef
455 draw_llvm_translate_from(LLVMBuilderRef builder,
456 LLVMValueRef vbuffer,
457 enum pipe_format from_format)
458 {
459 int i;
460 for (i = 0; i < Elements(translates); ++i) {
461 if (translates[i].format == from_format) {
462 /*LLVMTypeRef type = ll_type_to_llvm(translates[i].type);*/
463 return fetch(builder,
464 vbuffer,
465 ll_type_size(translates[i].type),
466 translates[i].num_components,
467 translates[i].from);
468 }
469 }
470 return LLVMGetUndef(LLVMVectorType(LLVMFloatType(), 4));
471 }