sp_tex_sample.c revision 9935e3b7303da656e258d4bd5bc799ffbfbc737b
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"
380dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "sp_tex_sample.h"
3970eb7996f265f3634dabda078f13d1be3533cc65Brian#include "sp_tile_cache.h"
400dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "pipe/p_context.h"
410dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "pipe/p_defines.h"
427de874ec2c7b9e3aff7f81b7e30045b45381fbadMichal Krol#include "pipe/p_util.h"
43c208a2c791fa24c7c5887fc496738cbddbfafc72José Fonseca#include "tgsi/tgsi_exec.h"
441a46dcc8a927dfb38ca1381e7b3dafb789f8257cBrian Paul#include "util/u_math.h"
450dc4eea64f56cc93e5359372b08b99a2d600273cBrian
460dc4eea64f56cc93e5359372b08b99a2d600273cBrian
4708f33a025100dea2d951e6d628891fe294b18082Brian/*
4808f33a025100dea2d951e6d628891fe294b18082Brian * Note, the FRAC macro has to work perfectly.  Otherwise you'll sometimes
4908f33a025100dea2d951e6d628891fe294b18082Brian * see 1-pixel bands of improperly weighted linear-filtered textures.
5008f33a025100dea2d951e6d628891fe294b18082Brian * The tests/texwrap.c demo is a good test.
5108f33a025100dea2d951e6d628891fe294b18082Brian * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0.
5208f33a025100dea2d951e6d628891fe294b18082Brian * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x).
5308f33a025100dea2d951e6d628891fe294b18082Brian */
549935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul#define FRAC(f)  ((f) - util_ifloor(f))
5508f33a025100dea2d951e6d628891fe294b18082Brian
5608f33a025100dea2d951e6d628891fe294b18082Brian
5708f33a025100dea2d951e6d628891fe294b18082Brian/**
5808f33a025100dea2d951e6d628891fe294b18082Brian * Linear interpolation macro
5908f33a025100dea2d951e6d628891fe294b18082Brian */
600dc4eea64f56cc93e5359372b08b99a2d600273cBrian#define LERP(T, A, B)  ( (A) + (T) * ((B) - (A)) )
610dc4eea64f56cc93e5359372b08b99a2d600273cBrian
620dc4eea64f56cc93e5359372b08b99a2d600273cBrian
630dc4eea64f56cc93e5359372b08b99a2d600273cBrian/**
640dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Do 2D/biliner interpolation of float values.
650dc4eea64f56cc93e5359372b08b99a2d600273cBrian * v00, v10, v01 and v11 are typically four texture samples in a square/box.
660dc4eea64f56cc93e5359372b08b99a2d600273cBrian * a and b are the horizontal and vertical interpolants.
670dc4eea64f56cc93e5359372b08b99a2d600273cBrian * It's important that this function is inlined when compiled with
680dc4eea64f56cc93e5359372b08b99a2d600273cBrian * optimization!  If we find that's not true on some systems, convert
690dc4eea64f56cc93e5359372b08b99a2d600273cBrian * to a macro.
700dc4eea64f56cc93e5359372b08b99a2d600273cBrian */
71b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic INLINE float
72b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianlerp_2d(float a, float b,
73b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian        float v00, float v10, float v01, float v11)
740dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
75b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   const float temp0 = LERP(a, v00, v10);
76b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   const float temp1 = LERP(a, v01, v11);
770dc4eea64f56cc93e5359372b08b99a2d600273cBrian   return LERP(b, temp0, temp1);
780dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
790dc4eea64f56cc93e5359372b08b99a2d600273cBrian
800dc4eea64f56cc93e5359372b08b99a2d600273cBrian
810dc4eea64f56cc93e5359372b08b99a2d600273cBrian/**
82906768316d9521a32d9a7eebc9edaf76c06a98a7Brian * If A is a signed integer, A % B doesn't give the right value for A < 0
83906768316d9521a32d9a7eebc9edaf76c06a98a7Brian * (in terms of texture repeat).  Just casting to unsigned fixes that.
840dc4eea64f56cc93e5359372b08b99a2d600273cBrian */
85906768316d9521a32d9a7eebc9edaf76c06a98a7Brian#define REMAINDER(A, B) ((unsigned) (A) % (unsigned) (B))
8608f33a025100dea2d951e6d628891fe294b18082Brian
8708f33a025100dea2d951e6d628891fe294b18082Brian
8808f33a025100dea2d951e6d628891fe294b18082Brian/**
8908f33a025100dea2d951e6d628891fe294b18082Brian * Apply texture coord wrapping mode and return integer texture index.
9008f33a025100dea2d951e6d628891fe294b18082Brian * \param wrapMode  PIPE_TEX_WRAP_x
9108f33a025100dea2d951e6d628891fe294b18082Brian * \param s  the texcoord
9208f33a025100dea2d951e6d628891fe294b18082Brian * \param size  the texture image size
9308f33a025100dea2d951e6d628891fe294b18082Brian * \return  integer texture index
9408f33a025100dea2d951e6d628891fe294b18082Brian */
9570af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwellstatic INLINE int
9670af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwellnearest_texcoord(unsigned wrapMode, float s, unsigned size)
970dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
9870af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   int i;
990dc4eea64f56cc93e5359372b08b99a2d600273cBrian   switch (wrapMode) {
1000dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_WRAP_REPEAT:
10108f33a025100dea2d951e6d628891fe294b18082Brian      /* s limited to [0,1) */
10208f33a025100dea2d951e6d628891fe294b18082Brian      /* i limited to [0,size-1] */
1039935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      i = util_ifloor(s * size);
104906768316d9521a32d9a7eebc9edaf76c06a98a7Brian      i = REMAINDER(i, size);
10508f33a025100dea2d951e6d628891fe294b18082Brian      return i;
1060dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_WRAP_CLAMP:
10708f33a025100dea2d951e6d628891fe294b18082Brian      /* s limited to [0,1] */
10808f33a025100dea2d951e6d628891fe294b18082Brian      /* i limited to [0,size-1] */
10908f33a025100dea2d951e6d628891fe294b18082Brian      if (s <= 0.0F)
11008f33a025100dea2d951e6d628891fe294b18082Brian         i = 0;
11108f33a025100dea2d951e6d628891fe294b18082Brian      else if (s >= 1.0F)
11208f33a025100dea2d951e6d628891fe294b18082Brian         i = size - 1;
11308f33a025100dea2d951e6d628891fe294b18082Brian      else
1149935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul         i = util_ifloor(s * size);
11508f33a025100dea2d951e6d628891fe294b18082Brian      return i;
11608f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
11708f33a025100dea2d951e6d628891fe294b18082Brian      {
11808f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [min,max] */
11908f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [0, size-1] */
120b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = 1.0F / (2.0F * size);
121b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
12208f33a025100dea2d951e6d628891fe294b18082Brian         if (s < min)
12308f33a025100dea2d951e6d628891fe294b18082Brian            i = 0;
12408f33a025100dea2d951e6d628891fe294b18082Brian         else if (s > max)
12508f33a025100dea2d951e6d628891fe294b18082Brian            i = size - 1;
12608f33a025100dea2d951e6d628891fe294b18082Brian         else
1279935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul            i = util_ifloor(s * size);
12808f33a025100dea2d951e6d628891fe294b18082Brian      }
12908f33a025100dea2d951e6d628891fe294b18082Brian      return i;
13008f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
13108f33a025100dea2d951e6d628891fe294b18082Brian      {
13208f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [min,max] */
13308f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [-1, size] */
134b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = -1.0F / (2.0F * size);
135b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
13608f33a025100dea2d951e6d628891fe294b18082Brian         if (s <= min)
13708f33a025100dea2d951e6d628891fe294b18082Brian            i = -1;
13808f33a025100dea2d951e6d628891fe294b18082Brian         else if (s >= max)
13908f33a025100dea2d951e6d628891fe294b18082Brian            i = size;
14008f33a025100dea2d951e6d628891fe294b18082Brian         else
1419935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul            i = util_ifloor(s * size);
14208f33a025100dea2d951e6d628891fe294b18082Brian      }
14308f33a025100dea2d951e6d628891fe294b18082Brian      return i;
14408f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_REPEAT:
14508f33a025100dea2d951e6d628891fe294b18082Brian      {
146b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = 1.0F / (2.0F * size);
147b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
1489935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul         const int flr = util_ifloor(s);
149b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         float u;
15008f33a025100dea2d951e6d628891fe294b18082Brian         if (flr & 1)
151b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian            u = 1.0F - (s - (float) flr);
15208f33a025100dea2d951e6d628891fe294b18082Brian         else
153b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian            u = s - (float) flr;
15408f33a025100dea2d951e6d628891fe294b18082Brian         if (u < min)
15508f33a025100dea2d951e6d628891fe294b18082Brian            i = 0;
15608f33a025100dea2d951e6d628891fe294b18082Brian         else if (u > max)
15708f33a025100dea2d951e6d628891fe294b18082Brian            i = size - 1;
15808f33a025100dea2d951e6d628891fe294b18082Brian         else
1599935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul            i = util_ifloor(u * size);
16008f33a025100dea2d951e6d628891fe294b18082Brian      }
16108f33a025100dea2d951e6d628891fe294b18082Brian      return i;
16208f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP:
16308f33a025100dea2d951e6d628891fe294b18082Brian      {
16408f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [0,1] */
16508f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [0,size-1] */
1669935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul         const float u = fabsf(s);
16708f33a025100dea2d951e6d628891fe294b18082Brian         if (u <= 0.0F)
16808f33a025100dea2d951e6d628891fe294b18082Brian            i = 0;
16908f33a025100dea2d951e6d628891fe294b18082Brian         else if (u >= 1.0F)
17008f33a025100dea2d951e6d628891fe294b18082Brian            i = size - 1;
17108f33a025100dea2d951e6d628891fe294b18082Brian         else
1729935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul            i = util_ifloor(u * size);
17308f33a025100dea2d951e6d628891fe294b18082Brian      }
17408f33a025100dea2d951e6d628891fe294b18082Brian      return i;
17508f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
17608f33a025100dea2d951e6d628891fe294b18082Brian      {
17708f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [min,max] */
17808f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [0, size-1] */
179b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = 1.0F / (2.0F * size);
180b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
1819935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul         const float u = fabsf(s);
18208f33a025100dea2d951e6d628891fe294b18082Brian         if (u < min)
18308f33a025100dea2d951e6d628891fe294b18082Brian            i = 0;
18408f33a025100dea2d951e6d628891fe294b18082Brian         else if (u > max)
18508f33a025100dea2d951e6d628891fe294b18082Brian            i = size - 1;
18608f33a025100dea2d951e6d628891fe294b18082Brian         else
1879935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul            i = util_ifloor(u * size);
18808f33a025100dea2d951e6d628891fe294b18082Brian      }
18908f33a025100dea2d951e6d628891fe294b18082Brian      return i;
19008f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
19108f33a025100dea2d951e6d628891fe294b18082Brian      {
19208f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [min,max] */
19308f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [0, size-1] */
194b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = -1.0F / (2.0F * size);
195b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
1969935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul         const float u = fabsf(s);
19708f33a025100dea2d951e6d628891fe294b18082Brian         if (u < min)
19808f33a025100dea2d951e6d628891fe294b18082Brian            i = -1;
19908f33a025100dea2d951e6d628891fe294b18082Brian         else if (u > max)
20008f33a025100dea2d951e6d628891fe294b18082Brian            i = size;
20108f33a025100dea2d951e6d628891fe294b18082Brian         else
2029935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul            i = util_ifloor(u * size);
20308f33a025100dea2d951e6d628891fe294b18082Brian      }
20408f33a025100dea2d951e6d628891fe294b18082Brian      return i;
2050dc4eea64f56cc93e5359372b08b99a2d600273cBrian   default:
2060dc4eea64f56cc93e5359372b08b99a2d600273cBrian      assert(0);
20708f33a025100dea2d951e6d628891fe294b18082Brian      return 0;
2080dc4eea64f56cc93e5359372b08b99a2d600273cBrian   }
2090dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
2100dc4eea64f56cc93e5359372b08b99a2d600273cBrian
21108f33a025100dea2d951e6d628891fe294b18082Brian
21208f33a025100dea2d951e6d628891fe294b18082Brian/**
21308f33a025100dea2d951e6d628891fe294b18082Brian * Used to compute texel locations for linear sampling.
21408f33a025100dea2d951e6d628891fe294b18082Brian * \param wrapMode  PIPE_TEX_WRAP_x
21508f33a025100dea2d951e6d628891fe294b18082Brian * \param s  the texcoord
21608f33a025100dea2d951e6d628891fe294b18082Brian * \param size  the texture image size
21708f33a025100dea2d951e6d628891fe294b18082Brian * \param i0  returns first texture index
21808f33a025100dea2d951e6d628891fe294b18082Brian * \param i1  returns second texture index (usually *i0 + 1)
21908f33a025100dea2d951e6d628891fe294b18082Brian * \param a  returns blend factor/weight between texture indexes
22008f33a025100dea2d951e6d628891fe294b18082Brian */
2210dc4eea64f56cc93e5359372b08b99a2d600273cBrianstatic INLINE void
22270af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwelllinear_texcoord(unsigned wrapMode, float s, unsigned size,
22370af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell                int *i0, int *i1, float *a)
2240dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
225b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   float u;
2260dc4eea64f56cc93e5359372b08b99a2d600273cBrian   switch (wrapMode) {
2270dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_WRAP_REPEAT:
22808f33a025100dea2d951e6d628891fe294b18082Brian      u = s * size - 0.5F;
2299935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      *i0 = REMAINDER(util_ifloor(u), size);
230906768316d9521a32d9a7eebc9edaf76c06a98a7Brian      *i1 = REMAINDER(*i0 + 1, size);
2310dc4eea64f56cc93e5359372b08b99a2d600273cBrian      break;
2320dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_WRAP_CLAMP:
23308f33a025100dea2d951e6d628891fe294b18082Brian      if (s <= 0.0F)
23408f33a025100dea2d951e6d628891fe294b18082Brian         u = 0.0F;
23508f33a025100dea2d951e6d628891fe294b18082Brian      else if (s >= 1.0F)
236b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         u = (float) size;
23708f33a025100dea2d951e6d628891fe294b18082Brian      else
23808f33a025100dea2d951e6d628891fe294b18082Brian         u = s * size;
23908f33a025100dea2d951e6d628891fe294b18082Brian      u -= 0.5F;
2409935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      *i0 = util_ifloor(u);
24108f33a025100dea2d951e6d628891fe294b18082Brian      *i1 = *i0 + 1;
24208f33a025100dea2d951e6d628891fe294b18082Brian      break;
24308f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
24408f33a025100dea2d951e6d628891fe294b18082Brian      if (s <= 0.0F)
24508f33a025100dea2d951e6d628891fe294b18082Brian         u = 0.0F;
24608f33a025100dea2d951e6d628891fe294b18082Brian      else if (s >= 1.0F)
247b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         u = (float) size;
24808f33a025100dea2d951e6d628891fe294b18082Brian      else
24908f33a025100dea2d951e6d628891fe294b18082Brian         u = s * size;
25008f33a025100dea2d951e6d628891fe294b18082Brian      u -= 0.5F;
2519935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      *i0 = util_ifloor(u);
25208f33a025100dea2d951e6d628891fe294b18082Brian      *i1 = *i0 + 1;
25308f33a025100dea2d951e6d628891fe294b18082Brian      if (*i0 < 0)
25408f33a025100dea2d951e6d628891fe294b18082Brian         *i0 = 0;
25570af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell      if (*i1 >= (int) size)
25608f33a025100dea2d951e6d628891fe294b18082Brian         *i1 = size - 1;
25708f33a025100dea2d951e6d628891fe294b18082Brian      break;
25808f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
25908f33a025100dea2d951e6d628891fe294b18082Brian      {
260b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = -1.0F / (2.0F * size);
261b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
26208f33a025100dea2d951e6d628891fe294b18082Brian         if (s <= min)
26308f33a025100dea2d951e6d628891fe294b18082Brian            u = min * size;
26408f33a025100dea2d951e6d628891fe294b18082Brian         else if (s >= max)
26508f33a025100dea2d951e6d628891fe294b18082Brian            u = max * size;
26608f33a025100dea2d951e6d628891fe294b18082Brian         else
26708f33a025100dea2d951e6d628891fe294b18082Brian            u = s * size;
26808f33a025100dea2d951e6d628891fe294b18082Brian         u -= 0.5F;
2699935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul         *i0 = util_ifloor(u);
27008f33a025100dea2d951e6d628891fe294b18082Brian         *i1 = *i0 + 1;
27108f33a025100dea2d951e6d628891fe294b18082Brian      }
27208f33a025100dea2d951e6d628891fe294b18082Brian      break;
27308f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_REPEAT:
27408f33a025100dea2d951e6d628891fe294b18082Brian      {
2759935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul         const int flr = util_ifloor(s);
27608f33a025100dea2d951e6d628891fe294b18082Brian         if (flr & 1)
277b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian            u = 1.0F - (s - (float) flr);
27808f33a025100dea2d951e6d628891fe294b18082Brian         else
279b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian            u = s - (float) flr;
28008f33a025100dea2d951e6d628891fe294b18082Brian         u = (u * size) - 0.5F;
2819935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul         *i0 = util_ifloor(u);
28208f33a025100dea2d951e6d628891fe294b18082Brian         *i1 = *i0 + 1;
28308f33a025100dea2d951e6d628891fe294b18082Brian         if (*i0 < 0)
28408f33a025100dea2d951e6d628891fe294b18082Brian            *i0 = 0;
28570af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell         if (*i1 >= (int) size)
28608f33a025100dea2d951e6d628891fe294b18082Brian            *i1 = size - 1;
28708f33a025100dea2d951e6d628891fe294b18082Brian      }
28808f33a025100dea2d951e6d628891fe294b18082Brian      break;
28908f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP:
2909935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      u = fabsf(s);
29108f33a025100dea2d951e6d628891fe294b18082Brian      if (u >= 1.0F)
292b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         u = (float) size;
29308f33a025100dea2d951e6d628891fe294b18082Brian      else
29408f33a025100dea2d951e6d628891fe294b18082Brian         u *= size;
29508f33a025100dea2d951e6d628891fe294b18082Brian      u -= 0.5F;
2969935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      *i0 = util_ifloor(u);
29708f33a025100dea2d951e6d628891fe294b18082Brian      *i1 = *i0 + 1;
29808f33a025100dea2d951e6d628891fe294b18082Brian      break;
29908f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
3009935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      u = fabsf(s);
30108f33a025100dea2d951e6d628891fe294b18082Brian      if (u >= 1.0F)
302b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         u = (float) size;
30308f33a025100dea2d951e6d628891fe294b18082Brian      else
30408f33a025100dea2d951e6d628891fe294b18082Brian         u *= size;
30508f33a025100dea2d951e6d628891fe294b18082Brian      u -= 0.5F;
3069935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      *i0 = util_ifloor(u);
30708f33a025100dea2d951e6d628891fe294b18082Brian      *i1 = *i0 + 1;
30808f33a025100dea2d951e6d628891fe294b18082Brian      if (*i0 < 0)
30908f33a025100dea2d951e6d628891fe294b18082Brian         *i0 = 0;
31070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell      if (*i1 >= (int) size)
31108f33a025100dea2d951e6d628891fe294b18082Brian         *i1 = size - 1;
31208f33a025100dea2d951e6d628891fe294b18082Brian      break;
31308f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
31408f33a025100dea2d951e6d628891fe294b18082Brian      {
315b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = -1.0F / (2.0F * size);
316b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
3179935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul         u = fabsf(s);
31808f33a025100dea2d951e6d628891fe294b18082Brian         if (u <= min)
31908f33a025100dea2d951e6d628891fe294b18082Brian            u = min * size;
32008f33a025100dea2d951e6d628891fe294b18082Brian         else if (u >= max)
32108f33a025100dea2d951e6d628891fe294b18082Brian            u = max * size;
32208f33a025100dea2d951e6d628891fe294b18082Brian         else
32308f33a025100dea2d951e6d628891fe294b18082Brian            u *= size;
32408f33a025100dea2d951e6d628891fe294b18082Brian         u -= 0.5F;
3259935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul         *i0 = util_ifloor(u);
32608f33a025100dea2d951e6d628891fe294b18082Brian         *i1 = *i0 + 1;
32708f33a025100dea2d951e6d628891fe294b18082Brian      }
3280dc4eea64f56cc93e5359372b08b99a2d600273cBrian      break;
3290dc4eea64f56cc93e5359372b08b99a2d600273cBrian   default:
3300dc4eea64f56cc93e5359372b08b99a2d600273cBrian      assert(0);
3310dc4eea64f56cc93e5359372b08b99a2d600273cBrian   }
33208f33a025100dea2d951e6d628891fe294b18082Brian   *a = FRAC(u);
3330dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
3340dc4eea64f56cc93e5359372b08b99a2d600273cBrian
3350dc4eea64f56cc93e5359372b08b99a2d600273cBrian
336b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian/**
337b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * For RECT textures / unnormalized texcoords
338b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * Only a subset of wrap modes supported.
339b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian */
340b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrianstatic INLINE int
341b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBriannearest_texcoord_unnorm(unsigned wrapMode, float s, unsigned size)
342b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{
343b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   int i;
344b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   switch (wrapMode) {
345b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP:
3469935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      i = util_ifloor(s);
34769a7c9739bc0f11e66e11ab410d813fa69fe5fc9Michal Krol      return CLAMP(i, 0, (int) size-1);
348b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
349b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      /* fall-through */
350b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
3519935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      return util_ifloor( CLAMP(s, 0.5F, (float) size - 0.5F) );
352b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   default:
353b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      assert(0);
354b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      return 0;
355b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   }
356b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian}
357b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
358b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
359b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian/**
360b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * For RECT textures / unnormalized texcoords.
361b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * Only a subset of wrap modes supported.
362b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian */
363b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrianstatic INLINE void
364b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrianlinear_texcoord_unnorm(unsigned wrapMode, float s, unsigned size,
365b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                       int *i0, int *i1, float *a)
366b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{
367b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   switch (wrapMode) {
368b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP:
369b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      /* Not exactly what the spec says, but it matches NVIDIA output */
37069a7c9739bc0f11e66e11ab410d813fa69fe5fc9Michal Krol      s = CLAMP(s - 0.5F, 0.0f, (float) size - 1.0f);
3719935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      *i0 = util_ifloor(s);
372b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      *i1 = *i0 + 1;
373b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      break;
374b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
375b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      /* fall-through */
376b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
3774ec46e4869b60b60c7ddf43168604713b5c4c359Brian      s = CLAMP(s, 0.5F, (float) size - 0.5F);
378b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      s -= 0.5F;
3799935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      *i0 = util_ifloor(s);
380b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      *i1 = *i0 + 1;
38169a7c9739bc0f11e66e11ab410d813fa69fe5fc9Michal Krol      if (*i1 > (int) size - 1)
382b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         *i1 = size - 1;
383b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      break;
384b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   default:
385b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      assert(0);
386b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   }
387b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   *a = FRAC(s);
388b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian}
389b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
390b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
39170af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwellstatic unsigned
392a34b8594b7b2d00404bb639621ec1ce918ba0786Brianchoose_cube_face(float rx, float ry, float rz, float *newS, float *newT)
39334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
39434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   /*
39534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      major axis
39634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      direction     target                             sc     tc    ma
39734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      ----------    -------------------------------    ---    ---   ---
39834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       +rx          TEXTURE_CUBE_MAP_POSITIVE_X_EXT    -rz    -ry   rx
39934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       -rx          TEXTURE_CUBE_MAP_NEGATIVE_X_EXT    +rz    -ry   rx
40034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       +ry          TEXTURE_CUBE_MAP_POSITIVE_Y_EXT    +rx    +rz   ry
40134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       -ry          TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT    +rx    -rz   ry
40234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       +rz          TEXTURE_CUBE_MAP_POSITIVE_Z_EXT    +rx    -ry   rz
40334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       -rz          TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT    -rx    -ry   rz
40434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   */
4059935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul   const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz);
40670af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   unsigned face;
407b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   float sc, tc, ma;
40834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
40934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   if (arx > ary && arx > arz) {
41034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      if (rx >= 0.0F) {
41134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_POS_X;
41234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = -rz;
41334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
41434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arx;
41534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
41634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      else {
41734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_NEG_X;
41834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rz;
41934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
42034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arx;
42134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
42234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
42334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   else if (ary > arx && ary > arz) {
42434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      if (ry >= 0.0F) {
42534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_POS_Y;
42634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rx;
42734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = rz;
42834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = ary;
42934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
43034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      else {
43134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_NEG_Y;
43234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rx;
43334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -rz;
43434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = ary;
43534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
43634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
43734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   else {
43834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      if (rz > 0.0F) {
43934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_POS_Z;
44034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rx;
44134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
44234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arz;
44334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
44434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      else {
44534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_NEG_Z;
44634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = -rx;
44734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
44834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arz;
44934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
45034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
45134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
452a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   *newS = ( sc / ma + 1.0F ) * 0.5F;
453a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   *newT = ( tc / ma + 1.0F ) * 0.5F;
45434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
45534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   return face;
45634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
45734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
45834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
459b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/**
460b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * Examine the quad's texture coordinates to compute the partial
461b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * derivatives w.r.t X and Y, then compute lambda (level of detail).
462b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian *
463b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * This is only done for fragment shaders, not vertex shaders.
464b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian */
465b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic float
466b4480285ed5098f1c862690ee105dd46f5e6cd1eBriancompute_lambda(struct tgsi_sampler *sampler,
467b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float s[QUAD_SIZE],
468b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float t[QUAD_SIZE],
469f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian               const float p[QUAD_SIZE],
470f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian               float lodbias)
471b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian{
472b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   float rho, lambda;
473b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
474b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   assert(sampler->state->normalized_coords);
475b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
476b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   assert(s);
477b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   {
478b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dsdx = s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT];
479b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dsdy = s[QUAD_TOP_LEFT]     - s[QUAD_BOTTOM_LEFT];
4809935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      dsdx = fabsf(dsdx);
4819935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      dsdy = fabsf(dsdy);
482b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      rho = MAX2(dsdx, dsdy) * sampler->texture->width[0];
483b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
484b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   if (t) {
485b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT];
486b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dtdy = t[QUAD_TOP_LEFT]     - t[QUAD_BOTTOM_LEFT];
487b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float max;
4889935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      dtdx = fabsf(dtdx);
4899935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      dtdy = fabsf(dtdy);
490b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      max = MAX2(dtdx, dtdy) * sampler->texture->height[0];
491b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      rho = MAX2(rho, max);
492b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
493b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   if (p) {
494b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dpdx = p[QUAD_BOTTOM_RIGHT] - p[QUAD_BOTTOM_LEFT];
495b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dpdy = p[QUAD_TOP_LEFT]     - p[QUAD_BOTTOM_LEFT];
496b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float max;
4979935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      dpdx = fabsf(dpdx);
4989935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      dpdy = fabsf(dpdy);
499b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      max = MAX2(dpdx, dpdy) * sampler->texture->depth[0];
500b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      rho = MAX2(rho, max);
501b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
502b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
5031a46dcc8a927dfb38ca1381e7b3dafb789f8257cBrian Paul   lambda = util_fast_log2(rho);
504f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian   lambda += lodbias + sampler->state->lod_bias;
505b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   lambda = CLAMP(lambda, sampler->state->min_lod, sampler->state->max_lod);
506b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
507b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   return lambda;
508b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian}
509b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
510b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
511f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian/**
512c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * Do several things here:
513c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 1. Compute lambda from the texcoords, if needed
514c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 2. Determine if we're minifying or magnifying
515c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 3. If minifying, choose mipmap levels
516c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 4. Return image filter to use within mipmap images
517f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian */
518f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrianstatic void
519c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brianchoose_mipmap_levels(struct tgsi_sampler *sampler,
520c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     const float s[QUAD_SIZE],
521c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     const float t[QUAD_SIZE],
522c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     const float p[QUAD_SIZE],
523c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     float lodbias,
524c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     unsigned *level0, unsigned *level1, float *levelBlend,
525c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     unsigned *imgFilter)
52609a1b912605ff48c8782dcc5aae55ac77e27037bBrian{
527c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian   if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) {
528c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      /* no mipmap selection needed */
5290c6bbd41bd6dc1041eaca7c907d3768d107c1afaBrian      *level0 = *level1 = CLAMP((int) sampler->state->min_lod,
5300c6bbd41bd6dc1041eaca7c907d3768d107c1afaBrian                                0, (int) sampler->texture->last_level);
53108c9534107fcaf06f9b801551524ed5dc724db13Brian
53208c9534107fcaf06f9b801551524ed5dc724db13Brian      if (sampler->state->min_img_filter != sampler->state->mag_img_filter) {
53308c9534107fcaf06f9b801551524ed5dc724db13Brian         /* non-mipmapped texture, but still need to determine if doing
53408c9534107fcaf06f9b801551524ed5dc724db13Brian          * minification or magnification.
53508c9534107fcaf06f9b801551524ed5dc724db13Brian          */
53608c9534107fcaf06f9b801551524ed5dc724db13Brian         float lambda = compute_lambda(sampler, s, t, p, lodbias);
5373b2a291888d8e62787de03f8529806fb562bd186Brian         if (lambda <= 0.0) {
53808c9534107fcaf06f9b801551524ed5dc724db13Brian            *imgFilter = sampler->state->mag_img_filter;
53908c9534107fcaf06f9b801551524ed5dc724db13Brian         }
54008c9534107fcaf06f9b801551524ed5dc724db13Brian         else {
54108c9534107fcaf06f9b801551524ed5dc724db13Brian            *imgFilter = sampler->state->min_img_filter;
54208c9534107fcaf06f9b801551524ed5dc724db13Brian         }
54308c9534107fcaf06f9b801551524ed5dc724db13Brian      }
5443b2a291888d8e62787de03f8529806fb562bd186Brian      else {
5453b2a291888d8e62787de03f8529806fb562bd186Brian         *imgFilter = sampler->state->mag_img_filter;
5463b2a291888d8e62787de03f8529806fb562bd186Brian      }
547c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian   }
548c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian   else {
549c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      float lambda;
550c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian
551c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      if (1)
552c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* fragment shader */
553c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         lambda = compute_lambda(sampler, s, t, p, lodbias);
554c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      else
555c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* vertex shader */
556c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         lambda = lodbias; /* not really a bias, but absolute LOD */
557c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian
5583b2a291888d8e62787de03f8529806fb562bd186Brian      if (lambda <= 0.0) { /* XXX threshold depends on the filter */
559c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* magnifying */
560c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         *imgFilter = sampler->state->mag_img_filter;
5614da1cdf78fa3b954840650fa46cf72da5daf149fBrian         *level0 = *level1 = 0;
562f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      }
563c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      else {
564c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* minifying */
565c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         *imgFilter = sampler->state->min_img_filter;
566c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian
567c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* choose mipmap level(s) and compute the blend factor between them */
568c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NEAREST) {
569c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            /* Nearest mipmap level */
570c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            const int lvl = (int) (lambda + 0.5);
571c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            *level0 =
5724da1cdf78fa3b954840650fa46cf72da5daf149fBrian            *level1 = CLAMP(lvl, 0, (int) sampler->texture->last_level);
573c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         }
574c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         else {
575c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            /* Linear interpolation between mipmap levels */
576c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            const int lvl = (int) lambda;
5774da1cdf78fa3b954840650fa46cf72da5daf149fBrian            *level0 = CLAMP(lvl,     0, (int) sampler->texture->last_level);
5784da1cdf78fa3b954840650fa46cf72da5daf149fBrian            *level1 = CLAMP(lvl + 1, 0, (int) sampler->texture->last_level);
579c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            *levelBlend = FRAC(lambda);  /* blending weight between levels */
580c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         }
581f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      }
58209a1b912605ff48c8782dcc5aae55ac77e27037bBrian   }
58309a1b912605ff48c8782dcc5aae55ac77e27037bBrian}
58409a1b912605ff48c8782dcc5aae55ac77e27037bBrian
58508f33a025100dea2d951e6d628891fe294b18082Brian
586b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/**
587a13de2464dd034ff117f9314df5757d068cae8e5Brian * Get a texel from a texture, using the texture tile cache.
588a13de2464dd034ff117f9314df5757d068cae8e5Brian *
589b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param face  the cube face in 0..5
590b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param level  the mipmap level
591b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param x  the x coord of texel within 2D image
592b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param y  the y coord of texel within 2D image
59370eb7996f265f3634dabda078f13d1be3533cc65Brian * \param z  which slice of a 3D texture
594b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param rgba  the quad to put the texel/color into
595b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param j  which element of the rgba quad to write to
59670eb7996f265f3634dabda078f13d1be3533cc65Brian *
59770eb7996f265f3634dabda078f13d1be3533cc65Brian * XXX maybe move this into sp_tile_cache.c and merge with the
59870eb7996f265f3634dabda078f13d1be3533cc65Brian * sp_get_cached_tile_tex() function.  Also, get 4 texels instead of 1...
599b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian */
600b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic void
601b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianget_texel(struct tgsi_sampler *sampler,
60270eb7996f265f3634dabda078f13d1be3533cc65Brian          unsigned face, unsigned level, int x, int y, int z,
603a13de2464dd034ff117f9314df5757d068cae8e5Brian          float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j)
604b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian{
605d50d7a54de89e602a9951264878dfe06924e1adbMichal Krol   if (x < 0 || x >= (int) sampler->texture->width[level] ||
606d50d7a54de89e602a9951264878dfe06924e1adbMichal Krol       y < 0 || y >= (int) sampler->texture->height[level] ||
607d50d7a54de89e602a9951264878dfe06924e1adbMichal Krol       z < 0 || z >= (int) sampler->texture->depth[level]) {
608ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul      rgba[0][j] = sampler->state->border_color[0];
609ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul      rgba[1][j] = sampler->state->border_color[1];
610ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul      rgba[2][j] = sampler->state->border_color[2];
611ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul      rgba[3][j] = sampler->state->border_color[3];
612ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul   }
613ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul   else {
614ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul      const int tx = x % TILE_SIZE;
615ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul      const int ty = y % TILE_SIZE;
616ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul      const struct softpipe_cached_tile *tile
617ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul         = sp_get_cached_tile_tex(sampler->pipe, sampler->cache,
618ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul                                  x, y, z, face, level);
619ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul      rgba[0][j] = tile->data.color[ty][tx][0];
620ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul      rgba[1][j] = tile->data.color[ty][tx][1];
621ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul      rgba[2][j] = tile->data.color[ty][tx][2];
622ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul      rgba[3][j] = tile->data.color[ty][tx][3];
623b1ff7dac537947d412bf423a73e7eacd76f90d84Brian Paul      if (0)
624b1ff7dac537947d412bf423a73e7eacd76f90d84Brian Paul      {
625ae2195caf56d2eb782475254c68858a25ee7c857Brian Paul         debug_printf("Get texel %f %f %f %f from %s\n",
6268fb55dab783f2de5111e7440093e1458fce5fb3dBrian Paul                      rgba[0][j], rgba[1][j], rgba[2][j], rgba[3][j],
6278fb55dab783f2de5111e7440093e1458fce5fb3dBrian Paul                      pf_name(sampler->texture->format));
628b1ff7dac537947d412bf423a73e7eacd76f90d84Brian Paul      }
629ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul   }
630b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian}
631b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
632b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
6333d8c05f7320151898dd224c1daaf3118e1f7ea34Brian/**
6343d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * Compare texcoord 'p' (aka R) against texture value 'rgba[0]'
6353d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * When we sampled the depth texture, the depth value was put into all
6363d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * RGBA channels.  We look at the red channel here.
6373d8c05f7320151898dd224c1daaf3118e1f7ea34Brian */
6383d8c05f7320151898dd224c1daaf3118e1f7ea34Brianstatic INLINE void
6393d8c05f7320151898dd224c1daaf3118e1f7ea34Brianshadow_compare(uint compare_func,
6403d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               float rgba[NUM_CHANNELS][QUAD_SIZE],
6413d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               const float p[QUAD_SIZE],
6423d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               uint j)
6433d8c05f7320151898dd224c1daaf3118e1f7ea34Brian{
6443d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   int k;
6453d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   switch (compare_func) {
6463d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_LESS:
6473d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] < rgba[0][j];
6483d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
6493d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_LEQUAL:
6503d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] <= rgba[0][j];
6513d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
6523d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_GREATER:
6533d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] > rgba[0][j];
6543d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
6553d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_GEQUAL:
6563d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] >= rgba[0][j];
6573d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
6583d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_EQUAL:
6593d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] == rgba[0][j];
6603d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
6613d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_NOTEQUAL:
6623d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] != rgba[0][j];
6633d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
6643d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_ALWAYS:
6653d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = 1;
6663d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
6673d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_NEVER:
6683d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = 0;
6693d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
6703d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   default:
671f9b1d47d652778012fd35552ffc51717ac0b6f79Keith Whitwell      k = 0;
6723d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      assert(0);
673f9b1d47d652778012fd35552ffc51717ac0b6f79Keith Whitwell      break;
6743d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   }
6753d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
6763d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   rgba[0][j] = rgba[1][j] = rgba[2][j] = (float) k;
6773d8c05f7320151898dd224c1daaf3118e1f7ea34Brian}
6783d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
679b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
680b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/**
681a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Common code for sampling 1D/2D/cube textures.
682a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Could probably extend for 3D...
6830dc4eea64f56cc93e5359372b08b99a2d600273cBrian */
684e12810d92ffb3547680b227bf88937c03018112bBrianstatic void
685a34b8594b7b2d00404bb639621ec1ce918ba0786Briansp_get_samples_2d_common(struct tgsi_sampler *sampler,
686a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         const float s[QUAD_SIZE],
687a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         const float t[QUAD_SIZE],
688a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         const float p[QUAD_SIZE],
689a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         float lodbias,
690a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         float rgba[NUM_CHANNELS][QUAD_SIZE],
691a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         const unsigned faces[4])
6920dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
6933d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   const uint compare_func = sampler->state->compare_func;
694f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian   unsigned level0, level1, j, imgFilter;
695f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian   int width, height;
696c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian   float levelBlend;
697a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
698c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian   choose_mipmap_levels(sampler, s, t, p, lodbias,
699c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                        &level0, &level1, &levelBlend, &imgFilter);
70009a1b912605ff48c8782dcc5aae55ac77e27037bBrian
701b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   assert(sampler->state->normalized_coords);
702b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
703b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   width = sampler->texture->width[level0];
704b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   height = sampler->texture->height[level0];
70509a1b912605ff48c8782dcc5aae55ac77e27037bBrian
706b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   assert(width > 0);
707612cfb749c3526eeb446bbc631bf24716522f373Brian
708b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   switch (imgFilter) {
7090dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_FILTER_NEAREST:
710b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      for (j = 0; j < QUAD_SIZE; j++) {
711b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         int x = nearest_texcoord(sampler->state->wrap_s, s[j], width);
712b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         int y = nearest_texcoord(sampler->state->wrap_t, t[j], height);
713df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, faces[j], level0, x, y, 0, rgba, j);
7143d8c05f7320151898dd224c1daaf3118e1f7ea34Brian         if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
7153d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            shadow_compare(compare_func, rgba, p, j);
7163d8c05f7320151898dd224c1daaf3118e1f7ea34Brian         }
717f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian
718f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian         if (level0 != level1) {
719f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            /* get texels from second mipmap level and blend */
720f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            float rgba2[4][4];
721f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            unsigned c;
722f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            x = x / 2;
723f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            y = y / 2;
724df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, faces[j], level1, x, y, 0, rgba2, j);
7253d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
7263d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               shadow_compare(compare_func, rgba2, p, j);
7273d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            }
7283d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
729f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            for (c = 0; c < NUM_CHANNELS; c++) {
73017c2f56dc3f2f58ba89d8e305e7d9b423e3cae16Brian               rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]);
731f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            }
732f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian         }
7330dc4eea64f56cc93e5359372b08b99a2d600273cBrian      }
7340dc4eea64f56cc93e5359372b08b99a2d600273cBrian      break;
7350dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_FILTER_LINEAR:
73698ae83d5cc73b61826823c915b5c59746c2e85c7Keith Whitwell   case PIPE_TEX_FILTER_ANISO:
737b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      for (j = 0; j < QUAD_SIZE; j++) {
738b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         float tx[4][4], a, b;
739b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         int x0, y0, x1, y1, c;
740b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         linear_texcoord(sampler->state->wrap_s, s[j], width,  &x0, &x1, &a);
741b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         linear_texcoord(sampler->state->wrap_t, t[j], height, &y0, &y1, &b);
742df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, faces[j], level0, x0, y0, 0, tx, 0);
743df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, faces[j], level0, x1, y0, 0, tx, 1);
744df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, faces[j], level0, x0, y1, 0, tx, 2);
745df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, faces[j], level0, x1, y1, 0, tx, 3);
7463d8c05f7320151898dd224c1daaf3118e1f7ea34Brian         if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
7473d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            shadow_compare(compare_func, tx, p, 0);
7483d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            shadow_compare(compare_func, tx, p, 1);
7493d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            shadow_compare(compare_func, tx, p, 2);
7503d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            shadow_compare(compare_func, tx, p, 3);
7513d8c05f7320151898dd224c1daaf3118e1f7ea34Brian         }
7523d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
753b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         for (c = 0; c < 4; c++) {
754b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian            rgba[c][j] = lerp_2d(a, b, tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
755b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         }
756f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian
757f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian         if (level0 != level1) {
758f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            /* get texels from second mipmap level and blend */
759f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            float rgba2[4][4];
760f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            x0 = x0 / 2;
761f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            y0 = y0 / 2;
762f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            x1 = x1 / 2;
763f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            y1 = y1 / 2;
764df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, faces[j], level1, x0, y0, 0, tx, 0);
765df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, faces[j], level1, x1, y0, 0, tx, 1);
766df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, faces[j], level1, x0, y1, 0, tx, 2);
767df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, faces[j], level1, x1, y1, 0, tx, 3);
7683d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
7693d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               shadow_compare(compare_func, tx, p, 0);
7703d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               shadow_compare(compare_func, tx, p, 1);
7713d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               shadow_compare(compare_func, tx, p, 2);
7723d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               shadow_compare(compare_func, tx, p, 3);
7733d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            }
7743d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
775f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            for (c = 0; c < 4; c++) {
776f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian               rgba2[c][j] = lerp_2d(a, b,
777f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian                                     tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
778f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            }
779f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian
780f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            for (c = 0; c < NUM_CHANNELS; c++) {
781c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian               rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]);
782f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            }
783f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian         }
78409a1b912605ff48c8782dcc5aae55ac77e27037bBrian      }
78509a1b912605ff48c8782dcc5aae55ac77e27037bBrian      break;
7860dc4eea64f56cc93e5359372b08b99a2d600273cBrian   default:
7870dc4eea64f56cc93e5359372b08b99a2d600273cBrian      assert(0);
7880dc4eea64f56cc93e5359372b08b99a2d600273cBrian   }
7890dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
79034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
79134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
79234a48abd5ff82ce9748fc29191e35a0985d47c5fBrianstatic void
793a34b8594b7b2d00404bb639621ec1ce918ba0786Briansp_get_samples_1d(struct tgsi_sampler *sampler,
794a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float s[QUAD_SIZE],
795a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float t[QUAD_SIZE],
796a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float p[QUAD_SIZE],
797a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  float lodbias,
798a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  float rgba[NUM_CHANNELS][QUAD_SIZE])
799a34b8594b7b2d00404bb639621ec1ce918ba0786Brian{
800a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   static const unsigned faces[4] = {0, 0, 0, 0};
801d16b4bc32a731cb6ae320e8c187af3bc751d4138Brian   static const float tzero[4] = {0, 0, 0, 0};
802d16b4bc32a731cb6ae320e8c187af3bc751d4138Brian   sp_get_samples_2d_common(sampler, s, tzero, NULL, lodbias, rgba, faces);
803a34b8594b7b2d00404bb639621ec1ce918ba0786Brian}
804a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
805a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
806a34b8594b7b2d00404bb639621ec1ce918ba0786Brianstatic void
807a34b8594b7b2d00404bb639621ec1ce918ba0786Briansp_get_samples_2d(struct tgsi_sampler *sampler,
808a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float s[QUAD_SIZE],
809a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float t[QUAD_SIZE],
810a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float p[QUAD_SIZE],
811a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  float lodbias,
812a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  float rgba[NUM_CHANNELS][QUAD_SIZE])
813a34b8594b7b2d00404bb639621ec1ce918ba0786Brian{
814a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   static const unsigned faces[4] = {0, 0, 0, 0};
8153d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   sp_get_samples_2d_common(sampler, s, t, p, lodbias, rgba, faces);
816a34b8594b7b2d00404bb639621ec1ce918ba0786Brian}
817a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
818a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
819a34b8594b7b2d00404bb639621ec1ce918ba0786Brianstatic void
820b4480285ed5098f1c862690ee105dd46f5e6cd1eBriansp_get_samples_3d(struct tgsi_sampler *sampler,
821b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  const float s[QUAD_SIZE],
822b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  const float t[QUAD_SIZE],
823b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  const float p[QUAD_SIZE],
824f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian                  float lodbias,
825b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  float rgba[NUM_CHANNELS][QUAD_SIZE])
82634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
82734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   /* get/map pipe_surfaces corresponding to 3D tex slices */
8283d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   unsigned level0, level1, j, imgFilter;
8293d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   int width, height, depth;
8303d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   float levelBlend;
8313d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   const uint face = 0;
8323d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
8333d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   choose_mipmap_levels(sampler, s, t, p, lodbias,
8343d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                        &level0, &level1, &levelBlend, &imgFilter);
8353d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
836b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   assert(sampler->state->normalized_coords);
837b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
838b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   width = sampler->texture->width[level0];
839b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   height = sampler->texture->height[level0];
840b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   depth = sampler->texture->depth[level0];
8413d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
8423d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   assert(width > 0);
8433d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   assert(height > 0);
8443d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   assert(depth > 0);
8453d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
8463d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   switch (imgFilter) {
8473d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   case PIPE_TEX_FILTER_NEAREST:
8483d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      for (j = 0; j < QUAD_SIZE; j++) {
8493d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         int x = nearest_texcoord(sampler->state->wrap_s, s[j], width);
8503d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         int y = nearest_texcoord(sampler->state->wrap_t, t[j], height);
8513d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         int z = nearest_texcoord(sampler->state->wrap_r, p[j], depth);
852df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, face, level0, x, y, z, rgba, j);
8533d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
8543d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         if (level0 != level1) {
8553d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            /* get texels from second mipmap level and blend */
8563d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            float rgba2[4][4];
8573d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            unsigned c;
8583d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            x /= 2;
8593d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            y /= 2;
8603d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            z /= 2;
861df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, face, level1, x, y, z, rgba2, j);
8623d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            for (c = 0; c < NUM_CHANNELS; c++) {
8633d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian               rgba[c][j] = LERP(levelBlend, rgba2[c][j], rgba[c][j]);
8643d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            }
8653d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         }
8663d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      }
8673d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      break;
8683d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   case PIPE_TEX_FILTER_LINEAR:
86998ae83d5cc73b61826823c915b5c59746c2e85c7Keith Whitwell   case PIPE_TEX_FILTER_ANISO:
8703d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      for (j = 0; j < QUAD_SIZE; j++) {
871df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         float texel0[4][4], texel1[4][4];
872df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         float xw, yw, zw; /* interpolation weights */
8733d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         int x0, x1, y0, y1, z0, z1, c;
8743d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         linear_texcoord(sampler->state->wrap_s, s[j], width,  &x0, &x1, &xw);
8753d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         linear_texcoord(sampler->state->wrap_t, t[j], height, &y0, &y1, &yw);
8763d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         linear_texcoord(sampler->state->wrap_r, p[j], depth,  &z0, &z1, &zw);
877df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, face, level0, x0, y0, z0, texel0, 0);
878df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, face, level0, x1, y0, z0, texel0, 1);
879df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, face, level0, x0, y1, z0, texel0, 2);
880df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, face, level0, x1, y1, z0, texel0, 3);
881df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, face, level0, x0, y0, z1, texel1, 0);
882df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, face, level0, x1, y0, z1, texel1, 1);
883df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, face, level0, x0, y1, z1, texel1, 2);
884df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, face, level0, x1, y1, z1, texel1, 3);
8853d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
8863d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         /* 3D lerp */
8873d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         for (c = 0; c < 4; c++) {
8883d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            float ctemp0[4][4], ctemp1[4][4];
8893d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            ctemp0[c][j] = lerp_2d(xw, yw,
8903d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                                   texel0[c][0], texel0[c][1],
8913d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                                   texel0[c][2], texel0[c][3]);
8923d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            ctemp1[c][j] = lerp_2d(xw, yw,
8933d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                                   texel1[c][0], texel1[c][1],
8943d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                                   texel1[c][2], texel1[c][3]);
8953d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            rgba[c][j] = LERP(zw, ctemp0[c][j], ctemp1[c][j]);
8963d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         }
8973d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
8983d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         if (level0 != level1) {
8993d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            /* get texels from second mipmap level and blend */
9003d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            float rgba2[4][4];
9013d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            x0 /= 2;
9023d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            y0 /= 2;
9033d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            z0 /= 2;
9043d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            x1 /= 2;
9053d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            y1 /= 2;
9063d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            z1 /= 2;
907df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, face, level1, x0, y0, z0, texel0, 0);
908df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, face, level1, x1, y0, z0, texel0, 1);
909df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, face, level1, x0, y1, z0, texel0, 2);
910df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, face, level1, x1, y1, z0, texel0, 3);
911df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, face, level1, x0, y0, z1, texel1, 0);
912df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, face, level1, x1, y0, z1, texel1, 1);
913df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, face, level1, x0, y1, z1, texel1, 2);
914df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, face, level1, x1, y1, z1, texel1, 3);
9153d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
9163d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            /* 3D lerp */
9173d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            for (c = 0; c < 4; c++) {
9183d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian               float ctemp0[4][4], ctemp1[4][4];
9193d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian               ctemp0[c][j] = lerp_2d(xw, yw,
9203d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                                      texel0[c][0], texel0[c][1],
9213d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                                      texel0[c][2], texel0[c][3]);
9223d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian               ctemp1[c][j] = lerp_2d(xw, yw,
9233d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                                      texel1[c][0], texel1[c][1],
9243d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                                      texel1[c][2], texel1[c][3]);
9253d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian               rgba2[c][j] = LERP(zw, ctemp0[c][j], ctemp1[c][j]);
9263d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            }
9273d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
9283d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            /* blend mipmap levels */
9293d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            for (c = 0; c < NUM_CHANNELS; c++) {
9303d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian               rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]);
9313d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            }
9323d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         }
9333d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      }
9343d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      break;
9353d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   default:
9363d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      assert(0);
9373d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   }
93834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
93934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
94034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
94134a48abd5ff82ce9748fc29191e35a0985d47c5fBrianstatic void
942b4480285ed5098f1c862690ee105dd46f5e6cd1eBriansp_get_samples_cube(struct tgsi_sampler *sampler,
943b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                    const float s[QUAD_SIZE],
944b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                    const float t[QUAD_SIZE],
945b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                    const float p[QUAD_SIZE],
946f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian                    float lodbias,
947b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                    float rgba[NUM_CHANNELS][QUAD_SIZE])
94834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
949a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   unsigned faces[QUAD_SIZE], j;
950a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   float ssss[4], tttt[4];
951b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   for (j = 0; j < QUAD_SIZE; j++) {
952a34b8594b7b2d00404bb639621ec1ce918ba0786Brian      faces[j] = choose_cube_face(s[j], t[j], p[j], ssss + j, tttt + j);
953b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
954a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   sp_get_samples_2d_common(sampler, ssss, tttt, NULL, lodbias, rgba, faces);
95534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
95634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
95734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
958b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrianstatic void
959b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBriansp_get_samples_rect(struct tgsi_sampler *sampler,
960b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                    const float s[QUAD_SIZE],
961b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                    const float t[QUAD_SIZE],
962b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                    const float p[QUAD_SIZE],
963b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                    float lodbias,
964b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                    float rgba[NUM_CHANNELS][QUAD_SIZE])
965b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{
966b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   //sp_get_samples_2d_common(sampler, s, t, p, lodbias, rgba, faces);
967b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   static const uint face = 0;
968b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   const uint compare_func = sampler->state->compare_func;
969b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   unsigned level0, level1, j, imgFilter;
970b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   int width, height;
971b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   float levelBlend;
972b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
973b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   choose_mipmap_levels(sampler, s, t, p, lodbias,
974b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                        &level0, &level1, &levelBlend, &imgFilter);
975b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
976b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   /* texture RECTS cannot be mipmapped */
977b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   assert(level0 == level1);
978b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
979b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   width = sampler->texture->width[level0];
980b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   height = sampler->texture->height[level0];
981b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
982b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   assert(width > 0);
983b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
984b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   switch (imgFilter) {
985b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_FILTER_NEAREST:
986b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      for (j = 0; j < QUAD_SIZE; j++) {
987b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         int x = nearest_texcoord_unnorm(sampler->state->wrap_s, s[j], width);
988b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         int y = nearest_texcoord_unnorm(sampler->state->wrap_t, t[j], height);
989b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         get_texel(sampler, face, level0, x, y, 0, rgba, j);
990b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
991b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian            shadow_compare(compare_func, rgba, p, j);
992b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         }
993b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      }
994b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      break;
995b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_FILTER_LINEAR:
99698ae83d5cc73b61826823c915b5c59746c2e85c7Keith Whitwell   case PIPE_TEX_FILTER_ANISO:
997b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      for (j = 0; j < QUAD_SIZE; j++) {
998b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         float tx[4][4], a, b;
999b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         int x0, y0, x1, y1, c;
1000b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         linear_texcoord_unnorm(sampler->state->wrap_s, s[j], width,  &x0, &x1, &a);
1001b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         linear_texcoord_unnorm(sampler->state->wrap_t, t[j], height, &y0, &y1, &b);
1002b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         get_texel(sampler, face, level0, x0, y0, 0, tx, 0);
1003b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         get_texel(sampler, face, level0, x1, y0, 0, tx, 1);
1004b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         get_texel(sampler, face, level0, x0, y1, 0, tx, 2);
1005b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         get_texel(sampler, face, level0, x1, y1, 0, tx, 3);
1006b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
1007b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian            shadow_compare(compare_func, tx, p, 0);
1008b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian            shadow_compare(compare_func, tx, p, 1);
1009b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian            shadow_compare(compare_func, tx, p, 2);
1010b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian            shadow_compare(compare_func, tx, p, 3);
1011b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         }
1012b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
1013b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         for (c = 0; c < 4; c++) {
1014b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian            rgba[c][j] = lerp_2d(a, b, tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
1015b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         }
1016b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      }
1017b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      break;
1018b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   default:
1019b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      assert(0);
1020b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   }
1021b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian}
1022b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
1023b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
1024b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
1025b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
1026a34b8594b7b2d00404bb639621ec1ce918ba0786Brian/**
1027a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Called via tgsi_sampler::get_samples()
1028a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Use the sampler's state setting to get a filtered RGBA value
1029753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * from the sampler's texture.
1030a34b8594b7b2d00404bb639621ec1ce918ba0786Brian *
1031a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * XXX we can implement many versions of this function, each
1032a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * tightly coded for a specific combination of sampler state
1033a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * (nearest + repeat), (bilinear mipmap + clamp), etc.
1034a34b8594b7b2d00404bb639621ec1ce918ba0786Brian *
1035a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * The update_samplers() function in st_atom_sampler.c could create
1036a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * a new tgsi_sampler object for each state combo it finds....
1037a34b8594b7b2d00404bb639621ec1ce918ba0786Brian */
103834a48abd5ff82ce9748fc29191e35a0985d47c5fBrianvoid
1039b4480285ed5098f1c862690ee105dd46f5e6cd1eBriansp_get_samples(struct tgsi_sampler *sampler,
1040b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float s[QUAD_SIZE],
1041b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float t[QUAD_SIZE],
1042b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float p[QUAD_SIZE],
1043f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian               float lodbias,
1044b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               float rgba[NUM_CHANNELS][QUAD_SIZE])
104534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
10464f23468bd0d14b8ed687a641003d587b91ad39a7Brian   if (!sampler->texture)
10474f23468bd0d14b8ed687a641003d587b91ad39a7Brian      return;
10484f23468bd0d14b8ed687a641003d587b91ad39a7Brian
104934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   switch (sampler->texture->target) {
105070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   case PIPE_TEXTURE_1D:
1051b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      assert(sampler->state->normalized_coords);
1052f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      sp_get_samples_1d(sampler, s, t, p, lodbias, rgba);
105334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
105470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   case PIPE_TEXTURE_2D:
1055b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      if (sampler->state->normalized_coords)
1056b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         sp_get_samples_2d(sampler, s, t, p, lodbias, rgba);
1057b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      else
1058b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         sp_get_samples_rect(sampler, s, t, p, lodbias, rgba);
105934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
106070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   case PIPE_TEXTURE_3D:
1061b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      assert(sampler->state->normalized_coords);
1062f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      sp_get_samples_3d(sampler, s, t, p, lodbias, rgba);
106334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
106470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   case PIPE_TEXTURE_CUBE:
1065b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      assert(sampler->state->normalized_coords);
1066f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      sp_get_samples_cube(sampler, s, t, p, lodbias, rgba);
106734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
106834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   default:
106934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      assert(0);
107034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
10713d53d38d5e35386de4793162b9dd32e171927059Brian Paul
10723d53d38d5e35386de4793162b9dd32e171927059Brian Paul#if 0 /* DEBUG */
10733d53d38d5e35386de4793162b9dd32e171927059Brian Paul   {
10743d53d38d5e35386de4793162b9dd32e171927059Brian Paul      int i;
10753d53d38d5e35386de4793162b9dd32e171927059Brian Paul      printf("Sampled at %f, %f, %f:\n", s[0], t[0], p[0]);
10763d53d38d5e35386de4793162b9dd32e171927059Brian Paul      for (i = 0; i < 4; i++) {
10773d53d38d5e35386de4793162b9dd32e171927059Brian Paul         printf("Frag %d: %f %f %f %f\n", i,
10783d53d38d5e35386de4793162b9dd32e171927059Brian Paul                rgba[0][i],
10793d53d38d5e35386de4793162b9dd32e171927059Brian Paul                rgba[1][i],
10803d53d38d5e35386de4793162b9dd32e171927059Brian Paul                rgba[2][i],
10813d53d38d5e35386de4793162b9dd32e171927059Brian Paul                rgba[3][i]);
10823d53d38d5e35386de4793162b9dd32e171927059Brian Paul      }
10833d53d38d5e35386de4793162b9dd32e171927059Brian Paul   }
10843d53d38d5e35386de4793162b9dd32e171927059Brian Paul#endif
108534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
108634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
1087