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