llvmpipe: remove some old sampler support structs
[mesa.git] / src / gallium / drivers / llvmpipe / lp_bld_format_aos.c
1 /**************************************************************************
2 *
3 * Copyright 2009 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28
29 #include "util/u_format.h"
30
31 #include "lp_bld_format.h"
32
33
34 LLVMValueRef
35 lp_build_unpack_rgba_aos(LLVMBuilderRef builder,
36 enum pipe_format format,
37 LLVMValueRef packed)
38 {
39 const struct util_format_description *desc;
40 LLVMTypeRef type;
41 LLVMValueRef shifted, casted, scaled, masked;
42 LLVMValueRef shifts[4];
43 LLVMValueRef masks[4];
44 LLVMValueRef scales[4];
45 LLVMValueRef swizzles[4];
46 LLVMValueRef aux[4];
47 bool normalized;
48 int empty_channel;
49 unsigned shift;
50 unsigned i;
51
52 desc = util_format_description(format);
53
54 /* FIXME: Support more formats */
55 assert(desc->layout == UTIL_FORMAT_LAYOUT_ARITH);
56 assert(desc->block.width == 1);
57 assert(desc->block.height == 1);
58 assert(desc->block.bits <= 32);
59
60 type = LLVMIntType(desc->block.bits);
61
62 /* Do the intermediate integer computations with 32bit integers since it
63 * matches floating point size */
64 if (desc->block.bits < 32)
65 packed = LLVMBuildZExt(builder, packed, LLVMInt32Type(), "");
66
67 /* Broadcast the packed value to all four channels */
68 packed = LLVMBuildInsertElement(builder,
69 LLVMGetUndef(LLVMVectorType(LLVMInt32Type(), 4)),
70 packed,
71 LLVMConstNull(LLVMInt32Type()),
72 "");
73 packed = LLVMBuildShuffleVector(builder,
74 packed,
75 LLVMGetUndef(LLVMVectorType(LLVMInt32Type(), 4)),
76 LLVMConstNull(LLVMVectorType(LLVMInt32Type(), 4)),
77 "");
78
79 /* Initialize vector constants */
80 normalized = FALSE;
81 empty_channel = -1;
82 shift = 0;
83 for (i = 0; i < 4; ++i) {
84 unsigned bits = desc->channel[i].size;
85
86 if (desc->channel[i].type == UTIL_FORMAT_TYPE_VOID) {
87 shifts[i] = LLVMGetUndef(LLVMInt32Type());
88 masks[i] = LLVMConstNull(LLVMInt32Type());
89 scales[i] = LLVMConstNull(LLVMFloatType());
90 empty_channel = i;
91 }
92 else {
93 unsigned mask = (1 << bits) - 1;
94
95 assert(desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED);
96 assert(bits < 32);
97
98 shifts[i] = LLVMConstInt(LLVMInt32Type(), shift, 0);
99 masks[i] = LLVMConstInt(LLVMInt32Type(), mask, 0);
100
101 if (desc->channel[i].normalized) {
102 scales[i] = LLVMConstReal(LLVMFloatType(), 1.0/mask);
103 normalized = TRUE;
104 }
105 else
106 scales[i] = LLVMConstReal(LLVMFloatType(), 1.0);
107 }
108
109 shift += bits;
110 }
111
112 shifted = LLVMBuildLShr(builder, packed, LLVMConstVector(shifts, 4), "");
113 masked = LLVMBuildAnd(builder, shifted, LLVMConstVector(masks, 4), "");
114 // UIToFP can't be expressed in SSE2
115 casted = LLVMBuildSIToFP(builder, masked, LLVMVectorType(LLVMFloatType(), 4), "");
116
117 if (normalized)
118 scaled = LLVMBuildMul(builder, casted, LLVMConstVector(scales, 4), "");
119 else
120 scaled = casted;
121
122 for (i = 0; i < 4; ++i)
123 aux[i] = LLVMGetUndef(LLVMFloatType());
124
125 for (i = 0; i < 4; ++i) {
126 enum util_format_swizzle swizzle = desc->swizzle[i];
127
128 switch (swizzle) {
129 case UTIL_FORMAT_SWIZZLE_X:
130 case UTIL_FORMAT_SWIZZLE_Y:
131 case UTIL_FORMAT_SWIZZLE_Z:
132 case UTIL_FORMAT_SWIZZLE_W:
133 swizzles[i] = LLVMConstInt(LLVMInt32Type(), swizzle, 0);
134 break;
135 case UTIL_FORMAT_SWIZZLE_0:
136 assert(empty_channel >= 0);
137 swizzles[i] = LLVMConstInt(LLVMInt32Type(), empty_channel, 0);
138 break;
139 case UTIL_FORMAT_SWIZZLE_1:
140 swizzles[i] = LLVMConstInt(LLVMInt32Type(), 4, 0);
141 aux[0] = LLVMConstReal(LLVMFloatType(), 1.0);
142 break;
143 case UTIL_FORMAT_SWIZZLE_NONE:
144 swizzles[i] = LLVMGetUndef(LLVMFloatType());
145 assert(0);
146 break;
147 }
148 }
149
150 return LLVMBuildShuffleVector(builder, scaled, LLVMConstVector(aux, 4), LLVMConstVector(swizzles, 4), "");
151 }
152
153
154 LLVMValueRef
155 lp_build_pack_rgba_aos(LLVMBuilderRef builder,
156 enum pipe_format format,
157 LLVMValueRef rgba)
158 {
159 const struct util_format_description *desc;
160 LLVMTypeRef type;
161 LLVMValueRef packed = NULL;
162 LLVMValueRef swizzles[4];
163 LLVMValueRef shifted, casted, scaled, unswizzled;
164 LLVMValueRef shifts[4];
165 LLVMValueRef scales[4];
166 bool normalized;
167 unsigned shift;
168 unsigned i, j;
169
170 desc = util_format_description(format);
171
172 assert(desc->layout == UTIL_FORMAT_LAYOUT_ARITH);
173 assert(desc->block.width == 1);
174 assert(desc->block.height == 1);
175
176 type = LLVMIntType(desc->block.bits);
177
178 /* Unswizzle the color components into the source vector. */
179 for (i = 0; i < 4; ++i) {
180 for (j = 0; j < 4; ++j) {
181 if (desc->swizzle[j] == i)
182 break;
183 }
184 if (j < 4)
185 swizzles[i] = LLVMConstInt(LLVMInt32Type(), j, 0);
186 else
187 swizzles[i] = LLVMGetUndef(LLVMInt32Type());
188 }
189
190 unswizzled = LLVMBuildShuffleVector(builder, rgba,
191 LLVMGetUndef(LLVMVectorType(LLVMFloatType(), 4)),
192 LLVMConstVector(swizzles, 4), "");
193
194 normalized = FALSE;
195 shift = 0;
196 for (i = 0; i < 4; ++i) {
197 unsigned bits = desc->channel[i].size;
198
199 if (desc->channel[i].type == UTIL_FORMAT_TYPE_VOID) {
200 shifts[i] = LLVMGetUndef(LLVMInt32Type());
201 scales[i] = LLVMGetUndef(LLVMFloatType());
202 }
203 else {
204 unsigned mask = (1 << bits) - 1;
205
206 assert(desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED);
207 assert(bits < 32);
208
209 shifts[i] = LLVMConstInt(LLVMInt32Type(), shift, 0);
210
211 if (desc->channel[i].normalized) {
212 scales[i] = LLVMConstReal(LLVMFloatType(), mask);
213 normalized = TRUE;
214 }
215 else
216 scales[i] = LLVMConstReal(LLVMFloatType(), 1.0);
217 }
218
219 shift += bits;
220 }
221
222 if (normalized)
223 scaled = LLVMBuildMul(builder, unswizzled, LLVMConstVector(scales, 4), "");
224 else
225 scaled = unswizzled;
226
227 casted = LLVMBuildFPToSI(builder, scaled, LLVMVectorType(LLVMInt32Type(), 4), "");
228
229 shifted = LLVMBuildShl(builder, casted, LLVMConstVector(shifts, 4), "");
230
231 /* Bitwise or all components */
232 for (i = 0; i < 4; ++i) {
233 if (desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED) {
234 LLVMValueRef component = LLVMBuildExtractElement(builder, shifted, LLVMConstInt(LLVMInt32Type(), i, 0), "");
235 if (packed)
236 packed = LLVMBuildOr(builder, packed, component, "");
237 else
238 packed = component;
239 }
240 }
241
242 if (!packed)
243 packed = LLVMGetUndef(LLVMInt32Type());
244
245 if (desc->block.bits < 32)
246 packed = LLVMBuildTrunc(builder, packed, type, "");
247
248 return packed;
249 }
250
251
252 LLVMValueRef
253 lp_build_load_rgba_aos(LLVMBuilderRef builder,
254 enum pipe_format format,
255 LLVMValueRef ptr)
256 {
257 const struct util_format_description *desc;
258 LLVMTypeRef type;
259 LLVMValueRef packed;
260
261 desc = util_format_description(format);
262
263 /* FIXME: Support more formats */
264 assert(desc->layout == UTIL_FORMAT_LAYOUT_ARITH);
265 assert(desc->block.width == 1);
266 assert(desc->block.height == 1);
267 assert(desc->block.bits <= 32);
268
269 type = LLVMIntType(desc->block.bits);
270
271 ptr = LLVMBuildBitCast(builder, ptr, LLVMPointerType(type, 0), "");
272
273 packed = LLVMBuildLoad(builder, ptr, "");
274
275 return lp_build_unpack_rgba_aos(builder, format, packed);
276 }
277
278
279 void
280 lp_build_store_rgba_aos(LLVMBuilderRef builder,
281 enum pipe_format format,
282 LLVMValueRef ptr,
283 LLVMValueRef rgba)
284 {
285 const struct util_format_description *desc;
286 LLVMTypeRef type;
287 LLVMValueRef packed;
288
289 desc = util_format_description(format);
290
291 assert(desc->layout == UTIL_FORMAT_LAYOUT_ARITH);
292 assert(desc->block.width == 1);
293 assert(desc->block.height == 1);
294
295 type = LLVMIntType(desc->block.bits);
296
297 packed = lp_build_pack_rgba_aos(builder, format, rgba);
298
299 ptr = LLVMBuildBitCast(builder, ptr, LLVMPointerType(type, 0), "");
300
301 LLVMBuildStore(builder, packed, ptr);
302 }
303