1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**************************************************************************
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2010 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 * @file
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Texture sampling -- AoS.
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @author Jose Fonseca <jfonseca@vmware.com>
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @author Brian Paul <brianp@vmware.com>
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_defines.h"
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_state.h"
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_debug.h"
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_dump.h"
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_memory.h"
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_math.h"
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_format.h"
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_cpu_detect.h"
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_debug.h"
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_type.h"
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_const.h"
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_conv.h"
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_arit.h"
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_bitarit.h"
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_logic.h"
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_swizzle.h"
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_pack.h"
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_flow.h"
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_gather.h"
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_format.h"
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_init.h"
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_sample.h"
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_sample_aos.h"
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_quad.h"
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Build LLVM code for texture coord wrapping, for nearest filtering,
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * for scaled integer texcoords.
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param block_length  is the length of the pixel block along the
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *                      coordinate axis
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param coord  the incoming texcoord (s,t,r or q) scaled to the texture size
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param length  the texture size along one dimension
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param stride  pixel stride along the coordinate axis (in bytes)
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param is_pot  if TRUE, length is a power of two
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param wrap_mode  one of PIPE_TEX_WRAP_x
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param out_offset  byte offset for the wrapped coordinate
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param out_i  resulting sub-block pixel coordinate for coord0
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_sample_wrap_nearest_int(struct lp_build_sample_context *bld,
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 unsigned block_length,
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 LLVMValueRef coord,
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 LLVMValueRef coord_f,
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 LLVMValueRef length,
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 LLVMValueRef stride,
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 boolean is_pot,
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 unsigned wrap_mode,
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 LLVMValueRef *out_offset,
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 LLVMValueRef *out_i)
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMBuilderRef builder = bld->gallivm->builder;
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef length_minus_one;
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   length_minus_one = lp_build_sub(int_coord_bld, length, int_coord_bld->one);
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch(wrap_mode) {
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEX_WRAP_REPEAT:
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if(is_pot)
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         coord = LLVMBuildAnd(builder, coord, length_minus_one, "");
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         struct lp_build_context *coord_bld = &bld->coord_bld;
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMValueRef length_f = lp_build_int_to_float(coord_bld, length);
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         coord = lp_build_fract_safe(coord_bld, coord_f);
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         coord = lp_build_mul(coord_bld, coord, length_f);
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         coord = lp_build_itrunc(coord_bld, coord);
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      coord = lp_build_max(int_coord_bld, coord, int_coord_bld->zero);
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      coord = lp_build_min(int_coord_bld, coord, length_minus_one);
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEX_WRAP_CLAMP:
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEX_WRAP_MIRROR_REPEAT:
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEX_WRAP_MIRROR_CLAMP:
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0);
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_sample_partial_offset(int_coord_bld, block_length, coord, stride,
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  out_offset, out_i);
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Build LLVM code for texture coord wrapping, for nearest filtering,
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * for float texcoords.
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param coord  the incoming texcoord (s,t,r or q)
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param length  the texture size along one dimension
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param is_pot  if TRUE, length is a power of two
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param wrap_mode  one of PIPE_TEX_WRAP_x
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param icoord  the texcoord after wrapping, as int
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_sample_wrap_nearest_float(struct lp_build_sample_context *bld,
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   LLVMValueRef coord,
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   LLVMValueRef length,
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   boolean is_pot,
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   unsigned wrap_mode,
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   LLVMValueRef *icoord)
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_build_context *coord_bld = &bld->coord_bld;
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef length_minus_one;
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch(wrap_mode) {
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEX_WRAP_REPEAT:
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* take fraction, unnormalize */
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      coord = lp_build_fract_safe(coord_bld, coord);
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      coord = lp_build_mul(coord_bld, coord, length);
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *icoord = lp_build_itrunc(coord_bld, coord);
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      length_minus_one = lp_build_sub(coord_bld, length, coord_bld->one);
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (bld->static_state->normalized_coords) {
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* scale coord to length */
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         coord = lp_build_mul(coord_bld, coord, length);
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      coord = lp_build_clamp(coord_bld, coord, coord_bld->zero,
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             length_minus_one);
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *icoord = lp_build_itrunc(coord_bld, coord);
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEX_WRAP_CLAMP:
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEX_WRAP_MIRROR_REPEAT:
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEX_WRAP_MIRROR_CLAMP:
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0);
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Build LLVM code for texture coord wrapping, for linear filtering,
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * for scaled integer texcoords.
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param block_length  is the length of the pixel block along the
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *                      coordinate axis
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param coord0  the incoming texcoord (s,t,r or q) scaled to the texture size
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param length  the texture size along one dimension
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param stride  pixel stride along the coordinate axis (in bytes)
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param is_pot  if TRUE, length is a power of two
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param wrap_mode  one of PIPE_TEX_WRAP_x
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param offset0  resulting relative offset for coord0
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param offset1  resulting relative offset for coord0 + 1
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param i0  resulting sub-block pixel coordinate for coord0
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param i1  resulting sub-block pixel coordinate for coord0 + 1
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_sample_wrap_linear_int(struct lp_build_sample_context *bld,
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                unsigned block_length,
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                LLVMValueRef coord0,
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                LLVMValueRef *weight_i,
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                LLVMValueRef coord_f,
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                LLVMValueRef length,
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                LLVMValueRef stride,
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                boolean is_pot,
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                unsigned wrap_mode,
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                LLVMValueRef *offset0,
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                LLVMValueRef *offset1,
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                LLVMValueRef *i0,
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                LLVMValueRef *i1)
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMBuilderRef builder = bld->gallivm->builder;
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef length_minus_one;
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef lmask, umask, mask;
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * If the pixel block covers more than one pixel then there is no easy
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * way to calculate offset1 relative to offset0. Instead, compute them
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * independently. Otherwise, try to compute offset0 and offset1 with
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * a single stride multiplication.
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   length_minus_one = lp_build_sub(int_coord_bld, length, int_coord_bld->one);
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (block_length != 1) {
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef coord1;
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch(wrap_mode) {
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case PIPE_TEX_WRAP_REPEAT:
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (is_pot) {
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            coord1 = lp_build_add(int_coord_bld, coord0, int_coord_bld->one);
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            coord0 = LLVMBuildAnd(builder, coord0, length_minus_one, "");
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            coord1 = LLVMBuildAnd(builder, coord1, length_minus_one, "");
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else {
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            LLVMValueRef mask;
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            LLVMValueRef weight;
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            LLVMValueRef length_f = lp_build_int_to_float(&bld->coord_bld, length);
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            lp_build_coord_repeat_npot_linear(bld, coord_f,
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              length, length_f,
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              &coord0, &weight);
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            mask = lp_build_compare(bld->gallivm, int_coord_bld->type,
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    PIPE_FUNC_NOTEQUAL, coord0, length_minus_one);
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            coord1 = LLVMBuildAnd(builder,
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  lp_build_add(int_coord_bld, coord0,
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               int_coord_bld->one),
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  mask, "");
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            weight = lp_build_mul_imm(&bld->coord_bld, weight, 256);
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            *weight_i = lp_build_itrunc(&bld->coord_bld, weight);
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         coord1 = lp_build_add(int_coord_bld, coord0, int_coord_bld->one);
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         coord0 = lp_build_clamp(int_coord_bld, coord0, int_coord_bld->zero,
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                length_minus_one);
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         coord1 = lp_build_clamp(int_coord_bld, coord1, int_coord_bld->zero,
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                length_minus_one);
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case PIPE_TEX_WRAP_CLAMP:
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case PIPE_TEX_WRAP_MIRROR_REPEAT:
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case PIPE_TEX_WRAP_MIRROR_CLAMP:
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(0);
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         coord0 = int_coord_bld->zero;
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         coord1 = int_coord_bld->zero;
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_sample_partial_offset(int_coord_bld, block_length, coord0, stride,
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     offset0, i0);
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_sample_partial_offset(int_coord_bld, block_length, coord1, stride,
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     offset1, i1);
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *i0 = int_coord_bld->zero;
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *i1 = int_coord_bld->zero;
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch(wrap_mode) {
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEX_WRAP_REPEAT:
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (is_pot) {
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         coord0 = LLVMBuildAnd(builder, coord0, length_minus_one, "");
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMValueRef weight;
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMValueRef length_f = lp_build_int_to_float(&bld->coord_bld, length);
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lp_build_coord_repeat_npot_linear(bld, coord_f,
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           length, length_f,
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           &coord0, &weight);
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         weight = lp_build_mul_imm(&bld->coord_bld, weight, 256);
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *weight_i = lp_build_itrunc(&bld->coord_bld, weight);
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      mask = lp_build_compare(bld->gallivm, int_coord_bld->type,
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              PIPE_FUNC_NOTEQUAL, coord0, length_minus_one);
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *offset0 = lp_build_mul(int_coord_bld, coord0, stride);
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *offset1 = LLVMBuildAnd(builder,
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              lp_build_add(int_coord_bld, *offset0, stride),
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              mask, "");
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* XXX this might be slower than the separate path
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * on some newer cpus. With sse41 this is 8 instructions vs. 7
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * - at least on SNB this is almost certainly slower since
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * min/max are cheaper than selects, and the muls aren't bad.
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lmask = lp_build_compare(int_coord_bld->gallivm, int_coord_bld->type,
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               PIPE_FUNC_GEQUAL, coord0, int_coord_bld->zero);
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      umask = lp_build_compare(int_coord_bld->gallivm, int_coord_bld->type,
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               PIPE_FUNC_LESS, coord0, length_minus_one);
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      coord0 = lp_build_select(int_coord_bld, lmask, coord0, int_coord_bld->zero);
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      coord0 = lp_build_select(int_coord_bld, umask, coord0, length_minus_one);
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      mask = LLVMBuildAnd(builder, lmask, umask, "");
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *offset0 = lp_build_mul(int_coord_bld, coord0, stride);
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *offset1 = lp_build_add(int_coord_bld,
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              *offset0,
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              LLVMBuildAnd(builder, stride, mask, ""));
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEX_WRAP_CLAMP:
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEX_WRAP_MIRROR_REPEAT:
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEX_WRAP_MIRROR_CLAMP:
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0);
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *offset0 = int_coord_bld->zero;
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *offset1 = int_coord_bld->zero;
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Build LLVM code for texture coord wrapping, for linear filtering,
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * for float texcoords.
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param block_length  is the length of the pixel block along the
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *                      coordinate axis
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param coord  the incoming texcoord (s,t,r or q)
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param length  the texture size along one dimension
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param is_pot  if TRUE, length is a power of two
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param wrap_mode  one of PIPE_TEX_WRAP_x
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param coord0  the first texcoord after wrapping, as int
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param coord1  the second texcoord after wrapping, as int
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param weight  the filter weight as int (0-255)
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param force_nearest  if this coord actually uses nearest filtering
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_sample_wrap_linear_float(struct lp_build_sample_context *bld,
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  unsigned block_length,
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  LLVMValueRef coord,
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  LLVMValueRef length,
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  boolean is_pot,
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  unsigned wrap_mode,
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  LLVMValueRef *coord0,
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  LLVMValueRef *coord1,
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  LLVMValueRef *weight,
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  unsigned force_nearest)
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_build_context *coord_bld = &bld->coord_bld;
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMBuilderRef builder = bld->gallivm->builder;
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef half = lp_build_const_vec(bld->gallivm, coord_bld->type, 0.5);
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef length_minus_one = lp_build_sub(coord_bld, length, coord_bld->one);
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch(wrap_mode) {
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEX_WRAP_REPEAT:
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (is_pot) {
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* mul by size and subtract 0.5 */
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         coord = lp_build_mul(coord_bld, coord, length);
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!force_nearest)
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            coord = lp_build_sub(coord_bld, coord, half);
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *coord1 = lp_build_add(coord_bld, coord, coord_bld->one);
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* convert to int, compute lerp weight */
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lp_build_ifloor_fract(coord_bld, coord, coord0, weight);
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *coord1 = lp_build_ifloor(coord_bld, *coord1);
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* repeat wrap */
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         length_minus_one = lp_build_itrunc(coord_bld, length_minus_one);
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *coord0 = LLVMBuildAnd(builder, *coord0, length_minus_one, "");
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *coord1 = LLVMBuildAnd(builder, *coord1, length_minus_one, "");
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMValueRef mask;
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* wrap with normalized floats is just fract */
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         coord = lp_build_fract(coord_bld, coord);
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* unnormalize */
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         coord = lp_build_mul(coord_bld, coord, length);
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /*
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * we avoided the 0.5/length division, have to fix up wrong
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * edge cases with selects
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *coord1 = lp_build_add(coord_bld, coord, half);
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         coord = lp_build_sub(coord_bld, coord, half);
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *weight = lp_build_fract(coord_bld, coord);
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         mask = lp_build_compare(coord_bld->gallivm, coord_bld->type,
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 PIPE_FUNC_LESS, coord, coord_bld->zero);
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *coord0 = lp_build_select(coord_bld, mask, length_minus_one, coord);
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *coord0 = lp_build_itrunc(coord_bld, *coord0);
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         mask = lp_build_compare(coord_bld->gallivm, coord_bld->type,
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 PIPE_FUNC_LESS, *coord1, length);
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *coord1 = lp_build_select(coord_bld, mask, *coord1, coord_bld->zero);
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *coord1 = lp_build_itrunc(coord_bld, *coord1);
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (bld->static_state->normalized_coords) {
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* mul by tex size */
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         coord = lp_build_mul(coord_bld, coord, length);
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* subtract 0.5 */
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!force_nearest) {
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         coord = lp_build_sub(coord_bld, coord, half);
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* clamp to [0, length - 1] */
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      coord = lp_build_min(coord_bld, coord, length_minus_one);
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      coord = lp_build_max(coord_bld, coord, coord_bld->zero);
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *coord1 = lp_build_add(coord_bld, coord, coord_bld->one);
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* convert to int, compute lerp weight */
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_ifloor_fract(coord_bld, coord, coord0, weight);
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* coord1 = min(coord1, length-1) */
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *coord1 = lp_build_min(coord_bld, *coord1, length_minus_one);
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *coord1 = lp_build_itrunc(coord_bld, *coord1);
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0);
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *coord0 = int_coord_bld->zero;
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *coord1 = int_coord_bld->zero;
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *weight = coord_bld->zero;
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *weight = lp_build_mul_imm(coord_bld, *weight, 256);
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *weight = lp_build_itrunc(coord_bld, *weight);
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return;
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Fetch texels for image with nearest sampling.
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return filtered color as two vectors of 16-bit fixed point values.
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_sample_fetch_image_nearest(struct lp_build_sample_context *bld,
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    LLVMValueRef data_ptr,
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    LLVMValueRef offset,
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    LLVMValueRef x_subcoord,
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    LLVMValueRef y_subcoord,
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    LLVMValueRef *colors_lo,
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    LLVMValueRef *colors_hi)
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Fetch the pixels as 4 x 32bit (rgba order might differ):
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *   rgba0 rgba1 rgba2 rgba3
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * bit cast them into 16 x u8
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *   r0 g0 b0 a0 r1 g1 b1 a1 r2 g2 b2 a2 r3 g3 b3 a3
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * unpack them into two 8 x i16:
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *   r0 g0 b0 a0 r1 g1 b1 a1
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *   r2 g2 b2 a2 r3 g3 b3 a3
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * The higher 8 bits of the resulting elements will be zero.
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMBuilderRef builder = bld->gallivm->builder;
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef rgba8;
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_build_context h16, u8n;
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMTypeRef u8n_vec_type;
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_context_init(&h16, bld->gallivm, lp_type_ufixed(16, bld->vector_width));
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_context_init(&u8n, bld->gallivm, lp_type_unorm(8, bld->vector_width));
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   u8n_vec_type = lp_build_vec_type(bld->gallivm, u8n.type);
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (util_format_is_rgba8_variant(bld->format_desc)) {
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Given the format is a rgba8, just read the pixels as is,
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * without any swizzling. Swizzling will be done later.
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba8 = lp_build_gather(bld->gallivm,
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              bld->texel_type.length,
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              bld->format_desc->block.bits,
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              bld->texel_type.width,
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              data_ptr, offset);
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba8 = LLVMBuildBitCast(builder, rgba8, u8n_vec_type, "");
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba8 = lp_build_fetch_rgba_aos(bld->gallivm,
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      bld->format_desc,
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      u8n.type,
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      data_ptr, offset,
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      x_subcoord,
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      y_subcoord);
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Expand one 4*rgba8 to two 2*rgba16 */
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_unpack2(bld->gallivm, u8n.type, h16.type,
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    rgba8,
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    colors_lo, colors_hi);
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Sample a single texture image with nearest sampling.
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If sampling a cube texture, r = cube face in [0,5].
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return filtered color as two vectors of 16-bit fixed point values.
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_sample_image_nearest(struct lp_build_sample_context *bld,
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              LLVMValueRef int_size,
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              LLVMValueRef row_stride_vec,
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              LLVMValueRef img_stride_vec,
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              LLVMValueRef data_ptr,
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              LLVMValueRef s,
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              LLVMValueRef t,
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              LLVMValueRef r,
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              LLVMValueRef *colors_lo,
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              LLVMValueRef *colors_hi)
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const unsigned dims = bld->dims;
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMBuilderRef builder = bld->gallivm->builder;
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_build_context i32;
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMTypeRef i32_vec_type;
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef i32_c8;
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef width_vec, height_vec, depth_vec;
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef s_ipart, t_ipart = NULL, r_ipart = NULL;
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef s_float, t_float = NULL, r_float = NULL;
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef x_stride;
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef x_offset, offset;
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef x_subcoord, y_subcoord, z_subcoord;
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_context_init(&i32, bld->gallivm, lp_type_int_vec(32, bld->vector_width));
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i32_vec_type = lp_build_vec_type(bld->gallivm, i32.type);
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_extract_image_sizes(bld,
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                bld->int_size_type,
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                bld->int_coord_type,
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                int_size,
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                &width_vec,
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                &height_vec,
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                &depth_vec);
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   s_float = s; t_float = t; r_float = r;
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (bld->static_state->normalized_coords) {
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef scaled_size;
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef flt_size;
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* scale size by 256 (8 fractional bits) */
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      scaled_size = lp_build_shl_imm(&bld->int_size_bld, int_size, 8);
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      flt_size = lp_build_int_to_float(&bld->float_size_bld, scaled_size);
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_unnormalized_coords(bld, flt_size, &s, &t, &r);
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* scale coords by 256 (8 fractional bits) */
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      s = lp_build_mul_imm(&bld->coord_bld, s, 256);
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dims >= 2)
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         t = lp_build_mul_imm(&bld->coord_bld, t, 256);
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dims >= 3)
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         r = lp_build_mul_imm(&bld->coord_bld, r, 256);
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* convert float to int */
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   s = LLVMBuildFPToSI(builder, s, i32_vec_type, "");
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dims >= 2)
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      t = LLVMBuildFPToSI(builder, t, i32_vec_type, "");
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dims >= 3)
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      r = LLVMBuildFPToSI(builder, r, i32_vec_type, "");
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* compute floor (shift right 8) */
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i32_c8 = lp_build_const_int_vec(bld->gallivm, i32.type, 8);
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   s_ipart = LLVMBuildAShr(builder, s, i32_c8, "");
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dims >= 2)
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      t_ipart = LLVMBuildAShr(builder, t, i32_c8, "");
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dims >= 3)
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      r_ipart = LLVMBuildAShr(builder, r, i32_c8, "");
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* get pixel, row, image strides */
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   x_stride = lp_build_const_vec(bld->gallivm,
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 bld->int_coord_bld.type,
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 bld->format_desc->block.bits/8);
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Do texcoord wrapping, compute texel offset */
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_sample_wrap_nearest_int(bld,
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    bld->format_desc->block.width,
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    s_ipart, s_float,
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    width_vec, x_stride,
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    bld->static_state->pot_width,
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    bld->static_state->wrap_s,
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    &x_offset, &x_subcoord);
599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   offset = x_offset;
600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dims >= 2) {
601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef y_offset;
602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_sample_wrap_nearest_int(bld,
603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       bld->format_desc->block.height,
604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       t_ipart, t_float,
605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       height_vec, row_stride_vec,
606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       bld->static_state->pot_height,
607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       bld->static_state->wrap_t,
608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       &y_offset, &y_subcoord);
609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      offset = lp_build_add(&bld->int_coord_bld, offset, y_offset);
610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dims >= 3) {
611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMValueRef z_offset;
612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lp_build_sample_wrap_nearest_int(bld,
613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          1, /* block length (depth) */
614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          r_ipart, r_float,
615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          depth_vec, img_stride_vec,
616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          bld->static_state->pot_depth,
617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          bld->static_state->wrap_r,
618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          &z_offset, &z_subcoord);
619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         offset = lp_build_add(&bld->int_coord_bld, offset, z_offset);
620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if (bld->static_state->target == PIPE_TEXTURE_CUBE) {
622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMValueRef z_offset;
623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* The r coord is the cube face in [0,5] */
624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         z_offset = lp_build_mul(&bld->int_coord_bld, r, img_stride_vec);
625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         offset = lp_build_add(&bld->int_coord_bld, offset, z_offset);
626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_sample_fetch_image_nearest(bld, data_ptr, offset,
630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       x_subcoord, y_subcoord,
631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       colors_lo, colors_hi);
632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Sample a single texture image with nearest sampling.
637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If sampling a cube texture, r = cube face in [0,5].
638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return filtered color as two vectors of 16-bit fixed point values.
639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Does address calcs (except offsets) with floats.
640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Useful for AVX which has support for 8x32 floats but not 8x32 ints.
641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_sample_image_nearest_afloat(struct lp_build_sample_context *bld,
644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     LLVMValueRef int_size,
645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     LLVMValueRef row_stride_vec,
646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     LLVMValueRef img_stride_vec,
647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     LLVMValueRef data_ptr,
648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     LLVMValueRef s,
649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     LLVMValueRef t,
650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     LLVMValueRef r,
651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     LLVMValueRef *colors_lo,
652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     LLVMValueRef *colors_hi)
653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const unsigned dims = bld->dims;
655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef width_vec, height_vec, depth_vec;
656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef offset;
657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef x_subcoord, y_subcoord;
658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef x_icoord = NULL, y_icoord = NULL, z_icoord = NULL;
659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef flt_size;
660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   flt_size = lp_build_int_to_float(&bld->float_size_bld, int_size);
662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_extract_image_sizes(bld,
664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                bld->float_size_type,
665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                bld->coord_type,
666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                flt_size,
667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                &width_vec,
668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                &height_vec,
669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                &depth_vec);
670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Do texcoord wrapping */
672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_sample_wrap_nearest_float(bld,
673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      s, width_vec,
674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      bld->static_state->pot_width,
675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      bld->static_state->wrap_s,
676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      &x_icoord);
677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dims >= 2) {
679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_sample_wrap_nearest_float(bld,
680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         t, height_vec,
681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         bld->static_state->pot_height,
682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         bld->static_state->wrap_t,
683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         &y_icoord);
684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dims >= 3) {
686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lp_build_sample_wrap_nearest_float(bld,
687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                            r, depth_vec,
688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                            bld->static_state->pot_depth,
689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                            bld->static_state->wrap_r,
690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                            &z_icoord);
691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if (bld->static_state->target == PIPE_TEXTURE_CUBE) {
693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         z_icoord = r;
694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * From here on we deal with ints, and we should split up the 256bit
699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * vectors manually for better generated code.
700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * compute texel offsets -
704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * cannot do offset calc with floats, difficult for block-based formats,
705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * and not enough precision anyway.
706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_sample_offset(&bld->int_coord_bld,
708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          bld->format_desc,
709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          x_icoord, y_icoord,
710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          z_icoord,
711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          row_stride_vec, img_stride_vec,
712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          &offset,
713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          &x_subcoord, &y_subcoord);
714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_sample_fetch_image_nearest(bld, data_ptr, offset,
716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       x_subcoord, y_subcoord,
717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       colors_lo, colors_hi);
718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Fetch texels for image with linear sampling.
723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return filtered color as two vectors of 16-bit fixed point values.
724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_sample_fetch_image_linear(struct lp_build_sample_context *bld,
727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   LLVMValueRef data_ptr,
728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   LLVMValueRef offset[2][2][2],
729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   LLVMValueRef x_subcoord[2],
730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   LLVMValueRef y_subcoord[2],
731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   LLVMValueRef s_fpart,
732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   LLVMValueRef t_fpart,
733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   LLVMValueRef r_fpart,
734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   LLVMValueRef *colors_lo,
735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   LLVMValueRef *colors_hi)
736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const unsigned dims = bld->dims;
738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMBuilderRef builder = bld->gallivm->builder;
739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_build_context h16, u8n;
740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMTypeRef h16_vec_type, u8n_vec_type;
741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMTypeRef elem_type = LLVMInt32TypeInContext(bld->gallivm->context);
742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef shuffles_lo[LP_MAX_VECTOR_LENGTH];
743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef shuffles_hi[LP_MAX_VECTOR_LENGTH];
744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef shuffle_lo, shuffle_hi;
745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef s_fpart_lo, s_fpart_hi;
746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef t_fpart_lo = NULL, t_fpart_hi = NULL;
747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef r_fpart_lo = NULL, r_fpart_hi = NULL;
748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef neighbors_lo[2][2][2]; /* [z][y][x] */
749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef neighbors_hi[2][2][2]; /* [z][y][x] */
750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef packed_lo, packed_hi;
751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i, j, k;
752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned numj, numk;
753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_context_init(&h16, bld->gallivm, lp_type_ufixed(16, bld->vector_width));
755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_context_init(&u8n, bld->gallivm, lp_type_unorm(8, bld->vector_width));
756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   h16_vec_type = lp_build_vec_type(bld->gallivm, h16.type);
757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   u8n_vec_type = lp_build_vec_type(bld->gallivm, u8n.type);
758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Transform 4 x i32 in
761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *   s_fpart = {s0, s1, s2, s3}
763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * into 8 x i16
765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *   s_fpart = {00, s0, 00, s1, 00, s2, 00, s3}
767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * into two 8 x i16
769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *   s_fpart_lo = {s0, s0, s0, s0, s1, s1, s1, s1}
771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *   s_fpart_hi = {s2, s2, s2, s2, s3, s3, s3, s3}
772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * and likewise for t_fpart. There is no risk of loosing precision here
774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * since the fractional parts only use the lower 8bits.
775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   s_fpart = LLVMBuildBitCast(builder, s_fpart, h16_vec_type, "");
777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dims >= 2)
778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      t_fpart = LLVMBuildBitCast(builder, t_fpart, h16_vec_type, "");
779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dims >= 3)
780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      r_fpart = LLVMBuildBitCast(builder, r_fpart, h16_vec_type, "");
781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (j = 0; j < h16.type.length; j += 4) {
783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef PIPE_ARCH_LITTLE_ENDIAN
784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned subindex = 0;
785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned subindex = 1;
787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef index;
789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      index = LLVMConstInt(elem_type, j/2 + subindex, 0);
791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < 4; ++i)
792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shuffles_lo[j + i] = index;
793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      index = LLVMConstInt(elem_type, h16.type.length/2 + j/2 + subindex, 0);
795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < 4; ++i)
796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shuffles_hi[j + i] = index;
797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   shuffle_lo = LLVMConstVector(shuffles_lo, h16.type.length);
800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   shuffle_hi = LLVMConstVector(shuffles_hi, h16.type.length);
801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   s_fpart_lo = LLVMBuildShuffleVector(builder, s_fpart, h16.undef,
803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       shuffle_lo, "");
804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   s_fpart_hi = LLVMBuildShuffleVector(builder, s_fpart, h16.undef,
805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       shuffle_hi, "");
806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dims >= 2) {
807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      t_fpart_lo = LLVMBuildShuffleVector(builder, t_fpart, h16.undef,
808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          shuffle_lo, "");
809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      t_fpart_hi = LLVMBuildShuffleVector(builder, t_fpart, h16.undef,
810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          shuffle_hi, "");
811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dims >= 3) {
813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      r_fpart_lo = LLVMBuildShuffleVector(builder, r_fpart, h16.undef,
814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          shuffle_lo, "");
815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      r_fpart_hi = LLVMBuildShuffleVector(builder, r_fpart, h16.undef,
816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          shuffle_hi, "");
817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Fetch the pixels as 4 x 32bit (rgba order might differ):
821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *   rgba0 rgba1 rgba2 rgba3
823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * bit cast them into 16 x u8
825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *   r0 g0 b0 a0 r1 g1 b1 a1 r2 g2 b2 a2 r3 g3 b3 a3
827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * unpack them into two 8 x i16:
829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *   r0 g0 b0 a0 r1 g1 b1 a1
831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *   r2 g2 b2 a2 r3 g3 b3 a3
832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * The higher 8 bits of the resulting elements will be zero.
834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   numj = 1 + (dims >= 2);
836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   numk = 1 + (dims >= 3);
837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (k = 0; k < numk; k++) {
839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (j = 0; j < numj; j++) {
840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 0; i < 2; i++) {
841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            LLVMValueRef rgba8;
842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (util_format_is_rgba8_variant(bld->format_desc)) {
844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               /*
845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                * Given the format is a rgba8, just read the pixels as is,
846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                * without any swizzling. Swizzling will be done later.
847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                */
848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               rgba8 = lp_build_gather(bld->gallivm,
849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       bld->texel_type.length,
850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       bld->format_desc->block.bits,
851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       bld->texel_type.width,
852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       data_ptr, offset[k][j][i]);
853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               rgba8 = LLVMBuildBitCast(builder, rgba8, u8n_vec_type, "");
855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            else {
857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               rgba8 = lp_build_fetch_rgba_aos(bld->gallivm,
858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               bld->format_desc,
859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               u8n.type,
860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               data_ptr, offset[k][j][i],
861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               x_subcoord[i],
862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               y_subcoord[j]);
863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* Expand one 4*rgba8 to two 2*rgba16 */
866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            lp_build_unpack2(bld->gallivm, u8n.type, h16.type,
867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             rgba8,
868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             &neighbors_lo[k][j][i], &neighbors_hi[k][j][i]);
869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Linear interpolation with 8.8 fixed point.
875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (bld->static_state->force_nearest_s) {
877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* special case 1-D lerp */
878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      packed_lo = lp_build_lerp(&h16,
879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                t_fpart_lo,
880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                neighbors_lo[0][0][0],
881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                neighbors_lo[0][0][1]);
882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      packed_hi = lp_build_lerp(&h16,
884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                t_fpart_hi,
885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                neighbors_hi[0][1][0],
886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                neighbors_hi[0][1][0]);
887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (bld->static_state->force_nearest_t) {
889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* special case 1-D lerp */
890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      packed_lo = lp_build_lerp(&h16,
891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                s_fpart_lo,
892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                neighbors_lo[0][0][0],
893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                neighbors_lo[0][0][1]);
894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      packed_hi = lp_build_lerp(&h16,
896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                s_fpart_hi,
897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                neighbors_hi[0][0][0],
898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                neighbors_hi[0][0][1]);
899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* general 1/2/3-D lerping */
902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dims == 1) {
903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         packed_lo = lp_build_lerp(&h16,
904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   s_fpart_lo,
905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   neighbors_lo[0][0][0],
906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   neighbors_lo[0][0][1]);
907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         packed_hi = lp_build_lerp(&h16,
909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   s_fpart_hi,
910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   neighbors_hi[0][0][0],
911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   neighbors_hi[0][0][1]);
912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* 2-D lerp */
915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         packed_lo = lp_build_lerp_2d(&h16,
916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      s_fpart_lo, t_fpart_lo,
917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      neighbors_lo[0][0][0],
918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      neighbors_lo[0][0][1],
919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      neighbors_lo[0][1][0],
920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      neighbors_lo[0][1][1]);
921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         packed_hi = lp_build_lerp_2d(&h16,
923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      s_fpart_hi, t_fpart_hi,
924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      neighbors_hi[0][0][0],
925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      neighbors_hi[0][0][1],
926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      neighbors_hi[0][1][0],
927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      neighbors_hi[0][1][1]);
928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (dims >= 3) {
930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            LLVMValueRef packed_lo2, packed_hi2;
931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* lerp in the second z slice */
933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            packed_lo2 = lp_build_lerp_2d(&h16,
934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          s_fpart_lo, t_fpart_lo,
935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          neighbors_lo[1][0][0],
936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          neighbors_lo[1][0][1],
937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          neighbors_lo[1][1][0],
938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          neighbors_lo[1][1][1]);
939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            packed_hi2 = lp_build_lerp_2d(&h16,
941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          s_fpart_hi, t_fpart_hi,
942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          neighbors_hi[1][0][0],
943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          neighbors_hi[1][0][1],
944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          neighbors_hi[1][1][0],
945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          neighbors_hi[1][1][1]);
946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* interp between two z slices */
947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            packed_lo = lp_build_lerp(&h16, r_fpart_lo,
948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      packed_lo, packed_lo2);
949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            packed_hi = lp_build_lerp(&h16, r_fpart_hi,
950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      packed_hi, packed_hi2);
951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *colors_lo = packed_lo;
956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *colors_hi = packed_hi;
957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Sample a single texture image with (bi-)(tri-)linear sampling.
961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return filtered color as two vectors of 16-bit fixed point values.
962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_sample_image_linear(struct lp_build_sample_context *bld,
965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             LLVMValueRef int_size,
966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             LLVMValueRef row_stride_vec,
967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             LLVMValueRef img_stride_vec,
968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             LLVMValueRef data_ptr,
969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             LLVMValueRef s,
970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             LLVMValueRef t,
971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             LLVMValueRef r,
972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             LLVMValueRef *colors_lo,
973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             LLVMValueRef *colors_hi)
974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const unsigned dims = bld->dims;
976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMBuilderRef builder = bld->gallivm->builder;
977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_build_context i32;
978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMTypeRef i32_vec_type;
979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef i32_c8, i32_c128, i32_c255;
980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef width_vec, height_vec, depth_vec;
981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef s_ipart, s_fpart, s_float;
982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef t_ipart = NULL, t_fpart = NULL, t_float = NULL;
983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef r_ipart = NULL, r_fpart = NULL, r_float = NULL;
984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef x_stride, y_stride, z_stride;
985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef x_offset0, x_offset1;
986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef y_offset0, y_offset1;
987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef z_offset0, z_offset1;
988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef offset[2][2][2]; /* [z][y][x] */
989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef x_subcoord[2], y_subcoord[2], z_subcoord[2];
990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned x, y, z;
991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_context_init(&i32, bld->gallivm, lp_type_int_vec(32, bld->vector_width));
993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i32_vec_type = lp_build_vec_type(bld->gallivm, i32.type);
995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_extract_image_sizes(bld,
997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                bld->int_size_type,
998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                bld->int_coord_type,
999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                int_size,
1000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                &width_vec,
1001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                &height_vec,
1002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                &depth_vec);
1003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   s_float = s; t_float = t; r_float = r;
1005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (bld->static_state->normalized_coords) {
1007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef scaled_size;
1008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef flt_size;
1009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* scale size by 256 (8 fractional bits) */
1011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      scaled_size = lp_build_shl_imm(&bld->int_size_bld, int_size, 8);
1012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      flt_size = lp_build_int_to_float(&bld->float_size_bld, scaled_size);
1014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_unnormalized_coords(bld, flt_size, &s, &t, &r);
1016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
1018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* scale coords by 256 (8 fractional bits) */
1019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      s = lp_build_mul_imm(&bld->coord_bld, s, 256);
1020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dims >= 2)
1021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         t = lp_build_mul_imm(&bld->coord_bld, t, 256);
1022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dims >= 3)
1023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         r = lp_build_mul_imm(&bld->coord_bld, r, 256);
1024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* convert float to int */
1027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   s = LLVMBuildFPToSI(builder, s, i32_vec_type, "");
1028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dims >= 2)
1029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      t = LLVMBuildFPToSI(builder, t, i32_vec_type, "");
1030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dims >= 3)
1031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      r = LLVMBuildFPToSI(builder, r, i32_vec_type, "");
1032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* subtract 0.5 (add -128) */
1034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i32_c128 = lp_build_const_int_vec(bld->gallivm, i32.type, -128);
1035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!bld->static_state->force_nearest_s) {
1036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      s = LLVMBuildAdd(builder, s, i32_c128, "");
1037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dims >= 2 && !bld->static_state->force_nearest_t) {
1039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      t = LLVMBuildAdd(builder, t, i32_c128, "");
1040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dims >= 3) {
1042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      r = LLVMBuildAdd(builder, r, i32_c128, "");
1043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* compute floor (shift right 8) */
1046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i32_c8 = lp_build_const_int_vec(bld->gallivm, i32.type, 8);
1047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   s_ipart = LLVMBuildAShr(builder, s, i32_c8, "");
1048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dims >= 2)
1049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      t_ipart = LLVMBuildAShr(builder, t, i32_c8, "");
1050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dims >= 3)
1051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      r_ipart = LLVMBuildAShr(builder, r, i32_c8, "");
1052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* compute fractional part (AND with 0xff) */
1054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i32_c255 = lp_build_const_int_vec(bld->gallivm, i32.type, 255);
1055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   s_fpart = LLVMBuildAnd(builder, s, i32_c255, "");
1056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dims >= 2)
1057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      t_fpart = LLVMBuildAnd(builder, t, i32_c255, "");
1058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dims >= 3)
1059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      r_fpart = LLVMBuildAnd(builder, r, i32_c255, "");
1060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* get pixel, row and image strides */
1062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   x_stride = lp_build_const_vec(bld->gallivm, bld->int_coord_bld.type,
1063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 bld->format_desc->block.bits/8);
1064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   y_stride = row_stride_vec;
1065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   z_stride = img_stride_vec;
1066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* do texcoord wrapping and compute texel offsets */
1068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_sample_wrap_linear_int(bld,
1069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   bld->format_desc->block.width,
1070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   s_ipart, &s_fpart, s_float,
1071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   width_vec, x_stride,
1072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   bld->static_state->pot_width,
1073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   bld->static_state->wrap_s,
1074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   &x_offset0, &x_offset1,
1075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   &x_subcoord[0], &x_subcoord[1]);
1076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (z = 0; z < 2; z++) {
1077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (y = 0; y < 2; y++) {
1078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         offset[z][y][0] = x_offset0;
1079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         offset[z][y][1] = x_offset1;
1080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dims >= 2) {
1084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_sample_wrap_linear_int(bld,
1085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      bld->format_desc->block.height,
1086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      t_ipart, &t_fpart, t_float,
1087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      height_vec, y_stride,
1088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      bld->static_state->pot_height,
1089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      bld->static_state->wrap_t,
1090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      &y_offset0, &y_offset1,
1091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      &y_subcoord[0], &y_subcoord[1]);
1092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (z = 0; z < 2; z++) {
1094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (x = 0; x < 2; x++) {
1095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            offset[z][0][x] = lp_build_add(&bld->int_coord_bld,
1096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           offset[z][0][x], y_offset0);
1097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            offset[z][1][x] = lp_build_add(&bld->int_coord_bld,
1098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           offset[z][1][x], y_offset1);
1099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dims >= 3) {
1104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_sample_wrap_linear_int(bld,
1105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      bld->format_desc->block.height,
1106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      r_ipart, &r_fpart, r_float,
1107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      depth_vec, z_stride,
1108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      bld->static_state->pot_depth,
1109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      bld->static_state->wrap_r,
1110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      &z_offset0, &z_offset1,
1111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      &z_subcoord[0], &z_subcoord[1]);
1112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (y = 0; y < 2; y++) {
1113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (x = 0; x < 2; x++) {
1114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            offset[0][y][x] = lp_build_add(&bld->int_coord_bld,
1115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           offset[0][y][x], z_offset0);
1116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            offset[1][y][x] = lp_build_add(&bld->int_coord_bld,
1117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           offset[1][y][x], z_offset1);
1118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (bld->static_state->target == PIPE_TEXTURE_CUBE) {
1122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef z_offset;
1123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      z_offset = lp_build_mul(&bld->int_coord_bld, r, img_stride_vec);
1124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (y = 0; y < 2; y++) {
1125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (x = 0; x < 2; x++) {
1126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* The r coord is the cube face in [0,5] */
1127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            offset[0][y][x] = lp_build_add(&bld->int_coord_bld,
1128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           offset[0][y][x], z_offset);
1129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_sample_fetch_image_linear(bld, data_ptr, offset,
1134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      x_subcoord, y_subcoord,
1135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      s_fpart, t_fpart, r_fpart,
1136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      colors_lo, colors_hi);
1137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
1141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Sample a single texture image with (bi-)(tri-)linear sampling.
1142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return filtered color as two vectors of 16-bit fixed point values.
1143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Does address calcs (except offsets) with floats.
1144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Useful for AVX which has support for 8x32 floats but not 8x32 ints.
1145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
1147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_sample_image_linear_afloat(struct lp_build_sample_context *bld,
1148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    LLVMValueRef int_size,
1149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    LLVMValueRef row_stride_vec,
1150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    LLVMValueRef img_stride_vec,
1151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    LLVMValueRef data_ptr,
1152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    LLVMValueRef s,
1153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    LLVMValueRef t,
1154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    LLVMValueRef r,
1155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    LLVMValueRef *colors_lo,
1156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    LLVMValueRef *colors_hi)
1157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const unsigned dims = bld->dims;
1159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef width_vec, height_vec, depth_vec;
1160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef s_fpart;
1161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef t_fpart = NULL;
1162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef r_fpart = NULL;
1163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef x_stride, y_stride, z_stride;
1164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef x_offset0, x_offset1;
1165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef y_offset0, y_offset1;
1166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef z_offset0, z_offset1;
1167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef offset[2][2][2]; /* [z][y][x] */
1168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef x_subcoord[2], y_subcoord[2];
1169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef flt_size;
1170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef x_icoord0, x_icoord1;
1171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef y_icoord0, y_icoord1;
1172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef z_icoord0, z_icoord1;
1173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned x, y, z;
1174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   flt_size = lp_build_int_to_float(&bld->float_size_bld, int_size);
1176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_extract_image_sizes(bld,
1178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                bld->float_size_type,
1179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                bld->coord_type,
1180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                flt_size,
1181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                &width_vec,
1182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                &height_vec,
1183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                &depth_vec);
1184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* do texcoord wrapping and compute texel offsets */
1186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_sample_wrap_linear_float(bld,
1187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     bld->format_desc->block.width,
1188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     s, width_vec,
1189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     bld->static_state->pot_width,
1190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     bld->static_state->wrap_s,
1191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     &x_icoord0, &x_icoord1,
1192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     &s_fpart,
1193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     bld->static_state->force_nearest_s);
1194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dims >= 2) {
1196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_sample_wrap_linear_float(bld,
1197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        bld->format_desc->block.height,
1198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        t, height_vec,
1199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        bld->static_state->pot_height,
1200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        bld->static_state->wrap_t,
1201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        &y_icoord0, &y_icoord1,
1202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        &t_fpart,
1203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        bld->static_state->force_nearest_t);
1204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dims >= 3) {
1206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lp_build_sample_wrap_linear_float(bld,
1207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           bld->format_desc->block.height,
1208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           r, depth_vec,
1209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           bld->static_state->pot_depth,
1210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           bld->static_state->wrap_r,
1211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           &z_icoord0, &z_icoord1,
1212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           &r_fpart, 0);
1213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
1217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * From here on we deal with ints, and we should split up the 256bit
1218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * vectors manually for better generated code.
1219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* get pixel, row and image strides */
1222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   x_stride = lp_build_const_vec(bld->gallivm,
1223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 bld->int_coord_bld.type,
1224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 bld->format_desc->block.bits/8);
1225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   y_stride = row_stride_vec;
1226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   z_stride = img_stride_vec;
1227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
1229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * compute texel offset -
1230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * cannot do offset calc with floats, difficult for block-based formats,
1231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * and not enough precision anyway.
1232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_sample_partial_offset(&bld->int_coord_bld,
1234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  bld->format_desc->block.width,
1235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  x_icoord0, x_stride,
1236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  &x_offset0, &x_subcoord[0]);
1237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_sample_partial_offset(&bld->int_coord_bld,
1238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  bld->format_desc->block.width,
1239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  x_icoord1, x_stride,
1240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  &x_offset1, &x_subcoord[1]);
1241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (z = 0; z < 2; z++) {
1242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (y = 0; y < 2; y++) {
1243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         offset[z][y][0] = x_offset0;
1244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         offset[z][y][1] = x_offset1;
1245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dims >= 2) {
1249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_sample_partial_offset(&bld->int_coord_bld,
1250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     bld->format_desc->block.height,
1251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     y_icoord0, y_stride,
1252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     &y_offset0, &y_subcoord[0]);
1253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_sample_partial_offset(&bld->int_coord_bld,
1254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     bld->format_desc->block.height,
1255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     y_icoord1, y_stride,
1256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     &y_offset1, &y_subcoord[1]);
1257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (z = 0; z < 2; z++) {
1258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (x = 0; x < 2; x++) {
1259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            offset[z][0][x] = lp_build_add(&bld->int_coord_bld,
1260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           offset[z][0][x], y_offset0);
1261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            offset[z][1][x] = lp_build_add(&bld->int_coord_bld,
1262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           offset[z][1][x], y_offset1);
1263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dims >= 3) {
1268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef z_subcoord[2];
1269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_sample_partial_offset(&bld->int_coord_bld,
1270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     1,
1271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     z_icoord0, z_stride,
1272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     &z_offset0, &z_subcoord[0]);
1273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_sample_partial_offset(&bld->int_coord_bld,
1274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     1,
1275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     z_icoord1, z_stride,
1276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     &z_offset1, &z_subcoord[1]);
1277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (y = 0; y < 2; y++) {
1278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (x = 0; x < 2; x++) {
1279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            offset[0][y][x] = lp_build_add(&bld->int_coord_bld,
1280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           offset[0][y][x], z_offset0);
1281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            offset[1][y][x] = lp_build_add(&bld->int_coord_bld,
1282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           offset[1][y][x], z_offset1);
1283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (bld->static_state->target == PIPE_TEXTURE_CUBE) {
1287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef z_offset;
1288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      z_offset = lp_build_mul(&bld->int_coord_bld, r, img_stride_vec);
1289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (y = 0; y < 2; y++) {
1290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (x = 0; x < 2; x++) {
1291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* The r coord is the cube face in [0,5] */
1292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            offset[0][y][x] = lp_build_add(&bld->int_coord_bld,
1293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           offset[0][y][x], z_offset);
1294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_sample_fetch_image_linear(bld, data_ptr, offset,
1299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      x_subcoord, y_subcoord,
1300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      s_fpart, t_fpart, r_fpart,
1301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      colors_lo, colors_hi);
1302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
1306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Sample the texture/mipmap using given image filter and mip filter.
1307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * data0_ptr and data1_ptr point to the two mipmap levels to sample
1308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * from.  width0/1_vec, height0/1_vec, depth0/1_vec indicate their sizes.
1309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If we're using nearest miplevel sampling the '1' values will be null/unused.
1310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
1312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_sample_mipmap(struct lp_build_sample_context *bld,
1313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       unsigned img_filter,
1314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       unsigned mip_filter,
1315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       LLVMValueRef s,
1316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       LLVMValueRef t,
1317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       LLVMValueRef r,
1318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       LLVMValueRef ilevel0,
1319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       LLVMValueRef ilevel1,
1320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       LLVMValueRef lod_fpart,
1321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       LLVMValueRef colors_lo_var,
1322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       LLVMValueRef colors_hi_var)
1323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMBuilderRef builder = bld->gallivm->builder;
1325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef size0;
1326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef size1;
1327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef row_stride0_vec = NULL;
1328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef row_stride1_vec = NULL;
1329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef img_stride0_vec = NULL;
1330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef img_stride1_vec = NULL;
1331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef data_ptr0;
1332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef data_ptr1;
1333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef colors0_lo, colors0_hi;
1334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef colors1_lo, colors1_hi;
1335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* sample the first mipmap level */
1337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_mipmap_level_sizes(bld, ilevel0,
1338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               &size0,
1339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               &row_stride0_vec, &img_stride0_vec);
1340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   data_ptr0 = lp_build_get_mipmap_level(bld, ilevel0);
1341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (util_cpu_caps.has_avx && bld->coord_type.length > 4) {
1342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (img_filter == PIPE_TEX_FILTER_NEAREST) {
1343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lp_build_sample_image_nearest_afloat(bld,
1344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              size0,
1345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              row_stride0_vec, img_stride0_vec,
1346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              data_ptr0, s, t, r,
1347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              &colors0_lo, &colors0_hi);
1348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
1350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(img_filter == PIPE_TEX_FILTER_LINEAR);
1351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lp_build_sample_image_linear_afloat(bld,
1352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                             size0,
1353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                             row_stride0_vec, img_stride0_vec,
1354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                             data_ptr0, s, t, r,
1355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                             &colors0_lo, &colors0_hi);
1356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
1359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (img_filter == PIPE_TEX_FILTER_NEAREST) {
1360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lp_build_sample_image_nearest(bld,
1361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       size0,
1362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       row_stride0_vec, img_stride0_vec,
1363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       data_ptr0, s, t, r,
1364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       &colors0_lo, &colors0_hi);
1365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
1367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(img_filter == PIPE_TEX_FILTER_LINEAR);
1368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lp_build_sample_image_linear(bld,
1369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      size0,
1370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      row_stride0_vec, img_stride0_vec,
1371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      data_ptr0, s, t, r,
1372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      &colors0_lo, &colors0_hi);
1373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Store the first level's colors in the output variables */
1377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMBuildStore(builder, colors0_lo, colors_lo_var);
1378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMBuildStore(builder, colors0_hi, colors_hi_var);
1379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
1381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef h16vec_scale = lp_build_const_vec(bld->gallivm,
1382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                     bld->perquadf_bld.type, 256.0);
1383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMTypeRef i32vec_type = lp_build_vec_type(bld->gallivm, bld->perquadi_bld.type);
1384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct lp_build_if_state if_ctx;
1385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef need_lerp;
1386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned num_quads = bld->coord_bld.type.length / 4;
1387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned i;
1388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lod_fpart = LLVMBuildFMul(builder, lod_fpart, h16vec_scale, "");
1390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lod_fpart = LLVMBuildFPToSI(builder, lod_fpart, i32vec_type, "lod_fpart.fixed16");
1391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* need_lerp = lod_fpart > 0 */
1393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (num_quads == 1) {
1394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         need_lerp = LLVMBuildICmp(builder, LLVMIntSGT,
1395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   lod_fpart, bld->perquadi_bld.zero,
1396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   "need_lerp");
1397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
1399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /*
1400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * We'll do mip filtering if any of the quads need it.
1401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * It might be better to split the vectors here and only fetch/filter
1402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * quads which need it.
1403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
1404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /*
1405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * We need to clamp lod_fpart here since we can get negative
1406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * values which would screw up filtering if not all
1407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * lod_fpart values have same sign.
1408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * We can however then skip the greater than comparison.
1409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
1410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lod_fpart = lp_build_max(&bld->perquadi_bld, lod_fpart,
1411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  bld->perquadi_bld.zero);
1412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         need_lerp = lp_build_any_true_range(&bld->perquadi_bld, num_quads, lod_fpart);
1413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_if(&if_ctx, bld->gallivm, need_lerp);
1416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      {
1417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         struct lp_build_context h16_bld;
1418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lp_build_context_init(&h16_bld, bld->gallivm, lp_type_ufixed(16, bld->vector_width));
1420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* sample the second mipmap level */
1422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lp_build_mipmap_level_sizes(bld, ilevel1,
1423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     &size1,
1424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     &row_stride1_vec, &img_stride1_vec);
1425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         data_ptr1 = lp_build_get_mipmap_level(bld, ilevel1);
1426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (util_cpu_caps.has_avx && bld->coord_type.length > 4) {
1428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (img_filter == PIPE_TEX_FILTER_NEAREST) {
1429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               lp_build_sample_image_nearest_afloat(bld,
1430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                    size1,
1431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                    row_stride1_vec, img_stride1_vec,
1432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                    data_ptr1, s, t, r,
1433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                    &colors1_lo, &colors1_hi);
1434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            else {
1436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               lp_build_sample_image_linear_afloat(bld,
1437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                   size1,
1438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                   row_stride1_vec, img_stride1_vec,
1439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                   data_ptr1, s, t, r,
1440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                   &colors1_lo, &colors1_hi);
1441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else {
1444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (img_filter == PIPE_TEX_FILTER_NEAREST) {
1445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               lp_build_sample_image_nearest(bld,
1446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                             size1,
1447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                             row_stride1_vec, img_stride1_vec,
1448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                             data_ptr1, s, t, r,
1449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                             &colors1_lo, &colors1_hi);
1450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            else {
1452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               lp_build_sample_image_linear(bld,
1453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                            size1,
1454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                            row_stride1_vec, img_stride1_vec,
1455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                            data_ptr1, s, t, r,
1456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                            &colors1_lo, &colors1_hi);
1457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* interpolate samples from the two mipmap levels */
1461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (num_quads == 1) {
1463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            lod_fpart = LLVMBuildTrunc(builder, lod_fpart, h16_bld.elem_type, "");
1464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            lod_fpart = lp_build_broadcast_scalar(&h16_bld, lod_fpart);
1465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if HAVE_LLVM == 0x208
1467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* This is a work-around for a bug in LLVM 2.8.
1468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * Evidently, something goes wrong in the construction of the
1469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * lod_fpart short[8] vector.  Adding this no-effect shuffle seems
1470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * to force the vector to be properly constructed.
1471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * Tested with mesa-demos/src/tests/mipmap_limits.c (press t, f).
1472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             */
1473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            {
1474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               LLVMValueRef shuffles[8], shuffle;
1475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               assert(h16_bld.type.length <= Elements(shuffles));
1476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               for (i = 0; i < h16_bld.type.length; i++)
1477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  shuffles[i] = lp_build_const_int32(bld->gallivm, 2 * (i & 1));
1478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               shuffle = LLVMConstVector(shuffles, h16_bld.type.length);
1479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               lod_fpart = LLVMBuildShuffleVector(builder,
1480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                  lod_fpart, lod_fpart,
1481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                  shuffle, "");
1482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
1484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            colors0_lo = lp_build_lerp(&h16_bld, lod_fpart,
1486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       colors0_lo, colors1_lo);
1487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            colors0_hi = lp_build_lerp(&h16_bld, lod_fpart,
1488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       colors0_hi, colors1_hi);
1489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else {
1491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            LLVMValueRef lod_parts[LP_MAX_VECTOR_LENGTH/16];
1492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            struct lp_type perquadi16_type = bld->perquadi_bld.type;
1493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            perquadi16_type.width /= 2;
1494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            perquadi16_type.length *= 2;
1495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            lod_fpart = LLVMBuildBitCast(builder, lod_fpart,
1496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         lp_build_vec_type(bld->gallivm,
1497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                           perquadi16_type), "");
1498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* XXX this only works for exactly 2 quads. More quads need shuffle */
1499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            assert(num_quads == 2);
1500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            for (i = 0; i < num_quads; i++) {
1501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               LLVMValueRef indexi2 = lp_build_const_int32(bld->gallivm, i*2);
1502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               lod_parts[i] = lp_build_extract_broadcast(bld->gallivm,
1503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                         perquadi16_type,
1504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                         h16_bld.type,
1505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                         lod_fpart,
1506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                         indexi2);
1507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            colors0_lo = lp_build_lerp(&h16_bld, lod_parts[0],
1509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       colors0_lo, colors1_lo);
1510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            colors0_hi = lp_build_lerp(&h16_bld, lod_parts[1],
1511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       colors0_hi, colors1_hi);
1512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMBuildStore(builder, colors0_lo, colors_lo_var);
1515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMBuildStore(builder, colors0_hi, colors_hi_var);
1516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_endif(&if_ctx);
1518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
1524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Texture sampling in AoS format.  Used when sampling common 32-bit/texel
1525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * formats.  1D/2D/3D/cube texture supported.  All mipmap sampling modes
1526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * but only limited texture coord wrap modes.
1527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
1529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_sample_aos(struct lp_build_sample_context *bld,
1530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    unsigned unit,
1531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    LLVMValueRef s,
1532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    LLVMValueRef t,
1533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    LLVMValueRef r,
1534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    LLVMValueRef lod_ipart,
1535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    LLVMValueRef lod_fpart,
1536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    LLVMValueRef ilevel0,
1537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    LLVMValueRef ilevel1,
1538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    LLVMValueRef texel_out[4])
1539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_build_context *int_bld = &bld->int_bld;
1541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMBuilderRef builder = bld->gallivm->builder;
1542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const unsigned mip_filter = bld->static_state->min_mip_filter;
1543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const unsigned min_filter = bld->static_state->min_img_filter;
1544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const unsigned mag_filter = bld->static_state->mag_img_filter;
1545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const unsigned dims = bld->dims;
1546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef packed, packed_lo, packed_hi;
1547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef unswizzled[4];
1548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_build_context h16_bld;
1549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* we only support the common/simple wrap modes at this time */
1551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(lp_is_simple_wrap_mode(bld->static_state->wrap_s));
1552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dims >= 2)
1553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(lp_is_simple_wrap_mode(bld->static_state->wrap_t));
1554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dims >= 3)
1555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(lp_is_simple_wrap_mode(bld->static_state->wrap_r));
1556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* make 16-bit fixed-pt builder context */
1559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_context_init(&h16_bld, bld->gallivm, lp_type_ufixed(16, bld->vector_width));
1560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
1562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Get/interpolate texture colors.
1563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   packed_lo = lp_build_alloca(bld->gallivm, h16_bld.vec_type, "packed_lo");
1566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   packed_hi = lp_build_alloca(bld->gallivm, h16_bld.vec_type, "packed_hi");
1567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (min_filter == mag_filter) {
1569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* no need to distinguish between minification and magnification */
1570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_sample_mipmap(bld,
1571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             min_filter, mip_filter,
1572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             s, t, r,
1573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             ilevel0, ilevel1, lod_fpart,
1574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             packed_lo, packed_hi);
1575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
1577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Emit conditional to choose min image filter or mag image filter
1578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * depending on the lod being > 0 or <= 0, respectively.
1579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct lp_build_if_state if_ctx;
1581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef minify;
1582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* minify = lod >= 0.0 */
1584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      minify = LLVMBuildICmp(builder, LLVMIntSGE,
1585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             lod_ipart, int_bld->zero, "");
1586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_if(&if_ctx, bld->gallivm, minify);
1588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      {
1589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Use the minification filter */
1590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lp_build_sample_mipmap(bld,
1591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                min_filter, mip_filter,
1592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                s, t, r,
1593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                ilevel0, ilevel1, lod_fpart,
1594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                packed_lo, packed_hi);
1595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_else(&if_ctx);
1597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      {
1598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Use the magnification filter */
1599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lp_build_sample_mipmap(bld,
1600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                mag_filter, PIPE_TEX_MIPFILTER_NONE,
1601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                s, t, r,
1602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                ilevel0, NULL, NULL,
1603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                packed_lo, packed_hi);
1604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_endif(&if_ctx);
1606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
1609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * combine the values stored in 'packed_lo' and 'packed_hi' variables
1610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * into 'packed'
1611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   packed = lp_build_pack2(bld->gallivm,
1613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           h16_bld.type, lp_type_unorm(8, bld->vector_width),
1614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           LLVMBuildLoad(builder, packed_lo, ""),
1615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           LLVMBuildLoad(builder, packed_hi, ""));
1616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
1618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Convert to SoA and swizzle.
1619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_rgba8_to_f32_soa(bld->gallivm,
1621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             bld->texel_type,
1622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             packed, unswizzled);
1623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (util_format_is_rgba8_variant(bld->format_desc)) {
1625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_format_swizzle_soa(bld->format_desc,
1626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  &bld->texel_bld,
1627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  unswizzled, texel_out);
1628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
1630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      texel_out[0] = unswizzled[0];
1631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      texel_out[1] = unswizzled[1];
1632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      texel_out[2] = unswizzled[2];
1633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      texel_out[3] = unswizzled[3];
1634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1636