sp_tex_sample.c revision 5fdac2dcea09c654725666b3cab5f59dfc9e31a5
10dc4eea64f56cc93e5359372b08b99a2d600273cBrian/**************************************************************************
20dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
30dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
40dc4eea64f56cc93e5359372b08b99a2d600273cBrian * All Rights Reserved.
53ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul * Copyright 2008 VMware, Inc.  All rights reserved.
60dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
70dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Permission is hereby granted, free of charge, to any person obtaining a
80dc4eea64f56cc93e5359372b08b99a2d600273cBrian * copy of this software and associated documentation files (the
90dc4eea64f56cc93e5359372b08b99a2d600273cBrian * "Software"), to deal in the Software without restriction, including
100dc4eea64f56cc93e5359372b08b99a2d600273cBrian * without limitation the rights to use, copy, modify, merge, publish,
110dc4eea64f56cc93e5359372b08b99a2d600273cBrian * distribute, sub license, and/or sell copies of the Software, and to
120dc4eea64f56cc93e5359372b08b99a2d600273cBrian * permit persons to whom the Software is furnished to do so, subject to
130dc4eea64f56cc93e5359372b08b99a2d600273cBrian * the following conditions:
140dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
150dc4eea64f56cc93e5359372b08b99a2d600273cBrian * The above copyright notice and this permission notice (including the
160dc4eea64f56cc93e5359372b08b99a2d600273cBrian * next paragraph) shall be included in all copies or substantial portions
170dc4eea64f56cc93e5359372b08b99a2d600273cBrian * of the Software.
180dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
190dc4eea64f56cc93e5359372b08b99a2d600273cBrian * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
200dc4eea64f56cc93e5359372b08b99a2d600273cBrian * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
210dc4eea64f56cc93e5359372b08b99a2d600273cBrian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
220dc4eea64f56cc93e5359372b08b99a2d600273cBrian * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
230dc4eea64f56cc93e5359372b08b99a2d600273cBrian * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
240dc4eea64f56cc93e5359372b08b99a2d600273cBrian * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
250dc4eea64f56cc93e5359372b08b99a2d600273cBrian * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
260dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
270dc4eea64f56cc93e5359372b08b99a2d600273cBrian **************************************************************************/
280dc4eea64f56cc93e5359372b08b99a2d600273cBrian
290dc4eea64f56cc93e5359372b08b99a2d600273cBrian/**
300dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Texture sampling
310dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
320dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Authors:
330dc4eea64f56cc93e5359372b08b99a2d600273cBrian *   Brian Paul
340dc4eea64f56cc93e5359372b08b99a2d600273cBrian */
350dc4eea64f56cc93e5359372b08b99a2d600273cBrian
3608f33a025100dea2d951e6d628891fe294b18082Brian#include "sp_context.h"
377925274da323d5a896b557181d4016e0391f026fBrian#include "sp_quad.h"
380dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "sp_surface.h"
390b9e96fae9493d5d58f046e01c983a3c4267090eBrian#include "sp_texture.h"
400dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "sp_tex_sample.h"
4170eb7996f265f3634dabda078f13d1be3533cc65Brian#include "sp_tile_cache.h"
420dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "pipe/p_context.h"
430dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "pipe/p_defines.h"
441a46dcc8a927dfb38ca1381e7b3dafb789f8257cBrian Paul#include "util/u_math.h"
454f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h"
460dc4eea64f56cc93e5359372b08b99a2d600273cBrian
470dc4eea64f56cc93e5359372b08b99a2d600273cBrian
483ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul
4908f33a025100dea2d951e6d628891fe294b18082Brian/*
5008f33a025100dea2d951e6d628891fe294b18082Brian * Note, the FRAC macro has to work perfectly.  Otherwise you'll sometimes
5108f33a025100dea2d951e6d628891fe294b18082Brian * see 1-pixel bands of improperly weighted linear-filtered textures.
5208f33a025100dea2d951e6d628891fe294b18082Brian * The tests/texwrap.c demo is a good test.
5308f33a025100dea2d951e6d628891fe294b18082Brian * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0.
5408f33a025100dea2d951e6d628891fe294b18082Brian * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x).
5508f33a025100dea2d951e6d628891fe294b18082Brian */
569935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul#define FRAC(f)  ((f) - util_ifloor(f))
5708f33a025100dea2d951e6d628891fe294b18082Brian
5808f33a025100dea2d951e6d628891fe294b18082Brian
5908f33a025100dea2d951e6d628891fe294b18082Brian/**
6008f33a025100dea2d951e6d628891fe294b18082Brian * Linear interpolation macro
6108f33a025100dea2d951e6d628891fe294b18082Brian */
6238bee46e83b18ff4ad42d340b507b1a15b4326c7Brianstatic INLINE float
6338bee46e83b18ff4ad42d340b507b1a15b4326c7Brianlerp(float a, float v0, float v1)
6438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian{
6538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   return v0 + a * (v1 - v0);
6638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian}
670dc4eea64f56cc93e5359372b08b99a2d600273cBrian
680dc4eea64f56cc93e5359372b08b99a2d600273cBrian
690dc4eea64f56cc93e5359372b08b99a2d600273cBrian/**
700dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Do 2D/biliner interpolation of float values.
710dc4eea64f56cc93e5359372b08b99a2d600273cBrian * v00, v10, v01 and v11 are typically four texture samples in a square/box.
720dc4eea64f56cc93e5359372b08b99a2d600273cBrian * a and b are the horizontal and vertical interpolants.
730dc4eea64f56cc93e5359372b08b99a2d600273cBrian * It's important that this function is inlined when compiled with
740dc4eea64f56cc93e5359372b08b99a2d600273cBrian * optimization!  If we find that's not true on some systems, convert
750dc4eea64f56cc93e5359372b08b99a2d600273cBrian * to a macro.
760dc4eea64f56cc93e5359372b08b99a2d600273cBrian */
77b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic INLINE float
78b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianlerp_2d(float a, float b,
79b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian        float v00, float v10, float v01, float v11)
800dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
8138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   const float temp0 = lerp(a, v00, v10);
8238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   const float temp1 = lerp(a, v01, v11);
8338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   return lerp(b, temp0, temp1);
8438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian}
8538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
8638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
8738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian/**
8838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * As above, but 3D interpolation of 8 values.
8938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian */
9038bee46e83b18ff4ad42d340b507b1a15b4326c7Brianstatic INLINE float
9138bee46e83b18ff4ad42d340b507b1a15b4326c7Brianlerp_3d(float a, float b, float c,
9238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian        float v000, float v100, float v010, float v110,
9338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian        float v001, float v101, float v011, float v111)
9438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian{
9538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   const float temp0 = lerp_2d(a, b, v000, v100, v010, v110);
9638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   const float temp1 = lerp_2d(a, b, v001, v101, v011, v111);
9738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   return lerp(c, temp0, temp1);
980dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
990dc4eea64f56cc93e5359372b08b99a2d600273cBrian
1000dc4eea64f56cc93e5359372b08b99a2d600273cBrian
10138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
1020dc4eea64f56cc93e5359372b08b99a2d600273cBrian/**
103906768316d9521a32d9a7eebc9edaf76c06a98a7Brian * If A is a signed integer, A % B doesn't give the right value for A < 0
104906768316d9521a32d9a7eebc9edaf76c06a98a7Brian * (in terms of texture repeat).  Just casting to unsigned fixes that.
1050dc4eea64f56cc93e5359372b08b99a2d600273cBrian */
106906768316d9521a32d9a7eebc9edaf76c06a98a7Brian#define REMAINDER(A, B) ((unsigned) (A) % (unsigned) (B))
10708f33a025100dea2d951e6d628891fe294b18082Brian
10808f33a025100dea2d951e6d628891fe294b18082Brian
10908f33a025100dea2d951e6d628891fe294b18082Brian/**
11038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * Apply texture coord wrapping mode and return integer texture indexes
11138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * for a vector of four texcoords (S or T or P).
11208f33a025100dea2d951e6d628891fe294b18082Brian * \param wrapMode  PIPE_TEX_WRAP_x
11338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param s  the incoming texcoords
11408f33a025100dea2d951e6d628891fe294b18082Brian * \param size  the texture image size
11538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param icoord  returns the integer texcoords
11608f33a025100dea2d951e6d628891fe294b18082Brian * \return  integer texture index
11708f33a025100dea2d951e6d628891fe294b18082Brian */
11838bee46e83b18ff4ad42d340b507b1a15b4326c7Brianstatic INLINE void
11938bee46e83b18ff4ad42d340b507b1a15b4326c7Briannearest_texcoord_4(unsigned wrapMode, const float s[4], unsigned size,
12038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                   int icoord[4])
1210dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
12238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   uint ch;
1230dc4eea64f56cc93e5359372b08b99a2d600273cBrian   switch (wrapMode) {
1240dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_WRAP_REPEAT:
12508f33a025100dea2d951e6d628891fe294b18082Brian      /* s limited to [0,1) */
12608f33a025100dea2d951e6d628891fe294b18082Brian      /* i limited to [0,size-1] */
12738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
12838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         int i = util_ifloor(s[ch] * size);
12938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord[ch] = REMAINDER(i, size);
13038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
13138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
1320dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_WRAP_CLAMP:
13308f33a025100dea2d951e6d628891fe294b18082Brian      /* s limited to [0,1] */
13408f33a025100dea2d951e6d628891fe294b18082Brian      /* i limited to [0,size-1] */
13538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
13638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (s[ch] <= 0.0F)
13738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord[ch] = 0;
13838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         else if (s[ch] >= 1.0F)
13938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord[ch] = size - 1;
14038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         else
14138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord[ch] = util_ifloor(s[ch] * size);
14238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
14338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
14408f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
14508f33a025100dea2d951e6d628891fe294b18082Brian      {
14608f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [min,max] */
14708f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [0, size-1] */
148b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = 1.0F / (2.0F * size);
149b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
15038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (ch = 0; ch < 4; ch++) {
15138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (s[ch] < min)
15238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = 0;
15338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else if (s[ch] > max)
15438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = size - 1;
15538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else
15638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = util_ifloor(s[ch] * size);
15738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         }
15808f33a025100dea2d951e6d628891fe294b18082Brian      }
15938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
16008f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
16108f33a025100dea2d951e6d628891fe294b18082Brian      {
16208f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [min,max] */
16308f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [-1, size] */
164b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = -1.0F / (2.0F * size);
165b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
16638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (ch = 0; ch < 4; ch++) {
16738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (s[ch] <= min)
16838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = -1;
16938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else if (s[ch] >= max)
17038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = size;
17138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else
17238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = util_ifloor(s[ch] * size);
17338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         }
17408f33a025100dea2d951e6d628891fe294b18082Brian      }
17538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
17608f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_REPEAT:
17708f33a025100dea2d951e6d628891fe294b18082Brian      {
178b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = 1.0F / (2.0F * size);
179b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
18038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (ch = 0; ch < 4; ch++) {
18138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            const int flr = util_ifloor(s[ch]);
18238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            float u;
18338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (flr & 1)
18438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               u = 1.0F - (s[ch] - (float) flr);
18538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else
18638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               u = s[ch] - (float) flr;
18738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (u < min)
18838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = 0;
18938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else if (u > max)
19038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = size - 1;
19138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else
19238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = util_ifloor(u * size);
19338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         }
19408f33a025100dea2d951e6d628891fe294b18082Brian      }
19538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
19608f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP:
19738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
19808f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [0,1] */
19908f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [0,size-1] */
20038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         const float u = fabsf(s[ch]);
20108f33a025100dea2d951e6d628891fe294b18082Brian         if (u <= 0.0F)
20238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord[ch] = 0;
20308f33a025100dea2d951e6d628891fe294b18082Brian         else if (u >= 1.0F)
20438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord[ch] = size - 1;
20508f33a025100dea2d951e6d628891fe294b18082Brian         else
20638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord[ch] = util_ifloor(u * size);
20708f33a025100dea2d951e6d628891fe294b18082Brian      }
20838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
20908f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
21008f33a025100dea2d951e6d628891fe294b18082Brian      {
21108f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [min,max] */
21208f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [0, size-1] */
213b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = 1.0F / (2.0F * size);
214b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
21538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (ch = 0; ch < 4; ch++) {
21638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            const float u = fabsf(s[ch]);
21738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (u < min)
21838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = 0;
21938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else if (u > max)
22038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = size - 1;
22138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else
22238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = util_ifloor(u * size);
22338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         }
22408f33a025100dea2d951e6d628891fe294b18082Brian      }
22538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
22608f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
22708f33a025100dea2d951e6d628891fe294b18082Brian      {
22808f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [min,max] */
22908f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [0, size-1] */
230b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = -1.0F / (2.0F * size);
231b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
23238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (ch = 0; ch < 4; ch++) {
23338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            const float u = fabsf(s[ch]);
23438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (u < min)
23538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = -1;
23638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else if (u > max)
23738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = size;
23838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else
23938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = util_ifloor(u * size);
24038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         }
24108f33a025100dea2d951e6d628891fe294b18082Brian      }
24238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
2430dc4eea64f56cc93e5359372b08b99a2d600273cBrian   default:
2440dc4eea64f56cc93e5359372b08b99a2d600273cBrian      assert(0);
2450dc4eea64f56cc93e5359372b08b99a2d600273cBrian   }
2460dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
2470dc4eea64f56cc93e5359372b08b99a2d600273cBrian
24808f33a025100dea2d951e6d628891fe294b18082Brian
24908f33a025100dea2d951e6d628891fe294b18082Brian/**
25038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * Used to compute texel locations for linear sampling for four texcoords.
25108f33a025100dea2d951e6d628891fe294b18082Brian * \param wrapMode  PIPE_TEX_WRAP_x
25238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param s  the texcoords
25308f33a025100dea2d951e6d628891fe294b18082Brian * \param size  the texture image size
25438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param icoord0  returns first texture indexes
25538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param icoord1  returns second texture indexes (usually icoord0 + 1)
25638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param w  returns blend factor/weight between texture indexes
25738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param icoord  returns the computed integer texture coords
25808f33a025100dea2d951e6d628891fe294b18082Brian */
2590dc4eea64f56cc93e5359372b08b99a2d600273cBrianstatic INLINE void
26038bee46e83b18ff4ad42d340b507b1a15b4326c7Brianlinear_texcoord_4(unsigned wrapMode, const float s[4], unsigned size,
26138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                  int icoord0[4], int icoord1[4], float w[4])
2620dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
26338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   uint ch;
26438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
2650dc4eea64f56cc93e5359372b08b99a2d600273cBrian   switch (wrapMode) {
2660dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_WRAP_REPEAT:
26738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
26838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float u = s[ch] * size - 0.5F;
26938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord0[ch] = REMAINDER(util_ifloor(u), size);
27038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord1[ch] = REMAINDER(icoord0[ch] + 1, size);
27138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         w[ch] = FRAC(u);
27238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
27338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      break;;
2740dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_WRAP_CLAMP:
27538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
27638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float u = CLAMP(s[ch], 0.0F, 1.0F);
27738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         u = u * size - 0.5f;
27838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord0[ch] = util_ifloor(u);
27938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord1[ch] = icoord0[ch] + 1;
28038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         w[ch] = FRAC(u);
28138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
28238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      break;;
28308f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
28438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
28538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float u = CLAMP(s[ch], 0.0F, 1.0F);
28638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         u = u * size - 0.5f;
28738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord0[ch] = util_ifloor(u);
28838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord1[ch] = icoord0[ch] + 1;
28938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (icoord0[ch] < 0)
29038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord0[ch] = 0;
29138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (icoord1[ch] >= (int) size)
29238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord1[ch] = size - 1;
29338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         w[ch] = FRAC(u);
29438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
29538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      break;;
29608f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
29708f33a025100dea2d951e6d628891fe294b18082Brian      {
298b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = -1.0F / (2.0F * size);
299b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
30038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (ch = 0; ch < 4; ch++) {
30138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            float u = CLAMP(s[ch], min, max);
30238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            u = u * size - 0.5f;
30338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord0[ch] = util_ifloor(u);
30438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord1[ch] = icoord0[ch] + 1;
30538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            w[ch] = FRAC(u);
30638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         }
30708f33a025100dea2d951e6d628891fe294b18082Brian      }
30838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      break;;
30908f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_REPEAT:
31038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
31138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         const int flr = util_ifloor(s[ch]);
31238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float u;
31308f33a025100dea2d951e6d628891fe294b18082Brian         if (flr & 1)
31438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            u = 1.0F - (s[ch] - (float) flr);
31508f33a025100dea2d951e6d628891fe294b18082Brian         else
31638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            u = s[ch] - (float) flr;
31738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         u = u * size - 0.5F;
31838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord0[ch] = util_ifloor(u);
31938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord1[ch] = icoord0[ch] + 1;
32038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (icoord0[ch] < 0)
32138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord0[ch] = 0;
32238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (icoord1[ch] >= (int) size)
32338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord1[ch] = size - 1;
32438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         w[ch] = FRAC(u);
32508f33a025100dea2d951e6d628891fe294b18082Brian      }
32638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      break;;
32708f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP:
32838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
32938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float u = fabsf(s[ch]);
33038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (u >= 1.0F)
33138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            u = (float) size;
33238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         else
33338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            u *= size;
33438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         u -= 0.5F;
33538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord0[ch] = util_ifloor(u);
33638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord1[ch] = icoord0[ch] + 1;
33738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         w[ch] = FRAC(u);
33838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
33938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      break;;
34008f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
34138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
34238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float u = fabsf(s[ch]);
34338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (u >= 1.0F)
34438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            u = (float) size;
34538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         else
34638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            u *= size;
34738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         u -= 0.5F;
34838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord0[ch] = util_ifloor(u);
34938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord1[ch] = icoord0[ch] + 1;
35038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (icoord0[ch] < 0)
35138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord0[ch] = 0;
35238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (icoord1[ch] >= (int) size)
35338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord1[ch] = size - 1;
35438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         w[ch] = FRAC(u);
35538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
35638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      break;;
35708f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
35808f33a025100dea2d951e6d628891fe294b18082Brian      {
359b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = -1.0F / (2.0F * size);
360b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
36138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (ch = 0; ch < 4; ch++) {
36238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            float u = fabsf(s[ch]);
36338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (u <= min)
36438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               u = min * size;
36538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else if (u >= max)
36638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               u = max * size;
36738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else
36838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               u *= size;
36938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            u -= 0.5F;
37038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord0[ch] = util_ifloor(u);
37138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord1[ch] = icoord0[ch] + 1;
37238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            w[ch] = FRAC(u);
37338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         }
37408f33a025100dea2d951e6d628891fe294b18082Brian      }
37538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      break;;
3760dc4eea64f56cc93e5359372b08b99a2d600273cBrian   default:
3770dc4eea64f56cc93e5359372b08b99a2d600273cBrian      assert(0);
3780dc4eea64f56cc93e5359372b08b99a2d600273cBrian   }
3790dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
3800dc4eea64f56cc93e5359372b08b99a2d600273cBrian
3810dc4eea64f56cc93e5359372b08b99a2d600273cBrian
382b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian/**
383b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * For RECT textures / unnormalized texcoords
384b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * Only a subset of wrap modes supported.
385b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian */
38638bee46e83b18ff4ad42d340b507b1a15b4326c7Brianstatic INLINE void
38738bee46e83b18ff4ad42d340b507b1a15b4326c7Briannearest_texcoord_unnorm_4(unsigned wrapMode, const float s[4], unsigned size,
38838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                          int icoord[4])
389b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{
39038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   uint ch;
391b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   switch (wrapMode) {
392b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP:
39338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
39438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         int i = util_ifloor(s[ch]);
39538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord[ch]= CLAMP(i, 0, (int) size-1);
39638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
39738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
398b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
399b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      /* fall-through */
400b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
40138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
40238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord[ch]= util_ifloor( CLAMP(s[ch], 0.5F, (float) size - 0.5F) );
40338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
40438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
405b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   default:
406b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      assert(0);
407b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   }
408b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian}
409b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
410b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
411b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian/**
412b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * For RECT textures / unnormalized texcoords.
413b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * Only a subset of wrap modes supported.
414b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian */
415b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrianstatic INLINE void
41638bee46e83b18ff4ad42d340b507b1a15b4326c7Brianlinear_texcoord_unnorm_4(unsigned wrapMode, const float s[4], unsigned size,
41738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                         int icoord0[4], int icoord1[4], float w[4])
418b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{
41938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   uint ch;
420b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   switch (wrapMode) {
421b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP:
42238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
42338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         /* Not exactly what the spec says, but it matches NVIDIA output */
42438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float u = CLAMP(s[ch] - 0.5F, 0.0f, (float) size - 1.0f);
42538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord0[ch] = util_ifloor(u);
42638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord1[ch] = icoord0[ch] + 1;
42738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         w[ch] = FRAC(u);
42838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
42938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
430b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
431b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      /* fall-through */
432b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
43338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
43438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float u = CLAMP(s[ch], 0.5F, (float) size - 0.5F);
43538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         u -= 0.5F;
43638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord0[ch] = util_ifloor(u);
43738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord1[ch] = icoord0[ch] + 1;
43838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (icoord1[ch] > (int) size - 1)
43938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord1[ch] = size - 1;
44038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         w[ch] = FRAC(u);
44138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
442b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      break;
443b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   default:
444b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      assert(0);
445b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   }
446b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian}
447b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
448b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
44970af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwellstatic unsigned
450a34b8594b7b2d00404bb639621ec1ce918ba0786Brianchoose_cube_face(float rx, float ry, float rz, float *newS, float *newT)
45134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
45234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   /*
45334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      major axis
45434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      direction     target                             sc     tc    ma
45534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      ----------    -------------------------------    ---    ---   ---
45634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       +rx          TEXTURE_CUBE_MAP_POSITIVE_X_EXT    -rz    -ry   rx
45734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       -rx          TEXTURE_CUBE_MAP_NEGATIVE_X_EXT    +rz    -ry   rx
45834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       +ry          TEXTURE_CUBE_MAP_POSITIVE_Y_EXT    +rx    +rz   ry
45934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       -ry          TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT    +rx    -rz   ry
46034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       +rz          TEXTURE_CUBE_MAP_POSITIVE_Z_EXT    +rx    -ry   rz
46134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       -rz          TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT    -rx    -ry   rz
46234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   */
4639935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul   const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz);
46470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   unsigned face;
465b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   float sc, tc, ma;
46634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
46734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   if (arx > ary && arx > arz) {
46834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      if (rx >= 0.0F) {
46934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_POS_X;
47034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = -rz;
47134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
47234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arx;
47334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
47434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      else {
47534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_NEG_X;
47634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rz;
47734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
47834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arx;
47934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
48034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
48134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   else if (ary > arx && ary > arz) {
48234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      if (ry >= 0.0F) {
48334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_POS_Y;
48434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rx;
48534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = rz;
48634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = ary;
48734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
48834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      else {
48934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_NEG_Y;
49034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rx;
49134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -rz;
49234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = ary;
49334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
49434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
49534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   else {
49634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      if (rz > 0.0F) {
49734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_POS_Z;
49834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rx;
49934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
50034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arz;
50134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
50234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      else {
50334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_NEG_Z;
50434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = -rx;
50534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
50634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arz;
50734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
50834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
50934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
510a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   *newS = ( sc / ma + 1.0F ) * 0.5F;
511a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   *newT = ( tc / ma + 1.0F ) * 0.5F;
51234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
51334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   return face;
51434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
51534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
51634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
517b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/**
518b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * Examine the quad's texture coordinates to compute the partial
519b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * derivatives w.r.t X and Y, then compute lambda (level of detail).
520b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian *
521b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * This is only done for fragment shaders, not vertex shaders.
522b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian */
523b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic float
5240b9e96fae9493d5d58f046e01c983a3c4267090eBriancompute_lambda(const struct pipe_texture *tex,
5250b9e96fae9493d5d58f046e01c983a3c4267090eBrian               const struct pipe_sampler_state *sampler,
526b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float s[QUAD_SIZE],
527b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float t[QUAD_SIZE],
528f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian               const float p[QUAD_SIZE],
529f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian               float lodbias)
530b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian{
531b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   float rho, lambda;
532b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
5330b9e96fae9493d5d58f046e01c983a3c4267090eBrian   assert(sampler->normalized_coords);
534b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
535b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   assert(s);
536b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   {
537b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dsdx = s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT];
538b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dsdy = s[QUAD_TOP_LEFT]     - s[QUAD_BOTTOM_LEFT];
5399935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      dsdx = fabsf(dsdx);
5409935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      dsdy = fabsf(dsdy);
5410b9e96fae9493d5d58f046e01c983a3c4267090eBrian      rho = MAX2(dsdx, dsdy) * tex->width[0];
542b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
543b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   if (t) {
544b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT];
545b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dtdy = t[QUAD_TOP_LEFT]     - t[QUAD_BOTTOM_LEFT];
546b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float max;
5479935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      dtdx = fabsf(dtdx);
5489935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      dtdy = fabsf(dtdy);
5490b9e96fae9493d5d58f046e01c983a3c4267090eBrian      max = MAX2(dtdx, dtdy) * tex->height[0];
550b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      rho = MAX2(rho, max);
551b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
552b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   if (p) {
553b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dpdx = p[QUAD_BOTTOM_RIGHT] - p[QUAD_BOTTOM_LEFT];
554b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dpdy = p[QUAD_TOP_LEFT]     - p[QUAD_BOTTOM_LEFT];
555b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float max;
5569935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      dpdx = fabsf(dpdx);
5579935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      dpdy = fabsf(dpdy);
5580b9e96fae9493d5d58f046e01c983a3c4267090eBrian      max = MAX2(dpdx, dpdy) * tex->depth[0];
559b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      rho = MAX2(rho, max);
560b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
561b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
5621a46dcc8a927dfb38ca1381e7b3dafb789f8257cBrian Paul   lambda = util_fast_log2(rho);
5630b9e96fae9493d5d58f046e01c983a3c4267090eBrian   lambda += lodbias + sampler->lod_bias;
5640b9e96fae9493d5d58f046e01c983a3c4267090eBrian   lambda = CLAMP(lambda, sampler->min_lod, sampler->max_lod);
565b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
566b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   return lambda;
567b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian}
568b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
569b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
570f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian/**
571c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * Do several things here:
572c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 1. Compute lambda from the texcoords, if needed
573c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 2. Determine if we're minifying or magnifying
574c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 3. If minifying, choose mipmap levels
575c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 4. Return image filter to use within mipmap images
576dd55083ac1c13723dba6be71f161e2ca7cac7c66Brian * \param level0  Returns first mipmap level to sample from
577dd55083ac1c13723dba6be71f161e2ca7cac7c66Brian * \param level1  Returns second mipmap level to sample from
578dd55083ac1c13723dba6be71f161e2ca7cac7c66Brian * \param levelBlend  Returns blend factor between levels, in [0,1]
579dd55083ac1c13723dba6be71f161e2ca7cac7c66Brian * \param imgFilter  Returns either the min or mag filter, depending on lambda
580f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian */
581f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrianstatic void
5820b9e96fae9493d5d58f046e01c983a3c4267090eBrianchoose_mipmap_levels(const struct pipe_texture *texture,
5830b9e96fae9493d5d58f046e01c983a3c4267090eBrian                     const struct pipe_sampler_state *sampler,
584c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     const float s[QUAD_SIZE],
585c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     const float t[QUAD_SIZE],
586c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     const float p[QUAD_SIZE],
5873ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                     boolean computeLambda,
588c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     float lodbias,
589c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     unsigned *level0, unsigned *level1, float *levelBlend,
590c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     unsigned *imgFilter)
59109a1b912605ff48c8782dcc5aae55ac77e27037bBrian{
5920b9e96fae9493d5d58f046e01c983a3c4267090eBrian   if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) {
593c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      /* no mipmap selection needed */
5940b9e96fae9493d5d58f046e01c983a3c4267090eBrian      *level0 = *level1 = CLAMP((int) sampler->min_lod,
5950b9e96fae9493d5d58f046e01c983a3c4267090eBrian                                0, (int) texture->last_level);
59608c9534107fcaf06f9b801551524ed5dc724db13Brian
5970b9e96fae9493d5d58f046e01c983a3c4267090eBrian      if (sampler->min_img_filter != sampler->mag_img_filter) {
59808c9534107fcaf06f9b801551524ed5dc724db13Brian         /* non-mipmapped texture, but still need to determine if doing
59908c9534107fcaf06f9b801551524ed5dc724db13Brian          * minification or magnification.
60008c9534107fcaf06f9b801551524ed5dc724db13Brian          */
6010b9e96fae9493d5d58f046e01c983a3c4267090eBrian         float lambda = compute_lambda(texture, sampler, s, t, p, lodbias);
6023b2a291888d8e62787de03f8529806fb562bd186Brian         if (lambda <= 0.0) {
6030b9e96fae9493d5d58f046e01c983a3c4267090eBrian            *imgFilter = sampler->mag_img_filter;
60408c9534107fcaf06f9b801551524ed5dc724db13Brian         }
60508c9534107fcaf06f9b801551524ed5dc724db13Brian         else {
6060b9e96fae9493d5d58f046e01c983a3c4267090eBrian            *imgFilter = sampler->min_img_filter;
60708c9534107fcaf06f9b801551524ed5dc724db13Brian         }
60808c9534107fcaf06f9b801551524ed5dc724db13Brian      }
6093b2a291888d8e62787de03f8529806fb562bd186Brian      else {
6100b9e96fae9493d5d58f046e01c983a3c4267090eBrian         *imgFilter = sampler->mag_img_filter;
6113b2a291888d8e62787de03f8529806fb562bd186Brian      }
612c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian   }
613c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian   else {
614c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      float lambda;
615c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian
6163ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul      if (computeLambda)
617c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* fragment shader */
6180b9e96fae9493d5d58f046e01c983a3c4267090eBrian         lambda = compute_lambda(texture, sampler, s, t, p, lodbias);
619c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      else
620c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* vertex shader */
621c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         lambda = lodbias; /* not really a bias, but absolute LOD */
622c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian
6233b2a291888d8e62787de03f8529806fb562bd186Brian      if (lambda <= 0.0) { /* XXX threshold depends on the filter */
624c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* magnifying */
6250b9e96fae9493d5d58f046e01c983a3c4267090eBrian         *imgFilter = sampler->mag_img_filter;
6264da1cdf78fa3b954840650fa46cf72da5daf149fBrian         *level0 = *level1 = 0;
627f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      }
628c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      else {
629c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* minifying */
6300b9e96fae9493d5d58f046e01c983a3c4267090eBrian         *imgFilter = sampler->min_img_filter;
631c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian
632c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* choose mipmap level(s) and compute the blend factor between them */
6330b9e96fae9493d5d58f046e01c983a3c4267090eBrian         if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NEAREST) {
634c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            /* Nearest mipmap level */
635c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            const int lvl = (int) (lambda + 0.5);
636c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            *level0 =
6370b9e96fae9493d5d58f046e01c983a3c4267090eBrian            *level1 = CLAMP(lvl, 0, (int) texture->last_level);
638c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         }
639c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         else {
640c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            /* Linear interpolation between mipmap levels */
641c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            const int lvl = (int) lambda;
6420b9e96fae9493d5d58f046e01c983a3c4267090eBrian            *level0 = CLAMP(lvl,     0, (int) texture->last_level);
6430b9e96fae9493d5d58f046e01c983a3c4267090eBrian            *level1 = CLAMP(lvl + 1, 0, (int) texture->last_level);
644c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            *levelBlend = FRAC(lambda);  /* blending weight between levels */
645c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         }
646f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      }
64709a1b912605ff48c8782dcc5aae55ac77e27037bBrian   }
64809a1b912605ff48c8782dcc5aae55ac77e27037bBrian}
64909a1b912605ff48c8782dcc5aae55ac77e27037bBrian
65008f33a025100dea2d951e6d628891fe294b18082Brian
651b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/**
652a13de2464dd034ff117f9314df5757d068cae8e5Brian * Get a texel from a texture, using the texture tile cache.
653a13de2464dd034ff117f9314df5757d068cae8e5Brian *
654b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param face  the cube face in 0..5
655b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param level  the mipmap level
656b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param x  the x coord of texel within 2D image
657b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param y  the y coord of texel within 2D image
65870eb7996f265f3634dabda078f13d1be3533cc65Brian * \param z  which slice of a 3D texture
659b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param rgba  the quad to put the texel/color into
660b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param j  which element of the rgba quad to write to
66170eb7996f265f3634dabda078f13d1be3533cc65Brian *
66270eb7996f265f3634dabda078f13d1be3533cc65Brian * XXX maybe move this into sp_tile_cache.c and merge with the
66370eb7996f265f3634dabda078f13d1be3533cc65Brian * sp_get_cached_tile_tex() function.  Also, get 4 texels instead of 1...
664b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian */
665b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic void
6666142de393fe34ff0866f8489f1292eb473276f11Keith Whitwellget_texel_quad_2d(const struct tgsi_sampler *tgsi_sampler,
6676142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                  unsigned face, unsigned level, int x, int y,
6686142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                  const float *out[4])
6696142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell{
6706142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
6716142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
6726142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   const struct softpipe_cached_tile *tile
6736142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      = sp_get_cached_tile_tex(samp->cache,
6746142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                               tile_address(x, y, 0, face, level));
6756142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
6766142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   y %= TILE_SIZE;
6776142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   x %= TILE_SIZE;
6786142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
6796142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   out[0] = &tile->data.color[y  ][x  ][0];
6806142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   out[1] = &tile->data.color[y  ][x+1][0];
6816142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   out[2] = &tile->data.color[y+1][x  ][0];
6826142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   out[3] = &tile->data.color[y+1][x+1][0];
6836142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell}
6846142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
6856142de393fe34ff0866f8489f1292eb473276f11Keith Whitwellstatic INLINE const float *
6866142de393fe34ff0866f8489f1292eb473276f11Keith Whitwellget_texel_2d_ptr(const struct tgsi_sampler *tgsi_sampler,
6876142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                 unsigned face, unsigned level, int x, int y)
6886142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell{
6896142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
6906142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
6916142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   const struct softpipe_cached_tile *tile
6926142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      = sp_get_cached_tile_tex(samp->cache,
6936142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                               tile_address(x, y, 0, face, level));
6946142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
6956142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   y %= TILE_SIZE;
6966142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   x %= TILE_SIZE;
6976142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
6986142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   return &tile->data.color[y][x][0];
6996142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell}
7006142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
7016142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
7026142de393fe34ff0866f8489f1292eb473276f11Keith Whitwellstatic void
7036142de393fe34ff0866f8489f1292eb473276f11Keith Whitwellget_texel_quad_2d_mt(const struct tgsi_sampler *tgsi_sampler,
7046142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                     unsigned face, unsigned level,
7056142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                     int x0, int y0,
7066142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                     int x1, int y1,
7076142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                     const float *out[4])
7086142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell{
7096142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   unsigned i;
7106142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
7116142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   for (i = 0; i < 4; i++) {
7126142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      unsigned tx = (i & 1) ? x1 : x0;
7136142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      unsigned ty = (i >> 1) ? y1 : y0;
7146142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
7156142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      out[i] = get_texel_2d_ptr( tgsi_sampler, face, level, tx, ty );
7166142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   }
7176142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell}
7186142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
7196142de393fe34ff0866f8489f1292eb473276f11Keith Whitwellstatic void
720dd55083ac1c13723dba6be71f161e2ca7cac7c66Brianget_texel(const struct tgsi_sampler *tgsi_sampler,
7216142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                 unsigned face, unsigned level, int x, int y, int z,
7226142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                 float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j)
723b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian{
7240b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
725aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell   const struct pipe_texture *texture = samp->texture;
726aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell   const struct pipe_sampler_state *sampler = samp->sampler;
7270b9e96fae9493d5d58f046e01c983a3c4267090eBrian
7280b9e96fae9493d5d58f046e01c983a3c4267090eBrian   if (x < 0 || x >= (int) texture->width[level] ||
7290b9e96fae9493d5d58f046e01c983a3c4267090eBrian       y < 0 || y >= (int) texture->height[level] ||
7300b9e96fae9493d5d58f046e01c983a3c4267090eBrian       z < 0 || z >= (int) texture->depth[level]) {
7310b9e96fae9493d5d58f046e01c983a3c4267090eBrian      rgba[0][j] = sampler->border_color[0];
7320b9e96fae9493d5d58f046e01c983a3c4267090eBrian      rgba[1][j] = sampler->border_color[1];
7330b9e96fae9493d5d58f046e01c983a3c4267090eBrian      rgba[2][j] = sampler->border_color[2];
7340b9e96fae9493d5d58f046e01c983a3c4267090eBrian      rgba[3][j] = sampler->border_color[3];
735ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul   }
736ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul   else {
737f911c3b9897b90132c8621a72bfeb824eb3b01e5Keith Whitwell      const unsigned tx = x % TILE_SIZE;
738f911c3b9897b90132c8621a72bfeb824eb3b01e5Keith Whitwell      const unsigned ty = y % TILE_SIZE;
739f911c3b9897b90132c8621a72bfeb824eb3b01e5Keith Whitwell      const struct softpipe_cached_tile *tile;
740f911c3b9897b90132c8621a72bfeb824eb3b01e5Keith Whitwell
741f911c3b9897b90132c8621a72bfeb824eb3b01e5Keith Whitwell      tile = sp_get_cached_tile_tex(samp->cache,
742f911c3b9897b90132c8621a72bfeb824eb3b01e5Keith Whitwell                                    tile_address(x, y, z, face, level));
743f911c3b9897b90132c8621a72bfeb824eb3b01e5Keith Whitwell
744ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul      rgba[0][j] = tile->data.color[ty][tx][0];
745ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul      rgba[1][j] = tile->data.color[ty][tx][1];
746ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul      rgba[2][j] = tile->data.color[ty][tx][2];
747ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul      rgba[3][j] = tile->data.color[ty][tx][3];
748b1ff7dac537947d412bf423a73e7eacd76f90d84Brian Paul      if (0)
749b1ff7dac537947d412bf423a73e7eacd76f90d84Brian Paul      {
750ae2195caf56d2eb782475254c68858a25ee7c857Brian Paul         debug_printf("Get texel %f %f %f %f from %s\n",
7518fb55dab783f2de5111e7440093e1458fce5fb3dBrian Paul                      rgba[0][j], rgba[1][j], rgba[2][j], rgba[3][j],
7520b9e96fae9493d5d58f046e01c983a3c4267090eBrian                      pf_name(texture->format));
753b1ff7dac537947d412bf423a73e7eacd76f90d84Brian Paul      }
754ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul   }
755b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian}
756b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
757b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
7583d8c05f7320151898dd224c1daaf3118e1f7ea34Brian/**
7593d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * Compare texcoord 'p' (aka R) against texture value 'rgba[0]'
7603d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * When we sampled the depth texture, the depth value was put into all
7613d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * RGBA channels.  We look at the red channel here.
762efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul * \param rgba  quad of (depth) texel values
763efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul * \param p  texture 'P' components for four pixels in quad
764efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul * \param j  which pixel in the quad to test [0..3]
7653d8c05f7320151898dd224c1daaf3118e1f7ea34Brian */
7663d8c05f7320151898dd224c1daaf3118e1f7ea34Brianstatic INLINE void
767005ee9f4e05b487d455e87c6843d1d1a3c1536ffBrian Paulshadow_compare(const struct pipe_sampler_state *sampler,
7683d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               float rgba[NUM_CHANNELS][QUAD_SIZE],
7693d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               const float p[QUAD_SIZE],
7703d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               uint j)
7713d8c05f7320151898dd224c1daaf3118e1f7ea34Brian{
7723d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   int k;
773005ee9f4e05b487d455e87c6843d1d1a3c1536ffBrian Paul   switch (sampler->compare_func) {
7743d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_LESS:
7753d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] < rgba[0][j];
7763d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
7773d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_LEQUAL:
7783d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] <= rgba[0][j];
7793d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
7803d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_GREATER:
7813d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] > rgba[0][j];
7823d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
7833d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_GEQUAL:
7843d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] >= rgba[0][j];
7853d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
7863d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_EQUAL:
7873d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] == rgba[0][j];
7883d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
7893d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_NOTEQUAL:
7903d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] != rgba[0][j];
7913d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
7923d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_ALWAYS:
7933d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = 1;
7943d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
7953d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_NEVER:
7963d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = 0;
7973d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
7983d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   default:
799f9b1d47d652778012fd35552ffc51717ac0b6f79Keith Whitwell      k = 0;
8003d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      assert(0);
801f9b1d47d652778012fd35552ffc51717ac0b6f79Keith Whitwell      break;
8023d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   }
8033d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
804048765624598e6c60b9fe4dc82a72b7110f16715Brian Paul   /* XXX returning result for default GL_DEPTH_TEXTURE_MODE = GL_LUMINANCE */
8053d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   rgba[0][j] = rgba[1][j] = rgba[2][j] = (float) k;
806048765624598e6c60b9fe4dc82a72b7110f16715Brian Paul   rgba[3][j] = 1.0F;
8073d8c05f7320151898dd224c1daaf3118e1f7ea34Brian}
8083d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
809b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
810b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/**
811efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul * As above, but do four z/texture comparisons.
812efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul */
813efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paulstatic INLINE void
814efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paulshadow_compare4(const struct pipe_sampler_state *sampler,
815efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul                float rgba[NUM_CHANNELS][QUAD_SIZE],
816efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul                const float p[QUAD_SIZE])
817efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul{
818efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   int j, k0, k1, k2, k3;
819efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   float val;
820efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul
821efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   /* compare four texcoords vs. four texture samples */
822efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   switch (sampler->compare_func) {
823efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_LESS:
824efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k0 = p[0] < rgba[0][0];
825efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k1 = p[1] < rgba[0][1];
826efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k2 = p[2] < rgba[0][2];
827efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k3 = p[3] < rgba[0][3];
828efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
829efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_LEQUAL:
830efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k0 = p[0] <= rgba[0][0];
831efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k1 = p[1] <= rgba[0][1];
832efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k2 = p[2] <= rgba[0][2];
833efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k3 = p[3] <= rgba[0][3];
834efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
835efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_GREATER:
836efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k0 = p[0] > rgba[0][0];
837efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k1 = p[1] > rgba[0][1];
838efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k2 = p[2] > rgba[0][2];
839efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k3 = p[3] > rgba[0][3];
840efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
841efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_GEQUAL:
842efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k0 = p[0] >= rgba[0][0];
843efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k1 = p[1] >= rgba[0][1];
844efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k2 = p[2] >= rgba[0][2];
845efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k3 = p[3] >= rgba[0][3];
846efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
847efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_EQUAL:
848efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k0 = p[0] == rgba[0][0];
849efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k1 = p[1] == rgba[0][1];
850efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k2 = p[2] == rgba[0][2];
851efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k3 = p[3] == rgba[0][3];
852efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
853efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_NOTEQUAL:
854efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k0 = p[0] != rgba[0][0];
855efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k1 = p[1] != rgba[0][1];
856efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k2 = p[2] != rgba[0][2];
857efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k3 = p[3] != rgba[0][3];
858efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
859efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_ALWAYS:
860efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k0 = k1 = k2 = k3 = 1;
861efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
862efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_NEVER:
863efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k0 = k1 = k2 = k3 = 0;
864efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
865efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   default:
866efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k0 = k1 = k2 = k3 = 0;
867efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      assert(0);
868efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
869efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   }
870efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul
871efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   /* convert four pass/fail values to an intensity in [0,1] */
872efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   val = 0.25F * (k0 + k1 + k2 + k3);
873efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul
874efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   /* XXX returning result for default GL_DEPTH_TEXTURE_MODE = GL_LUMINANCE */
875efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   for (j = 0; j < 4; j++) {
876efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      rgba[0][j] = rgba[1][j] = rgba[2][j] = val;
877efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      rgba[3][j] = 1.0F;
878efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   }
879efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul}
880efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul
881efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul
8826142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
8836142de393fe34ff0866f8489f1292eb473276f11Keith Whitwellstatic void
8846142de393fe34ff0866f8489f1292eb473276f11Keith Whitwellsp_get_samples_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler,
8856142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                                    const float s[QUAD_SIZE],
8866142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                                    const float t[QUAD_SIZE],
8876142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                                    const float p[QUAD_SIZE],
8886142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                                    float lodbias,
8896142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                                    float rgba[NUM_CHANNELS][QUAD_SIZE])
8906142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell{
8916142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
8926142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   unsigned  j;
8936142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   unsigned level = samp->level;
8946142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   unsigned xpot = 1 << (samp->xpot - level);
8956142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   unsigned ypot = 1 << (samp->ypot - level);
8966142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
8976142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   for (j = 0; j < QUAD_SIZE; j++) {
8986142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      int c;
8996142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
9006142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      float u = s[j] * xpot - 0.5F;
9016142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      float v = t[j] * ypot - 0.5F;
9026142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
9036142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      int uflr = util_ifloor(u);
9046142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      int vflr = util_ifloor(v);
9056142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
9066142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      float xw = u - (float)uflr;
9076142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      float yw = v - (float)vflr;
9086142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
9096142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      int x0 = uflr & (xpot - 1);
9106142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      int y0 = vflr & (ypot - 1);
9116142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
9126142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      const float *tx[4];
9136142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
9146142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
9156142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      /* Can we fetch all four at once:
9166142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell       */
9176142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      if (x0 % TILE_SIZE != TILE_SIZE-1 &&
9186142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell          y0 % TILE_SIZE != TILE_SIZE-1)
9196142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      {
9206142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell         get_texel_quad_2d(tgsi_sampler, 0, level, x0, y0, tx);
9216142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      }
9226142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      else
9236142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      {
9246142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell         unsigned x1 = (uflr + 1) & (xpot - 1);
9256142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell         unsigned y1 = (vflr + 1) & (ypot - 1);
9266142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell         get_texel_quad_2d_mt(tgsi_sampler, 0, level,
9276142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                              x0, y0, x1, y1, tx);
9286142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      }
9296142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
9306142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
9316142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      /* interpolate R, G, B, A */
9326142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      for (c = 0; c < 4; c++) {
9336142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell         rgba[c][j] = lerp_2d(xw, yw,
9346142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                              tx[0][c], tx[1][c],
9356142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                              tx[2][c], tx[3][c]);
9366142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      }
9376142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   }
9386142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell}
9396142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
9406142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
9416142de393fe34ff0866f8489f1292eb473276f11Keith Whitwellstatic void
9426142de393fe34ff0866f8489f1292eb473276f11Keith Whitwellsp_get_samples_2d_nearest_repeat_POT(struct tgsi_sampler *tgsi_sampler,
9436142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                                     const float s[QUAD_SIZE],
9446142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                                     const float t[QUAD_SIZE],
9456142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                                     const float p[QUAD_SIZE],
9466142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                                     float lodbias,
9476142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                                     float rgba[NUM_CHANNELS][QUAD_SIZE])
9486142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell{
9496142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
9506142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   unsigned  j;
9516142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   unsigned level = samp->level;
9526142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   unsigned xpot = 1 << (samp->xpot - level);
9536142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   unsigned ypot = 1 << (samp->ypot - level);
9546142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
9556142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   for (j = 0; j < QUAD_SIZE; j++) {
9566142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      int c;
9576142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
9585fdac2dcea09c654725666b3cab5f59dfc9e31a5Keith Whitwell      float u = s[j] * xpot;
9595fdac2dcea09c654725666b3cab5f59dfc9e31a5Keith Whitwell      float v = t[j] * ypot;
9606142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
9616142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      int uflr = util_ifloor(u);
9626142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      int vflr = util_ifloor(v);
9636142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
9646142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      int x0 = uflr & (xpot - 1);
9656142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      int y0 = vflr & (ypot - 1);
9666142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
9676142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      const float *out = get_texel_2d_ptr(tgsi_sampler, 0, level, x0, y0);
9686142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
9696142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      for (c = 0; c < 4; c++) {
9706142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell         rgba[c][j] = out[c];
9716142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      }
9726142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   }
9736142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell}
9746142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
9756142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
9766142de393fe34ff0866f8489f1292eb473276f11Keith Whitwellstatic void
9776142de393fe34ff0866f8489f1292eb473276f11Keith Whitwellsp_get_samples_2d_nearest_clamp_POT(struct tgsi_sampler *tgsi_sampler,
9786142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                                     const float s[QUAD_SIZE],
9796142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                                     const float t[QUAD_SIZE],
9806142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                                     const float p[QUAD_SIZE],
9816142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                                     float lodbias,
9826142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                                     float rgba[NUM_CHANNELS][QUAD_SIZE])
9836142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell{
9846142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
9856142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   unsigned  j;
9866142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   unsigned level = samp->level;
9876142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   unsigned xpot = (1<<samp->xpot);
9886142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   unsigned ypot = (1<<samp->ypot);
9896142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
9906142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   for (j = 0; j < QUAD_SIZE; j++) {
9916142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      int c;
9926142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
9935fdac2dcea09c654725666b3cab5f59dfc9e31a5Keith Whitwell      float u = s[j] * xpot;
9945fdac2dcea09c654725666b3cab5f59dfc9e31a5Keith Whitwell      float v = t[j] * ypot;
9956142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
9966142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      int x0, y0;
9976142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      const float *out;
9986142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
9996142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      x0 = util_ifloor(u);
10006142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      if (x0 < 0)
10016142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell         x0 = 0;
10026142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      else if (x0 > xpot - 1)
10036142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell         x0 = xpot - 1;
10046142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
10056142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      y0 = util_ifloor(v);
10066142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      if (y0 < 0)
10076142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell         y0 = 0;
10086142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      else if (y0 > ypot - 1)
10096142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell         y0 = ypot - 1;
10106142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
10116142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      out = get_texel_2d_ptr(tgsi_sampler, 0, level, x0, y0);
10126142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
10136142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      for (c = 0; c < 4; c++) {
10146142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell         rgba[c][j] = out[c];
10156142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      }
10166142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   }
10176142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell}
10186142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
10196142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
10206142de393fe34ff0866f8489f1292eb473276f11Keith Whitwellstatic void
10216142de393fe34ff0866f8489f1292eb473276f11Keith Whitwellsp_get_samples_2d_linear_mip_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler,
10226142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                                               const float s[QUAD_SIZE],
10236142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                                               const float t[QUAD_SIZE],
10246142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                                               const float p[QUAD_SIZE],
10256142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                                               float lodbias,
10266142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                                               float rgba[NUM_CHANNELS][QUAD_SIZE])
10276142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell{
10286142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
10296142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   const struct pipe_texture *texture = samp->texture;
10306142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   const struct pipe_sampler_state *sampler = samp->sampler;
10316142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   int level0, level1;
10326142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   float lambda;
10336142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
10346142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   lambda = compute_lambda(texture, sampler, s, t, p, lodbias);
10356142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   level0 = (int)lambda;
10366142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   level1 = level0 + 1;
10376142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
10386142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   if (lambda < 0.0) {
10396142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      samp->level = 0;
10406142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      sp_get_samples_2d_linear_repeat_POT( tgsi_sampler,
10416142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                                           s, t, p, lodbias, rgba );
10426142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   }
10436142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   else if (level0 >= texture->last_level) {
10446142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      samp->level = texture->last_level;
10456142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      sp_get_samples_2d_linear_repeat_POT( tgsi_sampler,
10466142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                                           s, t, p, lodbias, rgba );
10476142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   }
10486142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   else {
10496142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      float rgba0[4][4];
10506142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      float rgba1[4][4];
10516142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      int c,j;
10526142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
10536142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      float levelBlend = lambda - level0;  /* blending weight between levels */
10546142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
10556142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      samp->level = level0;
10566142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      sp_get_samples_2d_linear_repeat_POT( tgsi_sampler,
10576142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                                           s, t, p, lodbias, rgba0 );
10586142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
10596142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      samp->level++;
10606142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      sp_get_samples_2d_linear_repeat_POT( tgsi_sampler,
10616142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                                           s, t, p, lodbias, rgba1 );
10626142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
10636142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      for (c = 0; c < 4; c++)
10646142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell         for (j = 0; j < 4; j++)
10656142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell            rgba[c][j] = lerp(levelBlend, rgba0[c][j], rgba1[c][j]);
10666142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell  }
10676142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell}
10686142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
1069efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul/**
1070a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Common code for sampling 1D/2D/cube textures.
1071a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Could probably extend for 3D...
10720dc4eea64f56cc93e5359372b08b99a2d600273cBrian */
1073e12810d92ffb3547680b227bf88937c03018112bBrianstatic void
1074dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler,
1075a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         const float s[QUAD_SIZE],
1076a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         const float t[QUAD_SIZE],
1077a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         const float p[QUAD_SIZE],
10783ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                         boolean computeLambda,
1079a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         float lodbias,
1080a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         float rgba[NUM_CHANNELS][QUAD_SIZE],
1081a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         const unsigned faces[4])
10820dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
10830b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
1084aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell   const struct pipe_texture *texture = samp->texture;
1085aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell   const struct pipe_sampler_state *sampler = samp->sampler;
1086f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian   unsigned level0, level1, j, imgFilter;
1087f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian   int width, height;
1088c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian   float levelBlend;
1089a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
10903ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul   choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias,
1091c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                        &level0, &level1, &levelBlend, &imgFilter);
109209a1b912605ff48c8782dcc5aae55ac77e27037bBrian
10930b9e96fae9493d5d58f046e01c983a3c4267090eBrian   assert(sampler->normalized_coords);
1094b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
10950b9e96fae9493d5d58f046e01c983a3c4267090eBrian   width = texture->width[level0];
10960b9e96fae9493d5d58f046e01c983a3c4267090eBrian   height = texture->height[level0];
109709a1b912605ff48c8782dcc5aae55ac77e27037bBrian
1098b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   assert(width > 0);
1099612cfb749c3526eeb446bbc631bf24716522f373Brian
1100b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   switch (imgFilter) {
11010dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_FILTER_NEAREST:
110238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      {
110338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         int x[4], y[4];
110438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         nearest_texcoord_4(sampler->wrap_s, s, width, x);
110538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         nearest_texcoord_4(sampler->wrap_t, t, height, y);
110638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
110738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (j = 0; j < QUAD_SIZE; j++) {
110838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, faces[j], level0, x[j], y[j], 0, rgba, j);
110938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
1110005ee9f4e05b487d455e87c6843d1d1a3c1536ffBrian Paul               shadow_compare(sampler, rgba, p, j);
11113d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            }
11123d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
111338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (level0 != level1) {
111438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               /* get texels from second mipmap level and blend */
111538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               float rgba2[4][4];
111638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               unsigned c;
111738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               x[j] /= 2;
111838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               y[j] /= 2;
111938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, faces[j], level1, x[j], y[j], 0,
112038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                         rgba2, j);
112138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
1122005ee9f4e05b487d455e87c6843d1d1a3c1536ffBrian Paul                  shadow_compare(sampler, rgba2, p, j);
112338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               }
112438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
112538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               for (c = 0; c < NUM_CHANNELS; c++) {
112638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                  rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]);
112738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               }
1128f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            }
1129f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian         }
11300dc4eea64f56cc93e5359372b08b99a2d600273cBrian      }
11310dc4eea64f56cc93e5359372b08b99a2d600273cBrian      break;
11320dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_FILTER_LINEAR:
113398ae83d5cc73b61826823c915b5c59746c2e85c7Keith Whitwell   case PIPE_TEX_FILTER_ANISO:
113438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      {
113538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         int x0[4], y0[4], x1[4], y1[4];
113638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float xw[4], yw[4]; /* weights */
113738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
113838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         linear_texcoord_4(sampler->wrap_s, s, width, x0, x1, xw);
113938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         linear_texcoord_4(sampler->wrap_t, t, height, y0, y1, yw);
114038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
114138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (j = 0; j < QUAD_SIZE; j++) {
114238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            float tx[4][4]; /* texels */
114338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            int c;
114438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, faces[j], level0, x0[j], y0[j], 0, tx, 0);
114538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, faces[j], level0, x1[j], y0[j], 0, tx, 1);
114638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, faces[j], level0, x0[j], y1[j], 0, tx, 2);
114738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, faces[j], level0, x1[j], y1[j], 0, tx, 3);
114838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
1149efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul               shadow_compare4(sampler, tx, p);
11503d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            }
11513d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
115238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            /* interpolate R, G, B, A */
1153f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            for (c = 0; c < 4; c++) {
115438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               rgba[c][j] = lerp_2d(xw[j], yw[j],
115538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                    tx[c][0], tx[c][1],
115638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                    tx[c][2], tx[c][3]);
1157f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            }
1158f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian
115938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (level0 != level1) {
116038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               /* get texels from second mipmap level and blend */
116138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               float rgba2[4][4];
116238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               x0[j] /= 2;
116338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               y0[j] /= 2;
116438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               x1[j] /= 2;
116538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               y1[j] /= 2;
116638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, faces[j], level1, x0[j], y0[j], 0, tx, 0);
116738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, faces[j], level1, x1[j], y0[j], 0, tx, 1);
116838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, faces[j], level1, x0[j], y1[j], 0, tx, 2);
116938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, faces[j], level1, x1[j], y1[j], 0, tx, 3);
117038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
1171efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul                  shadow_compare4(sampler, tx, p);
117238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               }
117338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
117438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               /* interpolate R, G, B, A */
117538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               for (c = 0; c < 4; c++) {
117638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                  rgba2[c][j] = lerp_2d(xw[j], yw[j],
117738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                        tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
117838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               }
117938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
118038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               for (c = 0; c < NUM_CHANNELS; c++) {
118138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                  rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]);
118238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               }
1183f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            }
1184f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian         }
118509a1b912605ff48c8782dcc5aae55ac77e27037bBrian      }
118609a1b912605ff48c8782dcc5aae55ac77e27037bBrian      break;
11870dc4eea64f56cc93e5359372b08b99a2d600273cBrian   default:
11880dc4eea64f56cc93e5359372b08b99a2d600273cBrian      assert(0);
11890dc4eea64f56cc93e5359372b08b99a2d600273cBrian   }
11900dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
119134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
119234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
1193dd55083ac1c13723dba6be71f161e2ca7cac7c66Brianstatic INLINE void
1194dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_1d(const struct tgsi_sampler *sampler,
1195a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float s[QUAD_SIZE],
1196a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float t[QUAD_SIZE],
1197a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float p[QUAD_SIZE],
11983ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                  boolean computeLambda,
1199a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  float lodbias,
1200a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  float rgba[NUM_CHANNELS][QUAD_SIZE])
1201a34b8594b7b2d00404bb639621ec1ce918ba0786Brian{
1202a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   static const unsigned faces[4] = {0, 0, 0, 0};
1203d16b4bc32a731cb6ae320e8c187af3bc751d4138Brian   static const float tzero[4] = {0, 0, 0, 0};
12043ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul   sp_get_samples_2d_common(sampler, s, tzero, NULL,
12053ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                            computeLambda, lodbias, rgba, faces);
1206a34b8594b7b2d00404bb639621ec1ce918ba0786Brian}
1207a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
1208a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
1209dd55083ac1c13723dba6be71f161e2ca7cac7c66Brianstatic INLINE void
1210dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_2d(const struct tgsi_sampler *sampler,
1211a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float s[QUAD_SIZE],
1212a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float t[QUAD_SIZE],
1213a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float p[QUAD_SIZE],
12143ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                  boolean computeLambda,
1215a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  float lodbias,
1216a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  float rgba[NUM_CHANNELS][QUAD_SIZE])
1217a34b8594b7b2d00404bb639621ec1ce918ba0786Brian{
1218a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   static const unsigned faces[4] = {0, 0, 0, 0};
12193ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul   sp_get_samples_2d_common(sampler, s, t, p,
12203ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                            computeLambda, lodbias, rgba, faces);
1221a34b8594b7b2d00404bb639621ec1ce918ba0786Brian}
1222a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
1223a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
1224dd55083ac1c13723dba6be71f161e2ca7cac7c66Brianstatic INLINE void
1225dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_3d(const struct tgsi_sampler *tgsi_sampler,
1226b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  const float s[QUAD_SIZE],
1227b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  const float t[QUAD_SIZE],
1228b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  const float p[QUAD_SIZE],
12293ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                  boolean computeLambda,
1230f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian                  float lodbias,
1231b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  float rgba[NUM_CHANNELS][QUAD_SIZE])
123234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
12330b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
1234aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell   const struct pipe_texture *texture = samp->texture;
1235aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell   const struct pipe_sampler_state *sampler = samp->sampler;
123634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   /* get/map pipe_surfaces corresponding to 3D tex slices */
12373d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   unsigned level0, level1, j, imgFilter;
12383d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   int width, height, depth;
12393d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   float levelBlend;
12403d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   const uint face = 0;
12413d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
12423ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul   choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias,
12433d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                        &level0, &level1, &levelBlend, &imgFilter);
12443d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
12450b9e96fae9493d5d58f046e01c983a3c4267090eBrian   assert(sampler->normalized_coords);
1246b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
12470b9e96fae9493d5d58f046e01c983a3c4267090eBrian   width = texture->width[level0];
12480b9e96fae9493d5d58f046e01c983a3c4267090eBrian   height = texture->height[level0];
12490b9e96fae9493d5d58f046e01c983a3c4267090eBrian   depth = texture->depth[level0];
12503d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
12513d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   assert(width > 0);
12523d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   assert(height > 0);
12533d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   assert(depth > 0);
12543d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
12553d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   switch (imgFilter) {
12563d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   case PIPE_TEX_FILTER_NEAREST:
125738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      {
125838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         int x[4], y[4], z[4];
125938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         nearest_texcoord_4(sampler->wrap_s, s, width, x);
126038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         nearest_texcoord_4(sampler->wrap_t, t, height, y);
126138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         nearest_texcoord_4(sampler->wrap_r, p, depth, z);
126238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (j = 0; j < QUAD_SIZE; j++) {
126338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x[j], y[j], z[j], rgba, j);
126438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (level0 != level1) {
126538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               /* get texels from second mipmap level and blend */
126638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               float rgba2[4][4];
126738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               unsigned c;
126838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               x[j] /= 2;
126938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               y[j] /= 2;
127038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               z[j] /= 2;
127138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, face, level1, x[j], y[j], z[j], rgba2, j);
127238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               for (c = 0; c < NUM_CHANNELS; c++) {
127338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                  rgba[c][j] = lerp(levelBlend, rgba2[c][j], rgba[c][j]);
127438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               }
12753d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            }
12763d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         }
12773d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      }
12783d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      break;
12793d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   case PIPE_TEX_FILTER_LINEAR:
128098ae83d5cc73b61826823c915b5c59746c2e85c7Keith Whitwell   case PIPE_TEX_FILTER_ANISO:
128138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      {
128238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         int x0[4], x1[4], y0[4], y1[4], z0[4], z1[4];
128338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float xw[4], yw[4], zw[4]; /* interpolation weights */
128438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         linear_texcoord_4(sampler->wrap_s, s, width,  x0, x1, xw);
128538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         linear_texcoord_4(sampler->wrap_t, t, height, y0, y1, yw);
128638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         linear_texcoord_4(sampler->wrap_r, p, depth,  z0, z1, zw);
128738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
128838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (j = 0; j < QUAD_SIZE; j++) {
128938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            int c;
129038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            float tx0[4][4], tx1[4][4];
129138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x0[j], y0[j], z0[j], tx0, 0);
129238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x1[j], y0[j], z0[j], tx0, 1);
129338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x0[j], y1[j], z0[j], tx0, 2);
129438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x1[j], y1[j], z0[j], tx0, 3);
129538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x0[j], y0[j], z1[j], tx1, 0);
129638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x1[j], y0[j], z1[j], tx1, 1);
129738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x0[j], y1[j], z1[j], tx1, 2);
129838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x1[j], y1[j], z1[j], tx1, 3);
129938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
130038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            /* interpolate R, G, B, A */
13013d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            for (c = 0; c < 4; c++) {
130238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               rgba[c][j] = lerp_3d(xw[j], yw[j], zw[j],
130338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                    tx0[c][0], tx0[c][1],
130438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                    tx0[c][2], tx0[c][3],
130538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                    tx1[c][0], tx1[c][1],
130638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                    tx1[c][2], tx1[c][3]);
13073d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            }
13083d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
130938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (level0 != level1) {
131038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               /* get texels from second mipmap level and blend */
131138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               float rgba2[4][4];
131238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               x0[j] /= 2;
131338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               y0[j] /= 2;
131438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               z0[j] /= 2;
131538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               x1[j] /= 2;
131638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               y1[j] /= 2;
131738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               z1[j] /= 2;
131838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, face, level1, x0[j], y0[j], z0[j], tx0, 0);
131938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, face, level1, x1[j], y0[j], z0[j], tx0, 1);
132038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, face, level1, x0[j], y1[j], z0[j], tx0, 2);
132138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, face, level1, x1[j], y1[j], z0[j], tx0, 3);
132238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, face, level1, x0[j], y0[j], z1[j], tx1, 0);
132338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, face, level1, x1[j], y0[j], z1[j], tx1, 1);
132438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, face, level1, x0[j], y1[j], z1[j], tx1, 2);
132538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, face, level1, x1[j], y1[j], z1[j], tx1, 3);
132638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
132738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               /* interpolate R, G, B, A */
132838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               for (c = 0; c < 4; c++) {
132938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                  rgba2[c][j] = lerp_3d(xw[j], yw[j], zw[j],
133038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                        tx0[c][0], tx0[c][1],
133138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                        tx0[c][2], tx0[c][3],
133238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                        tx1[c][0], tx1[c][1],
133338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                        tx1[c][2], tx1[c][3]);
133438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               }
133538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
133638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               /* blend mipmap levels */
133738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               for (c = 0; c < NUM_CHANNELS; c++) {
133838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                  rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]);
133938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               }
13403d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            }
13413d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         }
13423d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      }
13433d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      break;
13443d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   default:
13453d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      assert(0);
13463d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   }
134734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
134834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
134934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
135034a48abd5ff82ce9748fc29191e35a0985d47c5fBrianstatic void
1351dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_cube(const struct tgsi_sampler *sampler,
1352b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                    const float s[QUAD_SIZE],
1353b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                    const float t[QUAD_SIZE],
1354b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                    const float p[QUAD_SIZE],
13553ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                    boolean computeLambda,
1356f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian                    float lodbias,
1357b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                    float rgba[NUM_CHANNELS][QUAD_SIZE])
135834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
1359a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   unsigned faces[QUAD_SIZE], j;
1360a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   float ssss[4], tttt[4];
1361b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   for (j = 0; j < QUAD_SIZE; j++) {
1362a34b8594b7b2d00404bb639621ec1ce918ba0786Brian      faces[j] = choose_cube_face(s[j], t[j], p[j], ssss + j, tttt + j);
1363b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
13643ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul   sp_get_samples_2d_common(sampler, ssss, tttt, NULL,
13653ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                            computeLambda, lodbias, rgba, faces);
136634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
136734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
136834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
1369b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrianstatic void
1370dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler,
1371b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                    const float s[QUAD_SIZE],
1372b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                    const float t[QUAD_SIZE],
1373b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                    const float p[QUAD_SIZE],
13743ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                    boolean computeLambda,
1375b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                    float lodbias,
1376b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                    float rgba[NUM_CHANNELS][QUAD_SIZE])
1377b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{
13780b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
1379aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell   const struct pipe_texture *texture = samp->texture;
1380aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell   const struct pipe_sampler_state *sampler = samp->sampler;
138136b941cdbf83bc23c95598baf7638def1632db01Brian   const uint face = 0;
1382b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   unsigned level0, level1, j, imgFilter;
1383b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   int width, height;
1384b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   float levelBlend;
1385b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
13863ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul   choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias,
1387b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                        &level0, &level1, &levelBlend, &imgFilter);
1388b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
1389b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   /* texture RECTS cannot be mipmapped */
1390b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   assert(level0 == level1);
1391b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
13920b9e96fae9493d5d58f046e01c983a3c4267090eBrian   width = texture->width[level0];
13930b9e96fae9493d5d58f046e01c983a3c4267090eBrian   height = texture->height[level0];
1394b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
1395b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   assert(width > 0);
1396b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
1397b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   switch (imgFilter) {
1398b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_FILTER_NEAREST:
139938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      {
140038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         int x[4], y[4];
140138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         nearest_texcoord_unnorm_4(sampler->wrap_s, s, width, x);
140238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         nearest_texcoord_unnorm_4(sampler->wrap_t, t, height, y);
140338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (j = 0; j < QUAD_SIZE; j++) {
140438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x[j], y[j], 0, rgba, j);
140538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
1406005ee9f4e05b487d455e87c6843d1d1a3c1536ffBrian Paul               shadow_compare(sampler, rgba, p, j);
140738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            }
1408b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         }
1409b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      }
1410b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      break;
1411b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_FILTER_LINEAR:
141298ae83d5cc73b61826823c915b5c59746c2e85c7Keith Whitwell   case PIPE_TEX_FILTER_ANISO:
141338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      {
141438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         int x0[4], y0[4], x1[4], y1[4];
141538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float xw[4], yw[4]; /* weights */
141638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         linear_texcoord_unnorm_4(sampler->wrap_s, s, width,  x0, x1, xw);
141738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         linear_texcoord_unnorm_4(sampler->wrap_t, t, height, y0, y1, yw);
141838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (j = 0; j < QUAD_SIZE; j++) {
141938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            float tx[4][4]; /* texels */
142038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            int c;
142138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x0[j], y0[j], 0, tx, 0);
142238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x1[j], y0[j], 0, tx, 1);
142338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x0[j], y1[j], 0, tx, 2);
142438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x1[j], y1[j], 0, tx, 3);
142538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
1426efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul               shadow_compare4(sampler, tx, p);
142738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            }
142838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            for (c = 0; c < 4; c++) {
142938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               rgba[c][j] = lerp_2d(xw[j], yw[j],
143038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                    tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
143138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            }
1432b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         }
1433b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      }
1434b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      break;
1435b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   default:
1436b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      assert(0);
1437b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   }
1438b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian}
1439b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
1440b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
1441a34b8594b7b2d00404bb639621ec1ce918ba0786Brian/**
14423ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul * Common code for vertex/fragment program texture sampling.
1443a34b8594b7b2d00404bb639621ec1ce918ba0786Brian */
14443ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paulstatic INLINE void
14450b9e96fae9493d5d58f046e01c983a3c4267090eBriansp_get_samples(struct tgsi_sampler *tgsi_sampler,
1446b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float s[QUAD_SIZE],
1447b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float t[QUAD_SIZE],
1448b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float p[QUAD_SIZE],
14493ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul               boolean computeLambda,
1450f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian               float lodbias,
1451b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               float rgba[NUM_CHANNELS][QUAD_SIZE])
145234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
14530b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
1454aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell   const struct pipe_texture *texture = samp->texture;
1455aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell   const struct pipe_sampler_state *sampler = samp->sampler;
14560b9e96fae9493d5d58f046e01c983a3c4267090eBrian
14570b9e96fae9493d5d58f046e01c983a3c4267090eBrian   if (!texture)
14584f23468bd0d14b8ed687a641003d587b91ad39a7Brian      return;
14594f23468bd0d14b8ed687a641003d587b91ad39a7Brian
14600b9e96fae9493d5d58f046e01c983a3c4267090eBrian   switch (texture->target) {
146170af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   case PIPE_TEXTURE_1D:
14620b9e96fae9493d5d58f046e01c983a3c4267090eBrian      assert(sampler->normalized_coords);
14633ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul      sp_get_samples_1d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
146434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
146570af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   case PIPE_TEXTURE_2D:
14660b9e96fae9493d5d58f046e01c983a3c4267090eBrian      if (sampler->normalized_coords)
14673ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul         sp_get_samples_2d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
1468b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      else
14693ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul         sp_get_samples_rect(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
147034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
147170af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   case PIPE_TEXTURE_3D:
14720b9e96fae9493d5d58f046e01c983a3c4267090eBrian      assert(sampler->normalized_coords);
14733ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul      sp_get_samples_3d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
147434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
147570af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   case PIPE_TEXTURE_CUBE:
14760b9e96fae9493d5d58f046e01c983a3c4267090eBrian      assert(sampler->normalized_coords);
14773ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul      sp_get_samples_cube(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
147834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
147934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   default:
148034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      assert(0);
148134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
14823d53d38d5e35386de4793162b9dd32e171927059Brian Paul
14833d53d38d5e35386de4793162b9dd32e171927059Brian Paul#if 0 /* DEBUG */
14843d53d38d5e35386de4793162b9dd32e171927059Brian Paul   {
14853d53d38d5e35386de4793162b9dd32e171927059Brian Paul      int i;
14863d53d38d5e35386de4793162b9dd32e171927059Brian Paul      printf("Sampled at %f, %f, %f:\n", s[0], t[0], p[0]);
14873d53d38d5e35386de4793162b9dd32e171927059Brian Paul      for (i = 0; i < 4; i++) {
14883d53d38d5e35386de4793162b9dd32e171927059Brian Paul         printf("Frag %d: %f %f %f %f\n", i,
14893d53d38d5e35386de4793162b9dd32e171927059Brian Paul                rgba[0][i],
14903d53d38d5e35386de4793162b9dd32e171927059Brian Paul                rgba[1][i],
14913d53d38d5e35386de4793162b9dd32e171927059Brian Paul                rgba[2][i],
14923d53d38d5e35386de4793162b9dd32e171927059Brian Paul                rgba[3][i]);
14933d53d38d5e35386de4793162b9dd32e171927059Brian Paul      }
14943d53d38d5e35386de4793162b9dd32e171927059Brian Paul   }
14953d53d38d5e35386de4793162b9dd32e171927059Brian Paul#endif
149634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
149734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
14986142de393fe34ff0866f8489f1292eb473276f11Keith Whitwellstatic void
14996142de393fe34ff0866f8489f1292eb473276f11Keith Whitwellsp_get_samples_fallback(struct tgsi_sampler *tgsi_sampler,
15006142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                        const float s[QUAD_SIZE],
15016142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                        const float t[QUAD_SIZE],
15026142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                        const float p[QUAD_SIZE],
15036142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                        float lodbias,
15046142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                        float rgba[NUM_CHANNELS][QUAD_SIZE])
15056142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell{
15066142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   sp_get_samples(tgsi_sampler, s, t, p, TRUE, lodbias, rgba);
15076142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell}
15083ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul
15093ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul/**
15103ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul * Called via tgsi_sampler::get_samples() when running a fragment shader.
15113ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul * Get four filtered RGBA values from the sampler's texture.
15123ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul */
15133ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paulvoid
15143ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paulsp_get_samples_fragment(struct tgsi_sampler *tgsi_sampler,
15153ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                        const float s[QUAD_SIZE],
15163ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                        const float t[QUAD_SIZE],
15173ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                        const float p[QUAD_SIZE],
15183ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                        float lodbias,
15193ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                        float rgba[NUM_CHANNELS][QUAD_SIZE])
15203ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul{
15216142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
15226142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   const struct pipe_texture *texture = samp->texture;
15236142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   const struct pipe_sampler_state *sampler = samp->sampler;
15246142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
15256142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   tgsi_sampler->get_samples = sp_get_samples_fallback;
15266142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
15276142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   /* Try to hook in a faster sampler.  Ultimately we'll have to
15286142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell    * code-generate these.  Luckily most of this looks like it is
15296142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell    * orthogonal state within the sampler.
15306142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell    */
15316142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   if (texture->target == PIPE_TEXTURE_2D &&
15326142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell       sampler->min_img_filter == sampler->mag_img_filter &&
15336142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell       sampler->wrap_s == sampler->wrap_t &&
15346142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell       sampler->compare_mode == FALSE &&
15356142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell       sampler->normalized_coords)
15366142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   {
15376142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      samp->xpot = util_unsigned_logbase2( samp->texture->width[0] );
15386142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      samp->ypot = util_unsigned_logbase2( samp->texture->height[0] );
15396142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
15406142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) {
15416142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell         samp->level = CLAMP((int) sampler->min_lod,
15426142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                             0, (int) texture->last_level);
15436142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
15446142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell         if (sampler->wrap_s == PIPE_TEX_WRAP_REPEAT) {
15456142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell            switch (sampler->min_img_filter) {
15466142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell            case PIPE_TEX_FILTER_NEAREST:
15476142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell               tgsi_sampler->get_samples = sp_get_samples_2d_nearest_repeat_POT;
15486142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell               break;
15496142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell            case PIPE_TEX_FILTER_LINEAR:
15506142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell               tgsi_sampler->get_samples = sp_get_samples_2d_linear_repeat_POT;
15516142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell               break;
15526142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell            default:
15536142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell               break;
15546142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell            }
15556142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell         }
15566142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell         else if (sampler->wrap_s == PIPE_TEX_WRAP_CLAMP) {
15576142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell            switch (sampler->min_img_filter) {
15586142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell            case PIPE_TEX_FILTER_NEAREST:
15596142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell               tgsi_sampler->get_samples = sp_get_samples_2d_nearest_clamp_POT;
15606142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell               break;
15616142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell            default:
15626142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell               break;
15636142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell            }
15646142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell         }
15656142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      }
15666142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      else if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
15676142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell         if (sampler->wrap_s == PIPE_TEX_WRAP_REPEAT) {
15686142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell            switch (sampler->min_img_filter) {
15696142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell            case PIPE_TEX_FILTER_LINEAR:
15706142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell               /* This one not working yet:
15716142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                */
15726142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell               if (0)
15736142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                  tgsi_sampler->get_samples = sp_get_samples_2d_linear_mip_linear_repeat_POT;
15746142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell               break;
15756142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell            default:
15766142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell               break;
15776142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell            }
15786142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell         }
15796142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      }
15806142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   }
15816142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   else if (0) {
15826142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      _debug_printf("target %d/%d min_mip %d/%d min_img %d/%d wrap %d/%d compare %d/%d norm %d/%d\n",
15836142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                    texture->target, PIPE_TEXTURE_2D,
15846142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                    sampler->min_mip_filter, PIPE_TEX_MIPFILTER_NONE,
15856142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                    sampler->min_img_filter, sampler->mag_img_filter,
15866142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                    sampler->wrap_s, sampler->wrap_t,
15876142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                    sampler->compare_mode, FALSE,
15886142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell                    sampler->normalized_coords, TRUE);
15896142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   }
15906142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
15916142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   tgsi_sampler->get_samples( tgsi_sampler, s, t, p, lodbias, rgba );
15923ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul}
15933ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul
15943ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul
15953ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul/**
15963ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul * Called via tgsi_sampler::get_samples() when running a vertex shader.
15973ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul * Get four filtered RGBA values from the sampler's texture.
15983ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul */
15993ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paulvoid
16003ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paulsp_get_samples_vertex(struct tgsi_sampler *tgsi_sampler,
16013ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                      const float s[QUAD_SIZE],
16023ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                      const float t[QUAD_SIZE],
16033ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                      const float p[QUAD_SIZE],
16043ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                      float lodbias,
16053ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                      float rgba[NUM_CHANNELS][QUAD_SIZE])
16063ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul{
16073ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul   sp_get_samples(tgsi_sampler, s, t, p, FALSE, lodbias, rgba);
16083ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul}
1609