Tizen 2.0 Release
[profile/ivi/osmesa.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 }