1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**************************************************************************
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2009 VMware, Inc.
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved.
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish,
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions:
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software.
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_defines.h"
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_format.h"
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_memory.h"
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_string.h"
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_type.h"
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_const.h"
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_conv.h"
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_swizzle.h"
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_gather.h"
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_debug.h"
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_format.h"
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_format_swizzle_soa(const struct util_format_description *format_desc,
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            struct lp_build_context *bld,
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            const LLVMValueRef *unswizzled,
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            LLVMValueRef swizzled_out[4])
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(UTIL_FORMAT_SWIZZLE_0 == PIPE_SWIZZLE_ZERO);
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(UTIL_FORMAT_SWIZZLE_1 == PIPE_SWIZZLE_ONE);
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) {
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Return zzz1 for depth-stencil formats.
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * XXX: Allow to control the depth swizzle with an additional parameter,
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * as the caller may wish another depth swizzle, or retain the stencil
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * value.
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      enum util_format_swizzle swizzle = format_desc->swizzle[0];
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef depth = lp_build_swizzle_soa_channel(bld, unswizzled, swizzle);
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swizzled_out[2] = swizzled_out[1] = swizzled_out[0] = depth;
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swizzled_out[3] = bld->one;
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned chan;
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (chan = 0; chan < 4; ++chan) {
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         enum util_format_swizzle swizzle = format_desc->swizzle[chan];
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         swizzled_out[chan] = lp_build_swizzle_soa_channel(bld, unswizzled, swizzle);
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Unpack several pixels in SoA.
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * It takes a vector of packed pixels:
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *   packed = {P0, P1, P2, P3, ..., Pn}
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * And will produce four vectors:
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *   red    = {R0, R1, R2, R3, ..., Rn}
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *   green  = {G0, G1, G2, G3, ..., Gn}
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *   blue   = {B0, B1, B2, B3, ..., Bn}
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *   alpha  = {A0, A1, A2, A3, ..., An}
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * It requires that a packed pixel fits into an element of the output
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * channels. The common case is when converting pixel with a depth of 32 bit or
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * less into floats.
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param format_desc  the format of the 'packed' incoming pixel vector
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param type  the desired type for rgba_out (type.length = n, above)
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param packed  the incoming vector of packed pixels
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param rgba_out  returns the SoA R,G,B,A vectors
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_unpack_rgba_soa(struct gallivm_state *gallivm,
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         const struct util_format_description *format_desc,
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         struct lp_type type,
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         LLVMValueRef packed,
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         LLVMValueRef rgba_out[4])
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMBuilderRef builder = gallivm->builder;
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_build_context bld;
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef inputs[4];
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned start;
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned chan;
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(format_desc->layout == UTIL_FORMAT_LAYOUT_PLAIN);
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(format_desc->block.width == 1);
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(format_desc->block.height == 1);
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(format_desc->block.bits <= type.width);
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* FIXME: Support more output types */
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(type.floating);
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(type.width == 32);
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_context_init(&bld, gallivm, type);
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Decode the input vector components */
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   start = 0;
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (chan = 0; chan < format_desc->nr_channels; ++chan) {
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const unsigned width = format_desc->channel[chan].size;
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const unsigned stop = start + width;
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef input;
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      input = packed;
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch(format_desc->channel[chan].type) {
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case UTIL_FORMAT_TYPE_VOID:
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         input = lp_build_undef(gallivm, type);
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case UTIL_FORMAT_TYPE_UNSIGNED:
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /*
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * Align the LSB
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (start) {
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            input = LLVMBuildLShr(builder, input, lp_build_const_int_vec(gallivm, type, start), "");
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /*
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * Zero the MSBs
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (stop < format_desc->block.bits) {
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            unsigned mask = ((unsigned long long)1 << width) - 1;
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            input = LLVMBuildAnd(builder, input, lp_build_const_int_vec(gallivm, type, mask), "");
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /*
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * Type conversion
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (type.floating) {
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if(format_desc->channel[chan].normalized)
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               input = lp_build_unsigned_norm_to_float(gallivm, width, type, input);
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            else
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               input = LLVMBuildSIToFP(builder, input,
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       lp_build_vec_type(gallivm, type), "");
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else {
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* FIXME */
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            assert(0);
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            input = lp_build_undef(gallivm, type);
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case UTIL_FORMAT_TYPE_SIGNED:
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /*
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * Align the sign bit first.
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (stop < type.width) {
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            unsigned bits = type.width - stop;
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            LLVMValueRef bits_val = lp_build_const_int_vec(gallivm, type, bits);
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            input = LLVMBuildShl(builder, input, bits_val, "");
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /*
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * Align the LSB (with an arithmetic shift to preserve the sign)
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (format_desc->channel[chan].size < type.width) {
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            unsigned bits = type.width - format_desc->channel[chan].size;
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            LLVMValueRef bits_val = lp_build_const_int_vec(gallivm, type, bits);
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            input = LLVMBuildAShr(builder, input, bits_val, "");
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /*
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * Type conversion
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (type.floating) {
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            input = LLVMBuildSIToFP(builder, input, lp_build_vec_type(gallivm, type), "");
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (format_desc->channel[chan].normalized) {
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               double scale = 1.0 / ((1 << (format_desc->channel[chan].size - 1)) - 1);
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               LLVMValueRef scale_val = lp_build_const_vec(gallivm, type, scale);
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               input = LLVMBuildFMul(builder, input, scale_val, "");
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else {
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* FIXME */
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            assert(0);
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            input = lp_build_undef(gallivm, type);
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case UTIL_FORMAT_TYPE_FLOAT:
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (type.floating) {
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            assert(start == 0);
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            assert(stop == 32);
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            assert(type.width == 32);
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            input = LLVMBuildBitCast(builder, input, lp_build_vec_type(gallivm, type), "");
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else {
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* FIXME */
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            assert(0);
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            input = lp_build_undef(gallivm, type);
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case UTIL_FORMAT_TYPE_FIXED:
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (type.floating) {
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            double scale = 1.0 / ((1 << (format_desc->channel[chan].size/2)) - 1);
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            LLVMValueRef scale_val = lp_build_const_vec(gallivm, type, scale);
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            input = LLVMBuildSIToFP(builder, input, lp_build_vec_type(gallivm, type), "");
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            input = LLVMBuildFMul(builder, input, scale_val, "");
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else {
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* FIXME */
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            assert(0);
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            input = lp_build_undef(gallivm, type);
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(0);
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         input = lp_build_undef(gallivm, type);
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inputs[chan] = input;
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      start = stop;
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_format_swizzle_soa(format_desc, &bld, inputs, rgba_out);
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_rgba8_to_f32_soa(struct gallivm_state *gallivm,
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          struct lp_type dst_type,
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          LLVMValueRef packed,
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          LLVMValueRef *rgba)
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMBuilderRef builder = gallivm->builder;
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef mask = lp_build_const_int_vec(gallivm, dst_type, 0xff);
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned chan;
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   packed = LLVMBuildBitCast(builder, packed,
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             lp_build_int_vec_type(gallivm, dst_type), "");
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Decode the input vector components */
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (chan = 0; chan < 4; ++chan) {
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned start = chan*8;
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned stop = start + 8;
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef input;
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      input = packed;
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (start)
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         input = LLVMBuildLShr(builder, input,
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               lp_build_const_int_vec(gallivm, dst_type, start), "");
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (stop < 32)
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         input = LLVMBuildAnd(builder, input, mask, "");
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      input = lp_build_unsigned_norm_to_float(gallivm, 8, dst_type, input);
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba[chan] = input;
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Fetch a texels from a texture, returning them in SoA layout.
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param type  the desired return type for 'rgba'.  The vector length
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *              is the number of texels to fetch
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param base_ptr  points to start of the texture image block.  For non-
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *                  compressed formats, this simply points to the texel.
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *                  For compressed formats, it points to the start of the
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *                  compressed data block.
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param i, j  the sub-block pixel coordinates.  For non-compressed formats
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *              these will always be (0,0).  For compressed formats, i will
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *              be in [0, block_width-1] and j will be in [0, block_height-1].
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_fetch_rgba_soa(struct gallivm_state *gallivm,
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct util_format_description *format_desc,
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        struct lp_type type,
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        LLVMValueRef base_ptr,
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        LLVMValueRef offset,
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        LLVMValueRef i,
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        LLVMValueRef j,
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        LLVMValueRef rgba_out[4])
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMBuilderRef builder = gallivm->builder;
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (format_desc->layout == UTIL_FORMAT_LAYOUT_PLAIN &&
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) &&
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       format_desc->block.width == 1 &&
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       format_desc->block.height == 1 &&
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       format_desc->block.bits <= type.width &&
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       (format_desc->channel[0].type != UTIL_FORMAT_TYPE_FLOAT ||
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        format_desc->channel[0].size == 32))
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * The packed pixel fits into an element of the destination format. Put
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * the packed pixels into a vector and extract each component for all
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * vector elements in parallel.
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef packed;
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * gather the texels from the texture
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Ex: packed = {BGRA, BGRA, BGRA, BGRA}.
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      packed = lp_build_gather(gallivm,
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               type.length,
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               format_desc->block.bits,
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               type.width,
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               base_ptr, offset);
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * convert texels to float rgba
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_unpack_rgba_soa(gallivm,
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               format_desc,
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               type,
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               packed, rgba_out);
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Try calling lp_build_fetch_rgba_aos for all pixels.
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (util_format_fits_8unorm(format_desc) &&
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       type.floating && type.width == 32 &&
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       (type.length == 1 || (type.length % 4 == 0))) {
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct lp_type tmp_type;
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef tmp;
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      memset(&tmp_type, 0, sizeof tmp_type);
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tmp_type.width = 8;
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tmp_type.length = type.length * 4;
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tmp_type.norm = TRUE;
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tmp = lp_build_fetch_rgba_aos(gallivm, format_desc, tmp_type,
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    base_ptr, offset, i, j);
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_rgba8_to_f32_soa(gallivm,
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                type,
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                tmp,
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                rgba_out);
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Fallback to calling lp_build_fetch_rgba_aos for each pixel.
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * This is not the most efficient way of fetching pixels, as we
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * miss some opportunities to do vectorization, but this is
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * convenient for formats or scenarios for which there was no
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * opportunity or incentive to optimize.
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned k, chan;
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct lp_type tmp_type;
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (gallivm_debug & GALLIVM_DEBUG_PERF) {
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         debug_printf("%s: scalar unpacking of %s\n",
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      __FUNCTION__, format_desc->short_name);
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tmp_type = type;
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tmp_type.length = 4;
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (chan = 0; chan < 4; ++chan) {
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         rgba_out[chan] = lp_build_undef(gallivm, type);
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* loop over number of pixels */
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for(k = 0; k < type.length; ++k) {
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMValueRef index = lp_build_const_int32(gallivm, k);
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMValueRef offset_elem;
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMValueRef i_elem, j_elem;
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMValueRef tmp;
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         offset_elem = LLVMBuildExtractElement(builder, offset,
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               index, "");
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         i_elem = LLVMBuildExtractElement(builder, i, index, "");
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         j_elem = LLVMBuildExtractElement(builder, j, index, "");
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Get a single float[4]={R,G,B,A} pixel */
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         tmp = lp_build_fetch_rgba_aos(gallivm, format_desc, tmp_type,
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       base_ptr, offset_elem,
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       i_elem, j_elem);
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /*
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * Insert the AoS tmp value channels into the SoA result vectors at
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * position = 'index'.
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (chan = 0; chan < 4; ++chan) {
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            LLVMValueRef chan_val = lp_build_const_int32(gallivm, chan),
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            tmp_chan = LLVMBuildExtractElement(builder, tmp, chan_val, "");
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            rgba_out[chan] = LLVMBuildInsertElement(builder, rgba_out[chan],
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                    tmp_chan, index, "");
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
439