sp_tex_sample.c revision 38bee46e83b18ff4ad42d340b507b1a15b4326c7
10dc4eea64f56cc93e5359372b08b99a2d600273cBrian/**************************************************************************
20dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
30dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
40dc4eea64f56cc93e5359372b08b99a2d600273cBrian * All Rights Reserved.
50dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
60dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Permission is hereby granted, free of charge, to any person obtaining a
70dc4eea64f56cc93e5359372b08b99a2d600273cBrian * copy of this software and associated documentation files (the
80dc4eea64f56cc93e5359372b08b99a2d600273cBrian * "Software"), to deal in the Software without restriction, including
90dc4eea64f56cc93e5359372b08b99a2d600273cBrian * without limitation the rights to use, copy, modify, merge, publish,
100dc4eea64f56cc93e5359372b08b99a2d600273cBrian * distribute, sub license, and/or sell copies of the Software, and to
110dc4eea64f56cc93e5359372b08b99a2d600273cBrian * permit persons to whom the Software is furnished to do so, subject to
120dc4eea64f56cc93e5359372b08b99a2d600273cBrian * the following conditions:
130dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
140dc4eea64f56cc93e5359372b08b99a2d600273cBrian * The above copyright notice and this permission notice (including the
150dc4eea64f56cc93e5359372b08b99a2d600273cBrian * next paragraph) shall be included in all copies or substantial portions
160dc4eea64f56cc93e5359372b08b99a2d600273cBrian * of the Software.
170dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
180dc4eea64f56cc93e5359372b08b99a2d600273cBrian * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
190dc4eea64f56cc93e5359372b08b99a2d600273cBrian * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
200dc4eea64f56cc93e5359372b08b99a2d600273cBrian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
210dc4eea64f56cc93e5359372b08b99a2d600273cBrian * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
220dc4eea64f56cc93e5359372b08b99a2d600273cBrian * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
230dc4eea64f56cc93e5359372b08b99a2d600273cBrian * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
240dc4eea64f56cc93e5359372b08b99a2d600273cBrian * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
250dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
260dc4eea64f56cc93e5359372b08b99a2d600273cBrian **************************************************************************/
270dc4eea64f56cc93e5359372b08b99a2d600273cBrian
280dc4eea64f56cc93e5359372b08b99a2d600273cBrian/**
290dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Texture sampling
300dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
310dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Authors:
320dc4eea64f56cc93e5359372b08b99a2d600273cBrian *   Brian Paul
330dc4eea64f56cc93e5359372b08b99a2d600273cBrian */
340dc4eea64f56cc93e5359372b08b99a2d600273cBrian
3508f33a025100dea2d951e6d628891fe294b18082Brian#include "sp_context.h"
36b91de8a6e7d74d38698b6dad9f34040e484e69afBrian#include "sp_headers.h"
370dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "sp_surface.h"
380b9e96fae9493d5d58f046e01c983a3c4267090eBrian#include "sp_texture.h"
390dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "sp_tex_sample.h"
4070eb7996f265f3634dabda078f13d1be3533cc65Brian#include "sp_tile_cache.h"
410dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "pipe/p_context.h"
420dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "pipe/p_defines.h"
43c208a2c791fa24c7c5887fc496738cbddbfafc72José Fonseca#include "tgsi/tgsi_exec.h"
441a46dcc8a927dfb38ca1381e7b3dafb789f8257cBrian Paul#include "util/u_math.h"
454f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h"
460dc4eea64f56cc93e5359372b08b99a2d600273cBrian
470dc4eea64f56cc93e5359372b08b99a2d600273cBrian
4808f33a025100dea2d951e6d628891fe294b18082Brian/*
4908f33a025100dea2d951e6d628891fe294b18082Brian * Note, the FRAC macro has to work perfectly.  Otherwise you'll sometimes
5008f33a025100dea2d951e6d628891fe294b18082Brian * see 1-pixel bands of improperly weighted linear-filtered textures.
5108f33a025100dea2d951e6d628891fe294b18082Brian * The tests/texwrap.c demo is a good test.
5208f33a025100dea2d951e6d628891fe294b18082Brian * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0.
5308f33a025100dea2d951e6d628891fe294b18082Brian * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x).
5408f33a025100dea2d951e6d628891fe294b18082Brian */
559935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul#define FRAC(f)  ((f) - util_ifloor(f))
5608f33a025100dea2d951e6d628891fe294b18082Brian
5708f33a025100dea2d951e6d628891fe294b18082Brian
5808f33a025100dea2d951e6d628891fe294b18082Brian/**
5908f33a025100dea2d951e6d628891fe294b18082Brian * Linear interpolation macro
6008f33a025100dea2d951e6d628891fe294b18082Brian */
6138bee46e83b18ff4ad42d340b507b1a15b4326c7Brianstatic INLINE float
6238bee46e83b18ff4ad42d340b507b1a15b4326c7Brianlerp(float a, float v0, float v1)
6338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian{
6438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   return v0 + a * (v1 - v0);
6538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian}
660dc4eea64f56cc93e5359372b08b99a2d600273cBrian
670dc4eea64f56cc93e5359372b08b99a2d600273cBrian
680dc4eea64f56cc93e5359372b08b99a2d600273cBrian/**
690dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Do 2D/biliner interpolation of float values.
700dc4eea64f56cc93e5359372b08b99a2d600273cBrian * v00, v10, v01 and v11 are typically four texture samples in a square/box.
710dc4eea64f56cc93e5359372b08b99a2d600273cBrian * a and b are the horizontal and vertical interpolants.
720dc4eea64f56cc93e5359372b08b99a2d600273cBrian * It's important that this function is inlined when compiled with
730dc4eea64f56cc93e5359372b08b99a2d600273cBrian * optimization!  If we find that's not true on some systems, convert
740dc4eea64f56cc93e5359372b08b99a2d600273cBrian * to a macro.
750dc4eea64f56cc93e5359372b08b99a2d600273cBrian */
76b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic INLINE float
77b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianlerp_2d(float a, float b,
78b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian        float v00, float v10, float v01, float v11)
790dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
8038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   const float temp0 = lerp(a, v00, v10);
8138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   const float temp1 = lerp(a, v01, v11);
8238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   return lerp(b, temp0, temp1);
8338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian}
8438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
8538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
8638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian/**
8738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * As above, but 3D interpolation of 8 values.
8838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian */
8938bee46e83b18ff4ad42d340b507b1a15b4326c7Brianstatic INLINE float
9038bee46e83b18ff4ad42d340b507b1a15b4326c7Brianlerp_3d(float a, float b, float c,
9138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian        float v000, float v100, float v010, float v110,
9238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian        float v001, float v101, float v011, float v111)
9338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian{
9438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   const float temp0 = lerp_2d(a, b, v000, v100, v010, v110);
9538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   const float temp1 = lerp_2d(a, b, v001, v101, v011, v111);
9638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   return lerp(c, temp0, temp1);
970dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
980dc4eea64f56cc93e5359372b08b99a2d600273cBrian
990dc4eea64f56cc93e5359372b08b99a2d600273cBrian
10038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
1010dc4eea64f56cc93e5359372b08b99a2d600273cBrian/**
102906768316d9521a32d9a7eebc9edaf76c06a98a7Brian * If A is a signed integer, A % B doesn't give the right value for A < 0
103906768316d9521a32d9a7eebc9edaf76c06a98a7Brian * (in terms of texture repeat).  Just casting to unsigned fixes that.
1040dc4eea64f56cc93e5359372b08b99a2d600273cBrian */
105906768316d9521a32d9a7eebc9edaf76c06a98a7Brian#define REMAINDER(A, B) ((unsigned) (A) % (unsigned) (B))
10608f33a025100dea2d951e6d628891fe294b18082Brian
10708f33a025100dea2d951e6d628891fe294b18082Brian
10808f33a025100dea2d951e6d628891fe294b18082Brian/**
10938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * Apply texture coord wrapping mode and return integer texture indexes
11038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * for a vector of four texcoords (S or T or P).
11108f33a025100dea2d951e6d628891fe294b18082Brian * \param wrapMode  PIPE_TEX_WRAP_x
11238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param s  the incoming texcoords
11308f33a025100dea2d951e6d628891fe294b18082Brian * \param size  the texture image size
11438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param icoord  returns the integer texcoords
11508f33a025100dea2d951e6d628891fe294b18082Brian * \return  integer texture index
11608f33a025100dea2d951e6d628891fe294b18082Brian */
11738bee46e83b18ff4ad42d340b507b1a15b4326c7Brianstatic INLINE void
11838bee46e83b18ff4ad42d340b507b1a15b4326c7Briannearest_texcoord_4(unsigned wrapMode, const float s[4], unsigned size,
11938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                   int icoord[4])
1200dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
12138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   uint ch;
1220dc4eea64f56cc93e5359372b08b99a2d600273cBrian   switch (wrapMode) {
1230dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_WRAP_REPEAT:
12408f33a025100dea2d951e6d628891fe294b18082Brian      /* s limited to [0,1) */
12508f33a025100dea2d951e6d628891fe294b18082Brian      /* i limited to [0,size-1] */
12638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
12738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         int i = util_ifloor(s[ch] * size);
12838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord[ch] = REMAINDER(i, size);
12938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
13038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
1310dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_WRAP_CLAMP:
13208f33a025100dea2d951e6d628891fe294b18082Brian      /* s limited to [0,1] */
13308f33a025100dea2d951e6d628891fe294b18082Brian      /* i limited to [0,size-1] */
13438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
13538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (s[ch] <= 0.0F)
13638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord[ch] = 0;
13738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         else if (s[ch] >= 1.0F)
13838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord[ch] = size - 1;
13938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         else
14038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord[ch] = util_ifloor(s[ch] * size);
14138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
14238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
14308f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
14408f33a025100dea2d951e6d628891fe294b18082Brian      {
14508f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [min,max] */
14608f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [0, size-1] */
147b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = 1.0F / (2.0F * size);
148b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
14938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (ch = 0; ch < 4; ch++) {
15038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (s[ch] < min)
15138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = 0;
15238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else if (s[ch] > max)
15338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = size - 1;
15438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else
15538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = util_ifloor(s[ch] * size);
15638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         }
15708f33a025100dea2d951e6d628891fe294b18082Brian      }
15838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
15908f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
16008f33a025100dea2d951e6d628891fe294b18082Brian      {
16108f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [min,max] */
16208f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [-1, size] */
163b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = -1.0F / (2.0F * size);
164b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
16538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (ch = 0; ch < 4; ch++) {
16638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (s[ch] <= min)
16738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = -1;
16838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else if (s[ch] >= max)
16938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = size;
17038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else
17138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = util_ifloor(s[ch] * size);
17238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         }
17308f33a025100dea2d951e6d628891fe294b18082Brian      }
17438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
17508f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_REPEAT:
17608f33a025100dea2d951e6d628891fe294b18082Brian      {
177b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = 1.0F / (2.0F * size);
178b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
17938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (ch = 0; ch < 4; ch++) {
18038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            const int flr = util_ifloor(s[ch]);
18138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            float u;
18238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (flr & 1)
18338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               u = 1.0F - (s[ch] - (float) flr);
18438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else
18538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               u = s[ch] - (float) flr;
18638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (u < min)
18738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = 0;
18838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else if (u > max)
18938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = size - 1;
19038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else
19138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = util_ifloor(u * size);
19238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         }
19308f33a025100dea2d951e6d628891fe294b18082Brian      }
19438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
19508f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP:
19638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
19708f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [0,1] */
19808f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [0,size-1] */
19938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         const float u = fabsf(s[ch]);
20008f33a025100dea2d951e6d628891fe294b18082Brian         if (u <= 0.0F)
20138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord[ch] = 0;
20208f33a025100dea2d951e6d628891fe294b18082Brian         else if (u >= 1.0F)
20338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord[ch] = size - 1;
20408f33a025100dea2d951e6d628891fe294b18082Brian         else
20538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord[ch] = util_ifloor(u * size);
20608f33a025100dea2d951e6d628891fe294b18082Brian      }
20738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
20808f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
20908f33a025100dea2d951e6d628891fe294b18082Brian      {
21008f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [min,max] */
21108f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [0, size-1] */
212b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = 1.0F / (2.0F * size);
213b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
21438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (ch = 0; ch < 4; ch++) {
21538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            const float u = fabsf(s[ch]);
21638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (u < min)
21738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = 0;
21838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else if (u > max)
21938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = size - 1;
22038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else
22138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = util_ifloor(u * size);
22238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         }
22308f33a025100dea2d951e6d628891fe294b18082Brian      }
22438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
22508f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
22608f33a025100dea2d951e6d628891fe294b18082Brian      {
22708f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [min,max] */
22808f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [0, size-1] */
229b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = -1.0F / (2.0F * size);
230b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
23138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (ch = 0; ch < 4; ch++) {
23238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            const float u = fabsf(s[ch]);
23338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (u < min)
23438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = -1;
23538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else if (u > max)
23638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = size;
23738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else
23838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = util_ifloor(u * size);
23938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         }
24008f33a025100dea2d951e6d628891fe294b18082Brian      }
24138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
2420dc4eea64f56cc93e5359372b08b99a2d600273cBrian   default:
2430dc4eea64f56cc93e5359372b08b99a2d600273cBrian      assert(0);
2440dc4eea64f56cc93e5359372b08b99a2d600273cBrian   }
2450dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
2460dc4eea64f56cc93e5359372b08b99a2d600273cBrian
24708f33a025100dea2d951e6d628891fe294b18082Brian
24808f33a025100dea2d951e6d628891fe294b18082Brian/**
24938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * Used to compute texel locations for linear sampling for four texcoords.
25008f33a025100dea2d951e6d628891fe294b18082Brian * \param wrapMode  PIPE_TEX_WRAP_x
25138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param s  the texcoords
25208f33a025100dea2d951e6d628891fe294b18082Brian * \param size  the texture image size
25338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param icoord0  returns first texture indexes
25438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param icoord1  returns second texture indexes (usually icoord0 + 1)
25538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param w  returns blend factor/weight between texture indexes
25638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param icoord  returns the computed integer texture coords
25708f33a025100dea2d951e6d628891fe294b18082Brian */
2580dc4eea64f56cc93e5359372b08b99a2d600273cBrianstatic INLINE void
25938bee46e83b18ff4ad42d340b507b1a15b4326c7Brianlinear_texcoord_4(unsigned wrapMode, const float s[4], unsigned size,
26038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                  int icoord0[4], int icoord1[4], float w[4])
2610dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
26238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   uint ch;
26338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
2640dc4eea64f56cc93e5359372b08b99a2d600273cBrian   switch (wrapMode) {
2650dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_WRAP_REPEAT:
26638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
26738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float u = s[ch] * size - 0.5F;
26838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord0[ch] = REMAINDER(util_ifloor(u), size);
26938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord1[ch] = REMAINDER(icoord0[ch] + 1, size);
27038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         w[ch] = FRAC(u);
27138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
27238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      break;;
2730dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_WRAP_CLAMP:
27438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
27538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float u = CLAMP(s[ch], 0.0F, 1.0F);
27638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         u = u * size - 0.5f;
27738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord0[ch] = util_ifloor(u);
27838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord1[ch] = icoord0[ch] + 1;
27938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         w[ch] = FRAC(u);
28038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
28138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      break;;
28208f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
28338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
28438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float u = CLAMP(s[ch], 0.0F, 1.0F);
28538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         u = u * size - 0.5f;
28638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord0[ch] = util_ifloor(u);
28738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord1[ch] = icoord0[ch] + 1;
28838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (icoord0[ch] < 0)
28938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord0[ch] = 0;
29038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (icoord1[ch] >= (int) size)
29138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord1[ch] = size - 1;
29238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         w[ch] = FRAC(u);
29338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
29438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      break;;
29508f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
29608f33a025100dea2d951e6d628891fe294b18082Brian      {
297b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = -1.0F / (2.0F * size);
298b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
29938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (ch = 0; ch < 4; ch++) {
30038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            float u = CLAMP(s[ch], min, max);
30138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            u = u * size - 0.5f;
30238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord0[ch] = util_ifloor(u);
30338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord1[ch] = icoord0[ch] + 1;
30438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            w[ch] = FRAC(u);
30538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         }
30608f33a025100dea2d951e6d628891fe294b18082Brian      }
30738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      break;;
30808f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_REPEAT:
30938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
31038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         const int flr = util_ifloor(s[ch]);
31138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float u;
31208f33a025100dea2d951e6d628891fe294b18082Brian         if (flr & 1)
31338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            u = 1.0F - (s[ch] - (float) flr);
31408f33a025100dea2d951e6d628891fe294b18082Brian         else
31538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            u = s[ch] - (float) flr;
31638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         u = u * size - 0.5F;
31738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord0[ch] = util_ifloor(u);
31838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord1[ch] = icoord0[ch] + 1;
31938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (icoord0[ch] < 0)
32038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord0[ch] = 0;
32138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (icoord1[ch] >= (int) size)
32238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord1[ch] = size - 1;
32338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         w[ch] = FRAC(u);
32408f33a025100dea2d951e6d628891fe294b18082Brian      }
32538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      break;;
32608f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP:
32738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
32838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float u = fabsf(s[ch]);
32938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (u >= 1.0F)
33038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            u = (float) size;
33138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         else
33238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            u *= size;
33338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         u -= 0.5F;
33438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord0[ch] = util_ifloor(u);
33538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord1[ch] = icoord0[ch] + 1;
33638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         w[ch] = FRAC(u);
33738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
33838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      break;;
33908f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
34038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
34138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float u = fabsf(s[ch]);
34238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (u >= 1.0F)
34338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            u = (float) size;
34438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         else
34538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            u *= size;
34638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         u -= 0.5F;
34738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord0[ch] = util_ifloor(u);
34838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord1[ch] = icoord0[ch] + 1;
34938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (icoord0[ch] < 0)
35038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord0[ch] = 0;
35138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (icoord1[ch] >= (int) size)
35238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord1[ch] = size - 1;
35338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         w[ch] = FRAC(u);
35438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
35538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      break;;
35608f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
35708f33a025100dea2d951e6d628891fe294b18082Brian      {
358b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = -1.0F / (2.0F * size);
359b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
36038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (ch = 0; ch < 4; ch++) {
36138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            float u = fabsf(s[ch]);
36238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (u <= min)
36338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               u = min * size;
36438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else if (u >= max)
36538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               u = max * size;
36638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else
36738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               u *= size;
36838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            u -= 0.5F;
36938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord0[ch] = util_ifloor(u);
37038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord1[ch] = icoord0[ch] + 1;
37138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            w[ch] = FRAC(u);
37238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         }
37308f33a025100dea2d951e6d628891fe294b18082Brian      }
37438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      break;;
3750dc4eea64f56cc93e5359372b08b99a2d600273cBrian   default:
3760dc4eea64f56cc93e5359372b08b99a2d600273cBrian      assert(0);
3770dc4eea64f56cc93e5359372b08b99a2d600273cBrian   }
3780dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
3790dc4eea64f56cc93e5359372b08b99a2d600273cBrian
3800dc4eea64f56cc93e5359372b08b99a2d600273cBrian
381b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian/**
382b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * For RECT textures / unnormalized texcoords
383b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * Only a subset of wrap modes supported.
384b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian */
38538bee46e83b18ff4ad42d340b507b1a15b4326c7Brianstatic INLINE void
38638bee46e83b18ff4ad42d340b507b1a15b4326c7Briannearest_texcoord_unnorm_4(unsigned wrapMode, const float s[4], unsigned size,
38738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                          int icoord[4])
388b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{
38938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   uint ch;
390b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   switch (wrapMode) {
391b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP:
39238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
39338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         int i = util_ifloor(s[ch]);
39438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord[ch]= CLAMP(i, 0, (int) size-1);
39538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
39638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
397b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
398b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      /* fall-through */
399b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
40038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
40138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord[ch]= util_ifloor( CLAMP(s[ch], 0.5F, (float) size - 0.5F) );
40238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
40338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
404b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   default:
405b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      assert(0);
406b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   }
407b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian}
408b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
409b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
410b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian/**
411b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * For RECT textures / unnormalized texcoords.
412b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * Only a subset of wrap modes supported.
413b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian */
414b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrianstatic INLINE void
41538bee46e83b18ff4ad42d340b507b1a15b4326c7Brianlinear_texcoord_unnorm_4(unsigned wrapMode, const float s[4], unsigned size,
41638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                         int icoord0[4], int icoord1[4], float w[4])
417b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{
41838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   uint ch;
419b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   switch (wrapMode) {
420b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP:
42138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
42238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         /* Not exactly what the spec says, but it matches NVIDIA output */
42338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float u = CLAMP(s[ch] - 0.5F, 0.0f, (float) size - 1.0f);
42438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord0[ch] = util_ifloor(u);
42538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord1[ch] = icoord0[ch] + 1;
42638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         w[ch] = FRAC(u);
42738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
42838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
429b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
430b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      /* fall-through */
431b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
43238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
43338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float u = CLAMP(s[ch], 0.5F, (float) size - 0.5F);
43438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         u -= 0.5F;
43538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord0[ch] = util_ifloor(u);
43638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord1[ch] = icoord0[ch] + 1;
43738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (icoord1[ch] > (int) size - 1)
43838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord1[ch] = size - 1;
43938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         w[ch] = FRAC(u);
44038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
441b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      break;
442b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   default:
443b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      assert(0);
444b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   }
445b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian}
446b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
447b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
44870af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwellstatic unsigned
449a34b8594b7b2d00404bb639621ec1ce918ba0786Brianchoose_cube_face(float rx, float ry, float rz, float *newS, float *newT)
45034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
45134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   /*
45234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      major axis
45334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      direction     target                             sc     tc    ma
45434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      ----------    -------------------------------    ---    ---   ---
45534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       +rx          TEXTURE_CUBE_MAP_POSITIVE_X_EXT    -rz    -ry   rx
45634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       -rx          TEXTURE_CUBE_MAP_NEGATIVE_X_EXT    +rz    -ry   rx
45734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       +ry          TEXTURE_CUBE_MAP_POSITIVE_Y_EXT    +rx    +rz   ry
45834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       -ry          TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT    +rx    -rz   ry
45934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       +rz          TEXTURE_CUBE_MAP_POSITIVE_Z_EXT    +rx    -ry   rz
46034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       -rz          TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT    -rx    -ry   rz
46134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   */
4629935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul   const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz);
46370af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   unsigned face;
464b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   float sc, tc, ma;
46534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
46634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   if (arx > ary && arx > arz) {
46734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      if (rx >= 0.0F) {
46834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_POS_X;
46934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = -rz;
47034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
47134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arx;
47234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
47334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      else {
47434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_NEG_X;
47534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rz;
47634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
47734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arx;
47834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
47934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
48034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   else if (ary > arx && ary > arz) {
48134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      if (ry >= 0.0F) {
48234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_POS_Y;
48334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rx;
48434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = rz;
48534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = ary;
48634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
48734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      else {
48834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_NEG_Y;
48934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rx;
49034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -rz;
49134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = ary;
49234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
49334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
49434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   else {
49534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      if (rz > 0.0F) {
49634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_POS_Z;
49734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rx;
49834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
49934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arz;
50034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
50134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      else {
50234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_NEG_Z;
50334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = -rx;
50434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
50534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arz;
50634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
50734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
50834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
509a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   *newS = ( sc / ma + 1.0F ) * 0.5F;
510a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   *newT = ( tc / ma + 1.0F ) * 0.5F;
51134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
51234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   return face;
51334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
51434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
51534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
516b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/**
517b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * Examine the quad's texture coordinates to compute the partial
518b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * derivatives w.r.t X and Y, then compute lambda (level of detail).
519b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian *
520b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * This is only done for fragment shaders, not vertex shaders.
521b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian */
522b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic float
5230b9e96fae9493d5d58f046e01c983a3c4267090eBriancompute_lambda(const struct pipe_texture *tex,
5240b9e96fae9493d5d58f046e01c983a3c4267090eBrian               const struct pipe_sampler_state *sampler,
525b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float s[QUAD_SIZE],
526b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float t[QUAD_SIZE],
527f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian               const float p[QUAD_SIZE],
528f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian               float lodbias)
529b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian{
530b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   float rho, lambda;
531b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
5320b9e96fae9493d5d58f046e01c983a3c4267090eBrian   assert(sampler->normalized_coords);
533b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
534b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   assert(s);
535b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   {
536b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dsdx = s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT];
537b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dsdy = s[QUAD_TOP_LEFT]     - s[QUAD_BOTTOM_LEFT];
5389935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      dsdx = fabsf(dsdx);
5399935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      dsdy = fabsf(dsdy);
5400b9e96fae9493d5d58f046e01c983a3c4267090eBrian      rho = MAX2(dsdx, dsdy) * tex->width[0];
541b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
542b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   if (t) {
543b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT];
544b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dtdy = t[QUAD_TOP_LEFT]     - t[QUAD_BOTTOM_LEFT];
545b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float max;
5469935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      dtdx = fabsf(dtdx);
5479935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      dtdy = fabsf(dtdy);
5480b9e96fae9493d5d58f046e01c983a3c4267090eBrian      max = MAX2(dtdx, dtdy) * tex->height[0];
549b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      rho = MAX2(rho, max);
550b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
551b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   if (p) {
552b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dpdx = p[QUAD_BOTTOM_RIGHT] - p[QUAD_BOTTOM_LEFT];
553b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dpdy = p[QUAD_TOP_LEFT]     - p[QUAD_BOTTOM_LEFT];
554b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float max;
5559935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      dpdx = fabsf(dpdx);
5569935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      dpdy = fabsf(dpdy);
5570b9e96fae9493d5d58f046e01c983a3c4267090eBrian      max = MAX2(dpdx, dpdy) * tex->depth[0];
558b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      rho = MAX2(rho, max);
559b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
560b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
5611a46dcc8a927dfb38ca1381e7b3dafb789f8257cBrian Paul   lambda = util_fast_log2(rho);
5620b9e96fae9493d5d58f046e01c983a3c4267090eBrian   lambda += lodbias + sampler->lod_bias;
5630b9e96fae9493d5d58f046e01c983a3c4267090eBrian   lambda = CLAMP(lambda, sampler->min_lod, sampler->max_lod);
564b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
565b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   return lambda;
566b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian}
567b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
568b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
569f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian/**
570c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * Do several things here:
571c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 1. Compute lambda from the texcoords, if needed
572c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 2. Determine if we're minifying or magnifying
573c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 3. If minifying, choose mipmap levels
574c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 4. Return image filter to use within mipmap images
575dd55083ac1c13723dba6be71f161e2ca7cac7c66Brian * \param level0  Returns first mipmap level to sample from
576dd55083ac1c13723dba6be71f161e2ca7cac7c66Brian * \param level1  Returns second mipmap level to sample from
577dd55083ac1c13723dba6be71f161e2ca7cac7c66Brian * \param levelBlend  Returns blend factor between levels, in [0,1]
578dd55083ac1c13723dba6be71f161e2ca7cac7c66Brian * \param imgFilter  Returns either the min or mag filter, depending on lambda
579f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian */
580f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrianstatic void
5810b9e96fae9493d5d58f046e01c983a3c4267090eBrianchoose_mipmap_levels(const struct pipe_texture *texture,
5820b9e96fae9493d5d58f046e01c983a3c4267090eBrian                     const struct pipe_sampler_state *sampler,
583c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     const float s[QUAD_SIZE],
584c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     const float t[QUAD_SIZE],
585c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     const float p[QUAD_SIZE],
586c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     float lodbias,
587c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     unsigned *level0, unsigned *level1, float *levelBlend,
588c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     unsigned *imgFilter)
58909a1b912605ff48c8782dcc5aae55ac77e27037bBrian{
5900b9e96fae9493d5d58f046e01c983a3c4267090eBrian   if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) {
591c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      /* no mipmap selection needed */
5920b9e96fae9493d5d58f046e01c983a3c4267090eBrian      *level0 = *level1 = CLAMP((int) sampler->min_lod,
5930b9e96fae9493d5d58f046e01c983a3c4267090eBrian                                0, (int) texture->last_level);
59408c9534107fcaf06f9b801551524ed5dc724db13Brian
5950b9e96fae9493d5d58f046e01c983a3c4267090eBrian      if (sampler->min_img_filter != sampler->mag_img_filter) {
59608c9534107fcaf06f9b801551524ed5dc724db13Brian         /* non-mipmapped texture, but still need to determine if doing
59708c9534107fcaf06f9b801551524ed5dc724db13Brian          * minification or magnification.
59808c9534107fcaf06f9b801551524ed5dc724db13Brian          */
5990b9e96fae9493d5d58f046e01c983a3c4267090eBrian         float lambda = compute_lambda(texture, sampler, s, t, p, lodbias);
6003b2a291888d8e62787de03f8529806fb562bd186Brian         if (lambda <= 0.0) {
6010b9e96fae9493d5d58f046e01c983a3c4267090eBrian            *imgFilter = sampler->mag_img_filter;
60208c9534107fcaf06f9b801551524ed5dc724db13Brian         }
60308c9534107fcaf06f9b801551524ed5dc724db13Brian         else {
6040b9e96fae9493d5d58f046e01c983a3c4267090eBrian            *imgFilter = sampler->min_img_filter;
60508c9534107fcaf06f9b801551524ed5dc724db13Brian         }
60608c9534107fcaf06f9b801551524ed5dc724db13Brian      }
6073b2a291888d8e62787de03f8529806fb562bd186Brian      else {
6080b9e96fae9493d5d58f046e01c983a3c4267090eBrian         *imgFilter = sampler->mag_img_filter;
6093b2a291888d8e62787de03f8529806fb562bd186Brian      }
610c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian   }
611c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian   else {
612c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      float lambda;
613c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian
614c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      if (1)
615c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* fragment shader */
6160b9e96fae9493d5d58f046e01c983a3c4267090eBrian         lambda = compute_lambda(texture, sampler, s, t, p, lodbias);
617c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      else
618c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* vertex shader */
619c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         lambda = lodbias; /* not really a bias, but absolute LOD */
620c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian
6213b2a291888d8e62787de03f8529806fb562bd186Brian      if (lambda <= 0.0) { /* XXX threshold depends on the filter */
622c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* magnifying */
6230b9e96fae9493d5d58f046e01c983a3c4267090eBrian         *imgFilter = sampler->mag_img_filter;
6244da1cdf78fa3b954840650fa46cf72da5daf149fBrian         *level0 = *level1 = 0;
625f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      }
626c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      else {
627c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* minifying */
6280b9e96fae9493d5d58f046e01c983a3c4267090eBrian         *imgFilter = sampler->min_img_filter;
629c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian
630c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* choose mipmap level(s) and compute the blend factor between them */
6310b9e96fae9493d5d58f046e01c983a3c4267090eBrian         if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NEAREST) {
632c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            /* Nearest mipmap level */
633c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            const int lvl = (int) (lambda + 0.5);
634c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            *level0 =
6350b9e96fae9493d5d58f046e01c983a3c4267090eBrian            *level1 = CLAMP(lvl, 0, (int) texture->last_level);
636c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         }
637c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         else {
638c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            /* Linear interpolation between mipmap levels */
639c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            const int lvl = (int) lambda;
6400b9e96fae9493d5d58f046e01c983a3c4267090eBrian            *level0 = CLAMP(lvl,     0, (int) texture->last_level);
6410b9e96fae9493d5d58f046e01c983a3c4267090eBrian            *level1 = CLAMP(lvl + 1, 0, (int) texture->last_level);
642c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            *levelBlend = FRAC(lambda);  /* blending weight between levels */
643c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         }
644f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      }
64509a1b912605ff48c8782dcc5aae55ac77e27037bBrian   }
64609a1b912605ff48c8782dcc5aae55ac77e27037bBrian}
64709a1b912605ff48c8782dcc5aae55ac77e27037bBrian
64808f33a025100dea2d951e6d628891fe294b18082Brian
649b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/**
650a13de2464dd034ff117f9314df5757d068cae8e5Brian * Get a texel from a texture, using the texture tile cache.
651a13de2464dd034ff117f9314df5757d068cae8e5Brian *
652b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param face  the cube face in 0..5
653b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param level  the mipmap level
654b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param x  the x coord of texel within 2D image
655b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param y  the y coord of texel within 2D image
65670eb7996f265f3634dabda078f13d1be3533cc65Brian * \param z  which slice of a 3D texture
657b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param rgba  the quad to put the texel/color into
658b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param j  which element of the rgba quad to write to
65970eb7996f265f3634dabda078f13d1be3533cc65Brian *
66070eb7996f265f3634dabda078f13d1be3533cc65Brian * XXX maybe move this into sp_tile_cache.c and merge with the
66170eb7996f265f3634dabda078f13d1be3533cc65Brian * sp_get_cached_tile_tex() function.  Also, get 4 texels instead of 1...
662b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian */
663b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic void
664dd55083ac1c13723dba6be71f161e2ca7cac7c66Brianget_texel(const struct tgsi_sampler *tgsi_sampler,
66570eb7996f265f3634dabda078f13d1be3533cc65Brian          unsigned face, unsigned level, int x, int y, int z,
666a13de2464dd034ff117f9314df5757d068cae8e5Brian          float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j)
667b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian{
6680b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
6690b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct softpipe_context *sp = samp->sp;
6700b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const uint unit = samp->unit;
6710b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct pipe_texture *texture = sp->texture[unit];
6720b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct pipe_sampler_state *sampler = sp->sampler[unit];
6730b9e96fae9493d5d58f046e01c983a3c4267090eBrian
6740b9e96fae9493d5d58f046e01c983a3c4267090eBrian   if (x < 0 || x >= (int) texture->width[level] ||
6750b9e96fae9493d5d58f046e01c983a3c4267090eBrian       y < 0 || y >= (int) texture->height[level] ||
6760b9e96fae9493d5d58f046e01c983a3c4267090eBrian       z < 0 || z >= (int) texture->depth[level]) {
6770b9e96fae9493d5d58f046e01c983a3c4267090eBrian      rgba[0][j] = sampler->border_color[0];
6780b9e96fae9493d5d58f046e01c983a3c4267090eBrian      rgba[1][j] = sampler->border_color[1];
6790b9e96fae9493d5d58f046e01c983a3c4267090eBrian      rgba[2][j] = sampler->border_color[2];
6800b9e96fae9493d5d58f046e01c983a3c4267090eBrian      rgba[3][j] = sampler->border_color[3];
681ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul   }
682ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul   else {
683ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul      const int tx = x % TILE_SIZE;
684ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul      const int ty = y % TILE_SIZE;
685ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul      const struct softpipe_cached_tile *tile
6860b9e96fae9493d5d58f046e01c983a3c4267090eBrian         = sp_get_cached_tile_tex(samp->sp, samp->cache,
687ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul                                  x, y, z, face, level);
688ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul      rgba[0][j] = tile->data.color[ty][tx][0];
689ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul      rgba[1][j] = tile->data.color[ty][tx][1];
690ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul      rgba[2][j] = tile->data.color[ty][tx][2];
691ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul      rgba[3][j] = tile->data.color[ty][tx][3];
692b1ff7dac537947d412bf423a73e7eacd76f90d84Brian Paul      if (0)
693b1ff7dac537947d412bf423a73e7eacd76f90d84Brian Paul      {
694ae2195caf56d2eb782475254c68858a25ee7c857Brian Paul         debug_printf("Get texel %f %f %f %f from %s\n",
6958fb55dab783f2de5111e7440093e1458fce5fb3dBrian Paul                      rgba[0][j], rgba[1][j], rgba[2][j], rgba[3][j],
6960b9e96fae9493d5d58f046e01c983a3c4267090eBrian                      pf_name(texture->format));
697b1ff7dac537947d412bf423a73e7eacd76f90d84Brian Paul      }
698ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul   }
699b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian}
700b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
701b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
7023d8c05f7320151898dd224c1daaf3118e1f7ea34Brian/**
7033d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * Compare texcoord 'p' (aka R) against texture value 'rgba[0]'
7043d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * When we sampled the depth texture, the depth value was put into all
7053d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * RGBA channels.  We look at the red channel here.
7063d8c05f7320151898dd224c1daaf3118e1f7ea34Brian */
7073d8c05f7320151898dd224c1daaf3118e1f7ea34Brianstatic INLINE void
7083d8c05f7320151898dd224c1daaf3118e1f7ea34Brianshadow_compare(uint compare_func,
7093d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               float rgba[NUM_CHANNELS][QUAD_SIZE],
7103d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               const float p[QUAD_SIZE],
7113d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               uint j)
7123d8c05f7320151898dd224c1daaf3118e1f7ea34Brian{
7133d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   int k;
7143d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   switch (compare_func) {
7153d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_LESS:
7163d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] < rgba[0][j];
7173d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
7183d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_LEQUAL:
7193d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] <= rgba[0][j];
7203d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
7213d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_GREATER:
7223d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] > rgba[0][j];
7233d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
7243d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_GEQUAL:
7253d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] >= rgba[0][j];
7263d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
7273d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_EQUAL:
7283d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] == rgba[0][j];
7293d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
7303d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_NOTEQUAL:
7313d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] != rgba[0][j];
7323d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
7333d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_ALWAYS:
7343d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = 1;
7353d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
7363d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_NEVER:
7373d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = 0;
7383d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
7393d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   default:
740f9b1d47d652778012fd35552ffc51717ac0b6f79Keith Whitwell      k = 0;
7413d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      assert(0);
742f9b1d47d652778012fd35552ffc51717ac0b6f79Keith Whitwell      break;
7433d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   }
7443d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
7453d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   rgba[0][j] = rgba[1][j] = rgba[2][j] = (float) k;
7463d8c05f7320151898dd224c1daaf3118e1f7ea34Brian}
7473d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
748b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
749b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/**
750a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Common code for sampling 1D/2D/cube textures.
751a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Could probably extend for 3D...
7520dc4eea64f56cc93e5359372b08b99a2d600273cBrian */
753e12810d92ffb3547680b227bf88937c03018112bBrianstatic void
754dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler,
755a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         const float s[QUAD_SIZE],
756a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         const float t[QUAD_SIZE],
757a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         const float p[QUAD_SIZE],
758a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         float lodbias,
759a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         float rgba[NUM_CHANNELS][QUAD_SIZE],
760a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         const unsigned faces[4])
7610dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
7620b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
7630b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct softpipe_context *sp = samp->sp;
7640b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const uint unit = samp->unit;
7650b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct pipe_texture *texture = sp->texture[unit];
7660b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct pipe_sampler_state *sampler = sp->sampler[unit];
7670b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const uint compare_func = sampler->compare_func;
768f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian   unsigned level0, level1, j, imgFilter;
769f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian   int width, height;
770c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian   float levelBlend;
771a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
7720b9e96fae9493d5d58f046e01c983a3c4267090eBrian   choose_mipmap_levels(texture, sampler, s, t, p, lodbias,
773c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                        &level0, &level1, &levelBlend, &imgFilter);
77409a1b912605ff48c8782dcc5aae55ac77e27037bBrian
7750b9e96fae9493d5d58f046e01c983a3c4267090eBrian   assert(sampler->normalized_coords);
776b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
7770b9e96fae9493d5d58f046e01c983a3c4267090eBrian   width = texture->width[level0];
7780b9e96fae9493d5d58f046e01c983a3c4267090eBrian   height = texture->height[level0];
77909a1b912605ff48c8782dcc5aae55ac77e27037bBrian
780b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   assert(width > 0);
781612cfb749c3526eeb446bbc631bf24716522f373Brian
782b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   switch (imgFilter) {
7830dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_FILTER_NEAREST:
78438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      {
78538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         int x[4], y[4];
78638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         nearest_texcoord_4(sampler->wrap_s, s, width, x);
78738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         nearest_texcoord_4(sampler->wrap_t, t, height, y);
78838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
78938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (j = 0; j < QUAD_SIZE; j++) {
79038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, faces[j], level0, x[j], y[j], 0, rgba, j);
79138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
79238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               shadow_compare(compare_func, rgba, p, j);
7933d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            }
7943d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
79538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (level0 != level1) {
79638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               /* get texels from second mipmap level and blend */
79738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               float rgba2[4][4];
79838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               unsigned c;
79938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               x[j] /= 2;
80038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               y[j] /= 2;
80138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, faces[j], level1, x[j], y[j], 0,
80238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                         rgba2, j);
80338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
80438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                  shadow_compare(compare_func, rgba2, p, j);
80538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               }
80638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
80738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               for (c = 0; c < NUM_CHANNELS; c++) {
80838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                  rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]);
80938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               }
810f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            }
811f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian         }
8120dc4eea64f56cc93e5359372b08b99a2d600273cBrian      }
8130dc4eea64f56cc93e5359372b08b99a2d600273cBrian      break;
8140dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_FILTER_LINEAR:
81598ae83d5cc73b61826823c915b5c59746c2e85c7Keith Whitwell   case PIPE_TEX_FILTER_ANISO:
81638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      {
81738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         int x0[4], y0[4], x1[4], y1[4];
81838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float xw[4], yw[4]; /* weights */
81938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
82038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         linear_texcoord_4(sampler->wrap_s, s, width, x0, x1, xw);
82138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         linear_texcoord_4(sampler->wrap_t, t, height, y0, y1, yw);
82238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
82338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (j = 0; j < QUAD_SIZE; j++) {
82438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            float tx[4][4]; /* texels */
82538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            int c;
82638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, faces[j], level0, x0[j], y0[j], 0, tx, 0);
82738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, faces[j], level0, x1[j], y0[j], 0, tx, 1);
82838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, faces[j], level0, x0[j], y1[j], 0, tx, 2);
82938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, faces[j], level0, x1[j], y1[j], 0, tx, 3);
83038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
8313d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               shadow_compare(compare_func, tx, p, 0);
8323d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               shadow_compare(compare_func, tx, p, 1);
8333d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               shadow_compare(compare_func, tx, p, 2);
8343d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               shadow_compare(compare_func, tx, p, 3);
8353d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            }
8363d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
83738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            /* interpolate R, G, B, A */
838f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            for (c = 0; c < 4; c++) {
83938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               rgba[c][j] = lerp_2d(xw[j], yw[j],
84038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                    tx[c][0], tx[c][1],
84138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                    tx[c][2], tx[c][3]);
842f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            }
843f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian
84438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (level0 != level1) {
84538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               /* get texels from second mipmap level and blend */
84638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               float rgba2[4][4];
84738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               x0[j] /= 2;
84838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               y0[j] /= 2;
84938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               x1[j] /= 2;
85038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               y1[j] /= 2;
85138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, faces[j], level1, x0[j], y0[j], 0, tx, 0);
85238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, faces[j], level1, x1[j], y0[j], 0, tx, 1);
85338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, faces[j], level1, x0[j], y1[j], 0, tx, 2);
85438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, faces[j], level1, x1[j], y1[j], 0, tx, 3);
85538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
85638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                  shadow_compare(compare_func, tx, p, 0);
85738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                  shadow_compare(compare_func, tx, p, 1);
85838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                  shadow_compare(compare_func, tx, p, 2);
85938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                  shadow_compare(compare_func, tx, p, 3);
86038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               }
86138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
86238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               /* interpolate R, G, B, A */
86338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               for (c = 0; c < 4; c++) {
86438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                  rgba2[c][j] = lerp_2d(xw[j], yw[j],
86538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                        tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
86638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               }
86738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
86838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               for (c = 0; c < NUM_CHANNELS; c++) {
86938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                  rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]);
87038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               }
871f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            }
872f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian         }
87309a1b912605ff48c8782dcc5aae55ac77e27037bBrian      }
87409a1b912605ff48c8782dcc5aae55ac77e27037bBrian      break;
8750dc4eea64f56cc93e5359372b08b99a2d600273cBrian   default:
8760dc4eea64f56cc93e5359372b08b99a2d600273cBrian      assert(0);
8770dc4eea64f56cc93e5359372b08b99a2d600273cBrian   }
8780dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
87934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
88034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
881dd55083ac1c13723dba6be71f161e2ca7cac7c66Brianstatic INLINE void
882dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_1d(const struct tgsi_sampler *sampler,
883a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float s[QUAD_SIZE],
884a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float t[QUAD_SIZE],
885a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float p[QUAD_SIZE],
886a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  float lodbias,
887a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  float rgba[NUM_CHANNELS][QUAD_SIZE])
888a34b8594b7b2d00404bb639621ec1ce918ba0786Brian{
889a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   static const unsigned faces[4] = {0, 0, 0, 0};
890d16b4bc32a731cb6ae320e8c187af3bc751d4138Brian   static const float tzero[4] = {0, 0, 0, 0};
891d16b4bc32a731cb6ae320e8c187af3bc751d4138Brian   sp_get_samples_2d_common(sampler, s, tzero, NULL, lodbias, rgba, faces);
892a34b8594b7b2d00404bb639621ec1ce918ba0786Brian}
893a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
894a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
895dd55083ac1c13723dba6be71f161e2ca7cac7c66Brianstatic INLINE void
896dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_2d(const struct tgsi_sampler *sampler,
897a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float s[QUAD_SIZE],
898a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float t[QUAD_SIZE],
899a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float p[QUAD_SIZE],
900a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  float lodbias,
901a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  float rgba[NUM_CHANNELS][QUAD_SIZE])
902a34b8594b7b2d00404bb639621ec1ce918ba0786Brian{
903a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   static const unsigned faces[4] = {0, 0, 0, 0};
9043d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   sp_get_samples_2d_common(sampler, s, t, p, lodbias, rgba, faces);
905a34b8594b7b2d00404bb639621ec1ce918ba0786Brian}
906a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
907a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
908dd55083ac1c13723dba6be71f161e2ca7cac7c66Brianstatic INLINE void
909dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_3d(const struct tgsi_sampler *tgsi_sampler,
910b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  const float s[QUAD_SIZE],
911b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  const float t[QUAD_SIZE],
912b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  const float p[QUAD_SIZE],
913f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian                  float lodbias,
914b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  float rgba[NUM_CHANNELS][QUAD_SIZE])
91534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
9160b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
9170b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct softpipe_context *sp = samp->sp;
9180b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const uint unit = samp->unit;
9190b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct pipe_texture *texture = sp->texture[unit];
9200b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct pipe_sampler_state *sampler = sp->sampler[unit];
92134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   /* get/map pipe_surfaces corresponding to 3D tex slices */
9223d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   unsigned level0, level1, j, imgFilter;
9233d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   int width, height, depth;
9243d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   float levelBlend;
9253d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   const uint face = 0;
9263d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
9270b9e96fae9493d5d58f046e01c983a3c4267090eBrian   choose_mipmap_levels(texture, sampler, s, t, p, lodbias,
9283d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                        &level0, &level1, &levelBlend, &imgFilter);
9293d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
9300b9e96fae9493d5d58f046e01c983a3c4267090eBrian   assert(sampler->normalized_coords);
931b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
9320b9e96fae9493d5d58f046e01c983a3c4267090eBrian   width = texture->width[level0];
9330b9e96fae9493d5d58f046e01c983a3c4267090eBrian   height = texture->height[level0];
9340b9e96fae9493d5d58f046e01c983a3c4267090eBrian   depth = texture->depth[level0];
9353d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
9363d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   assert(width > 0);
9373d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   assert(height > 0);
9383d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   assert(depth > 0);
9393d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
9403d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   switch (imgFilter) {
9413d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   case PIPE_TEX_FILTER_NEAREST:
94238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      {
94338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         int x[4], y[4], z[4];
94438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         nearest_texcoord_4(sampler->wrap_s, s, width, x);
94538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         nearest_texcoord_4(sampler->wrap_t, t, height, y);
94638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         nearest_texcoord_4(sampler->wrap_r, p, depth, z);
94738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (j = 0; j < QUAD_SIZE; j++) {
94838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x[j], y[j], z[j], rgba, j);
94938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (level0 != level1) {
95038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               /* get texels from second mipmap level and blend */
95138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               float rgba2[4][4];
95238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               unsigned c;
95338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               x[j] /= 2;
95438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               y[j] /= 2;
95538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               z[j] /= 2;
95638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, face, level1, x[j], y[j], z[j], rgba2, j);
95738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               for (c = 0; c < NUM_CHANNELS; c++) {
95838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                  rgba[c][j] = lerp(levelBlend, rgba2[c][j], rgba[c][j]);
95938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               }
9603d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            }
9613d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         }
9623d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      }
9633d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      break;
9643d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   case PIPE_TEX_FILTER_LINEAR:
96598ae83d5cc73b61826823c915b5c59746c2e85c7Keith Whitwell   case PIPE_TEX_FILTER_ANISO:
96638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      {
96738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         int x0[4], x1[4], y0[4], y1[4], z0[4], z1[4];
96838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float xw[4], yw[4], zw[4]; /* interpolation weights */
96938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         linear_texcoord_4(sampler->wrap_s, s, width,  x0, x1, xw);
97038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         linear_texcoord_4(sampler->wrap_t, t, height, y0, y1, yw);
97138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         linear_texcoord_4(sampler->wrap_r, p, depth,  z0, z1, zw);
97238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
97338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (j = 0; j < QUAD_SIZE; j++) {
97438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            int c;
97538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            float tx0[4][4], tx1[4][4];
97638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x0[j], y0[j], z0[j], tx0, 0);
97738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x1[j], y0[j], z0[j], tx0, 1);
97838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x0[j], y1[j], z0[j], tx0, 2);
97938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x1[j], y1[j], z0[j], tx0, 3);
98038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x0[j], y0[j], z1[j], tx1, 0);
98138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x1[j], y0[j], z1[j], tx1, 1);
98238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x0[j], y1[j], z1[j], tx1, 2);
98338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x1[j], y1[j], z1[j], tx1, 3);
98438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
98538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            /* interpolate R, G, B, A */
9863d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            for (c = 0; c < 4; c++) {
98738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               rgba[c][j] = lerp_3d(xw[j], yw[j], zw[j],
98838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                    tx0[c][0], tx0[c][1],
98938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                    tx0[c][2], tx0[c][3],
99038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                    tx1[c][0], tx1[c][1],
99138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                    tx1[c][2], tx1[c][3]);
9923d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            }
9933d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
99438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (level0 != level1) {
99538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               /* get texels from second mipmap level and blend */
99638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               float rgba2[4][4];
99738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               x0[j] /= 2;
99838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               y0[j] /= 2;
99938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               z0[j] /= 2;
100038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               x1[j] /= 2;
100138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               y1[j] /= 2;
100238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               z1[j] /= 2;
100338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, face, level1, x0[j], y0[j], z0[j], tx0, 0);
100438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, face, level1, x1[j], y0[j], z0[j], tx0, 1);
100538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, face, level1, x0[j], y1[j], z0[j], tx0, 2);
100638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, face, level1, x1[j], y1[j], z0[j], tx0, 3);
100738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, face, level1, x0[j], y0[j], z1[j], tx1, 0);
100838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, face, level1, x1[j], y0[j], z1[j], tx1, 1);
100938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, face, level1, x0[j], y1[j], z1[j], tx1, 2);
101038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, face, level1, x1[j], y1[j], z1[j], tx1, 3);
101138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
101238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               /* interpolate R, G, B, A */
101338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               for (c = 0; c < 4; c++) {
101438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                  rgba2[c][j] = lerp_3d(xw[j], yw[j], zw[j],
101538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                        tx0[c][0], tx0[c][1],
101638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                        tx0[c][2], tx0[c][3],
101738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                        tx1[c][0], tx1[c][1],
101838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                        tx1[c][2], tx1[c][3]);
101938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               }
102038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
102138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               /* blend mipmap levels */
102238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               for (c = 0; c < NUM_CHANNELS; c++) {
102338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                  rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]);
102438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               }
10253d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            }
10263d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         }
10273d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      }
10283d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      break;
10293d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   default:
10303d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      assert(0);
10313d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   }
103234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
103334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
103434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
103534a48abd5ff82ce9748fc29191e35a0985d47c5fBrianstatic void
1036dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_cube(const struct tgsi_sampler *sampler,
1037b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                    const float s[QUAD_SIZE],
1038b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                    const float t[QUAD_SIZE],
1039b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                    const float p[QUAD_SIZE],
1040f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian                    float lodbias,
1041b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                    float rgba[NUM_CHANNELS][QUAD_SIZE])
104234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
1043a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   unsigned faces[QUAD_SIZE], j;
1044a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   float ssss[4], tttt[4];
1045b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   for (j = 0; j < QUAD_SIZE; j++) {
1046a34b8594b7b2d00404bb639621ec1ce918ba0786Brian      faces[j] = choose_cube_face(s[j], t[j], p[j], ssss + j, tttt + j);
1047b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
1048a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   sp_get_samples_2d_common(sampler, ssss, tttt, NULL, lodbias, rgba, faces);
104934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
105034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
105134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
1052b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrianstatic void
1053dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler,
1054b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                    const float s[QUAD_SIZE],
1055b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                    const float t[QUAD_SIZE],
1056b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                    const float p[QUAD_SIZE],
1057b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                    float lodbias,
1058b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                    float rgba[NUM_CHANNELS][QUAD_SIZE])
1059b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{
10600b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
10610b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct softpipe_context *sp = samp->sp;
10620b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const uint unit = samp->unit;
10630b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct pipe_texture *texture = sp->texture[unit];
10640b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct pipe_sampler_state *sampler = sp->sampler[unit];
1065b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   //sp_get_samples_2d_common(sampler, s, t, p, lodbias, rgba, faces);
1066b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   static const uint face = 0;
10670b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const uint compare_func = sampler->compare_func;
1068b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   unsigned level0, level1, j, imgFilter;
1069b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   int width, height;
1070b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   float levelBlend;
1071b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
10720b9e96fae9493d5d58f046e01c983a3c4267090eBrian   choose_mipmap_levels(texture, sampler, s, t, p, lodbias,
1073b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                        &level0, &level1, &levelBlend, &imgFilter);
1074b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
1075b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   /* texture RECTS cannot be mipmapped */
1076b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   assert(level0 == level1);
1077b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
10780b9e96fae9493d5d58f046e01c983a3c4267090eBrian   width = texture->width[level0];
10790b9e96fae9493d5d58f046e01c983a3c4267090eBrian   height = texture->height[level0];
1080b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
1081b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   assert(width > 0);
1082b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
1083b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   switch (imgFilter) {
1084b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_FILTER_NEAREST:
108538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      {
108638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         int x[4], y[4];
108738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         nearest_texcoord_unnorm_4(sampler->wrap_s, s, width, x);
108838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         nearest_texcoord_unnorm_4(sampler->wrap_t, t, height, y);
108938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (j = 0; j < QUAD_SIZE; j++) {
109038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x[j], y[j], 0, rgba, j);
109138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
109238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               shadow_compare(compare_func, rgba, p, j);
109338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            }
1094b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         }
1095b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      }
1096b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      break;
1097b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_FILTER_LINEAR:
109898ae83d5cc73b61826823c915b5c59746c2e85c7Keith Whitwell   case PIPE_TEX_FILTER_ANISO:
109938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      {
110038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         int x0[4], y0[4], x1[4], y1[4];
110138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float xw[4], yw[4]; /* weights */
110238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         linear_texcoord_unnorm_4(sampler->wrap_s, s, width,  x0, x1, xw);
110338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         linear_texcoord_unnorm_4(sampler->wrap_t, t, height, y0, y1, yw);
110438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (j = 0; j < QUAD_SIZE; j++) {
110538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            float tx[4][4]; /* texels */
110638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            int c;
110738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x0[j], y0[j], 0, tx, 0);
110838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x1[j], y0[j], 0, tx, 1);
110938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x0[j], y1[j], 0, tx, 2);
111038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x1[j], y1[j], 0, tx, 3);
111138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
111238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               shadow_compare(compare_func, tx, p, 0);
111338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               shadow_compare(compare_func, tx, p, 1);
111438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               shadow_compare(compare_func, tx, p, 2);
111538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               shadow_compare(compare_func, tx, p, 3);
111638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            }
111738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            for (c = 0; c < 4; c++) {
111838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               rgba[c][j] = lerp_2d(xw[j], yw[j],
111938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                    tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
112038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            }
1121b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         }
1122b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      }
1123b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      break;
1124b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   default:
1125b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      assert(0);
1126b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   }
1127b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian}
1128b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
1129b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
1130a34b8594b7b2d00404bb639621ec1ce918ba0786Brian/**
1131a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Called via tgsi_sampler::get_samples()
1132a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Use the sampler's state setting to get a filtered RGBA value
1133753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * from the sampler's texture.
1134a34b8594b7b2d00404bb639621ec1ce918ba0786Brian *
1135a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * XXX we can implement many versions of this function, each
1136a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * tightly coded for a specific combination of sampler state
1137a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * (nearest + repeat), (bilinear mipmap + clamp), etc.
1138a34b8594b7b2d00404bb639621ec1ce918ba0786Brian *
1139a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * The update_samplers() function in st_atom_sampler.c could create
1140a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * a new tgsi_sampler object for each state combo it finds....
1141a34b8594b7b2d00404bb639621ec1ce918ba0786Brian */
114234a48abd5ff82ce9748fc29191e35a0985d47c5fBrianvoid
11430b9e96fae9493d5d58f046e01c983a3c4267090eBriansp_get_samples(struct tgsi_sampler *tgsi_sampler,
1144b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float s[QUAD_SIZE],
1145b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float t[QUAD_SIZE],
1146b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float p[QUAD_SIZE],
1147f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian               float lodbias,
1148b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               float rgba[NUM_CHANNELS][QUAD_SIZE])
114934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
11500b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
11510b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct softpipe_context *sp = samp->sp;
11520b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const uint unit = samp->unit;
11530b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct pipe_texture *texture = sp->texture[unit];
11540b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct pipe_sampler_state *sampler = sp->sampler[unit];
11550b9e96fae9493d5d58f046e01c983a3c4267090eBrian
11560b9e96fae9493d5d58f046e01c983a3c4267090eBrian   if (!texture)
11574f23468bd0d14b8ed687a641003d587b91ad39a7Brian      return;
11584f23468bd0d14b8ed687a641003d587b91ad39a7Brian
11590b9e96fae9493d5d58f046e01c983a3c4267090eBrian   switch (texture->target) {
116070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   case PIPE_TEXTURE_1D:
11610b9e96fae9493d5d58f046e01c983a3c4267090eBrian      assert(sampler->normalized_coords);
11620b9e96fae9493d5d58f046e01c983a3c4267090eBrian      sp_get_samples_1d(tgsi_sampler, s, t, p, lodbias, rgba);
116334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
116470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   case PIPE_TEXTURE_2D:
11650b9e96fae9493d5d58f046e01c983a3c4267090eBrian      if (sampler->normalized_coords)
11660b9e96fae9493d5d58f046e01c983a3c4267090eBrian         sp_get_samples_2d(tgsi_sampler, s, t, p, lodbias, rgba);
1167b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      else
11680b9e96fae9493d5d58f046e01c983a3c4267090eBrian         sp_get_samples_rect(tgsi_sampler, s, t, p, lodbias, rgba);
116934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
117070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   case PIPE_TEXTURE_3D:
11710b9e96fae9493d5d58f046e01c983a3c4267090eBrian      assert(sampler->normalized_coords);
11720b9e96fae9493d5d58f046e01c983a3c4267090eBrian      sp_get_samples_3d(tgsi_sampler, s, t, p, lodbias, rgba);
117334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
117470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   case PIPE_TEXTURE_CUBE:
11750b9e96fae9493d5d58f046e01c983a3c4267090eBrian      assert(sampler->normalized_coords);
11760b9e96fae9493d5d58f046e01c983a3c4267090eBrian      sp_get_samples_cube(tgsi_sampler, s, t, p, lodbias, rgba);
117734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
117834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   default:
117934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      assert(0);
118034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
11813d53d38d5e35386de4793162b9dd32e171927059Brian Paul
11823d53d38d5e35386de4793162b9dd32e171927059Brian Paul#if 0 /* DEBUG */
11833d53d38d5e35386de4793162b9dd32e171927059Brian Paul   {
11843d53d38d5e35386de4793162b9dd32e171927059Brian Paul      int i;
11853d53d38d5e35386de4793162b9dd32e171927059Brian Paul      printf("Sampled at %f, %f, %f:\n", s[0], t[0], p[0]);
11863d53d38d5e35386de4793162b9dd32e171927059Brian Paul      for (i = 0; i < 4; i++) {
11873d53d38d5e35386de4793162b9dd32e171927059Brian Paul         printf("Frag %d: %f %f %f %f\n", i,
11883d53d38d5e35386de4793162b9dd32e171927059Brian Paul                rgba[0][i],
11893d53d38d5e35386de4793162b9dd32e171927059Brian Paul                rgba[1][i],
11903d53d38d5e35386de4793162b9dd32e171927059Brian Paul                rgba[2][i],
11913d53d38d5e35386de4793162b9dd32e171927059Brian Paul                rgba[3][i]);
11923d53d38d5e35386de4793162b9dd32e171927059Brian Paul      }
11933d53d38d5e35386de4793162b9dd32e171927059Brian Paul   }
11943d53d38d5e35386de4793162b9dd32e171927059Brian Paul#endif
119534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
119634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
1197