sp_tex_sample.c revision f911c3b9897b90132c8621a72bfeb824eb3b01e5
10dc4eea64f56cc93e5359372b08b99a2d600273cBrian/**************************************************************************
20dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
30dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
40dc4eea64f56cc93e5359372b08b99a2d600273cBrian * All Rights Reserved.
53ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul * Copyright 2008 VMware, Inc.  All rights reserved.
60dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
70dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Permission is hereby granted, free of charge, to any person obtaining a
80dc4eea64f56cc93e5359372b08b99a2d600273cBrian * copy of this software and associated documentation files (the
90dc4eea64f56cc93e5359372b08b99a2d600273cBrian * "Software"), to deal in the Software without restriction, including
100dc4eea64f56cc93e5359372b08b99a2d600273cBrian * without limitation the rights to use, copy, modify, merge, publish,
110dc4eea64f56cc93e5359372b08b99a2d600273cBrian * distribute, sub license, and/or sell copies of the Software, and to
120dc4eea64f56cc93e5359372b08b99a2d600273cBrian * permit persons to whom the Software is furnished to do so, subject to
130dc4eea64f56cc93e5359372b08b99a2d600273cBrian * the following conditions:
140dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
150dc4eea64f56cc93e5359372b08b99a2d600273cBrian * The above copyright notice and this permission notice (including the
160dc4eea64f56cc93e5359372b08b99a2d600273cBrian * next paragraph) shall be included in all copies or substantial portions
170dc4eea64f56cc93e5359372b08b99a2d600273cBrian * of the Software.
180dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
190dc4eea64f56cc93e5359372b08b99a2d600273cBrian * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
200dc4eea64f56cc93e5359372b08b99a2d600273cBrian * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
210dc4eea64f56cc93e5359372b08b99a2d600273cBrian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
220dc4eea64f56cc93e5359372b08b99a2d600273cBrian * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
230dc4eea64f56cc93e5359372b08b99a2d600273cBrian * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
240dc4eea64f56cc93e5359372b08b99a2d600273cBrian * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
250dc4eea64f56cc93e5359372b08b99a2d600273cBrian * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
260dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
270dc4eea64f56cc93e5359372b08b99a2d600273cBrian **************************************************************************/
280dc4eea64f56cc93e5359372b08b99a2d600273cBrian
290dc4eea64f56cc93e5359372b08b99a2d600273cBrian/**
300dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Texture sampling
310dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
320dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Authors:
330dc4eea64f56cc93e5359372b08b99a2d600273cBrian *   Brian Paul
340dc4eea64f56cc93e5359372b08b99a2d600273cBrian */
350dc4eea64f56cc93e5359372b08b99a2d600273cBrian
3608f33a025100dea2d951e6d628891fe294b18082Brian#include "sp_context.h"
377925274da323d5a896b557181d4016e0391f026fBrian#include "sp_quad.h"
380dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "sp_surface.h"
390b9e96fae9493d5d58f046e01c983a3c4267090eBrian#include "sp_texture.h"
400dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "sp_tex_sample.h"
4170eb7996f265f3634dabda078f13d1be3533cc65Brian#include "sp_tile_cache.h"
420dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "pipe/p_context.h"
430dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "pipe/p_defines.h"
441a46dcc8a927dfb38ca1381e7b3dafb789f8257cBrian Paul#include "util/u_math.h"
454f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h"
460dc4eea64f56cc93e5359372b08b99a2d600273cBrian
470dc4eea64f56cc93e5359372b08b99a2d600273cBrian
483ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul
4908f33a025100dea2d951e6d628891fe294b18082Brian/*
5008f33a025100dea2d951e6d628891fe294b18082Brian * Note, the FRAC macro has to work perfectly.  Otherwise you'll sometimes
5108f33a025100dea2d951e6d628891fe294b18082Brian * see 1-pixel bands of improperly weighted linear-filtered textures.
5208f33a025100dea2d951e6d628891fe294b18082Brian * The tests/texwrap.c demo is a good test.
5308f33a025100dea2d951e6d628891fe294b18082Brian * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0.
5408f33a025100dea2d951e6d628891fe294b18082Brian * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x).
5508f33a025100dea2d951e6d628891fe294b18082Brian */
569935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul#define FRAC(f)  ((f) - util_ifloor(f))
5708f33a025100dea2d951e6d628891fe294b18082Brian
5808f33a025100dea2d951e6d628891fe294b18082Brian
5908f33a025100dea2d951e6d628891fe294b18082Brian/**
6008f33a025100dea2d951e6d628891fe294b18082Brian * Linear interpolation macro
6108f33a025100dea2d951e6d628891fe294b18082Brian */
6238bee46e83b18ff4ad42d340b507b1a15b4326c7Brianstatic INLINE float
6338bee46e83b18ff4ad42d340b507b1a15b4326c7Brianlerp(float a, float v0, float v1)
6438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian{
6538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   return v0 + a * (v1 - v0);
6638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian}
670dc4eea64f56cc93e5359372b08b99a2d600273cBrian
680dc4eea64f56cc93e5359372b08b99a2d600273cBrian
690dc4eea64f56cc93e5359372b08b99a2d600273cBrian/**
700dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Do 2D/biliner interpolation of float values.
710dc4eea64f56cc93e5359372b08b99a2d600273cBrian * v00, v10, v01 and v11 are typically four texture samples in a square/box.
720dc4eea64f56cc93e5359372b08b99a2d600273cBrian * a and b are the horizontal and vertical interpolants.
730dc4eea64f56cc93e5359372b08b99a2d600273cBrian * It's important that this function is inlined when compiled with
740dc4eea64f56cc93e5359372b08b99a2d600273cBrian * optimization!  If we find that's not true on some systems, convert
750dc4eea64f56cc93e5359372b08b99a2d600273cBrian * to a macro.
760dc4eea64f56cc93e5359372b08b99a2d600273cBrian */
77b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic INLINE float
78b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianlerp_2d(float a, float b,
79b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian        float v00, float v10, float v01, float v11)
800dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
8138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   const float temp0 = lerp(a, v00, v10);
8238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   const float temp1 = lerp(a, v01, v11);
8338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   return lerp(b, temp0, temp1);
8438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian}
8538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
8638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
8738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian/**
8838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * As above, but 3D interpolation of 8 values.
8938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian */
9038bee46e83b18ff4ad42d340b507b1a15b4326c7Brianstatic INLINE float
9138bee46e83b18ff4ad42d340b507b1a15b4326c7Brianlerp_3d(float a, float b, float c,
9238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian        float v000, float v100, float v010, float v110,
9338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian        float v001, float v101, float v011, float v111)
9438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian{
9538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   const float temp0 = lerp_2d(a, b, v000, v100, v010, v110);
9638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   const float temp1 = lerp_2d(a, b, v001, v101, v011, v111);
9738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   return lerp(c, temp0, temp1);
980dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
990dc4eea64f56cc93e5359372b08b99a2d600273cBrian
1000dc4eea64f56cc93e5359372b08b99a2d600273cBrian
10138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
1020dc4eea64f56cc93e5359372b08b99a2d600273cBrian/**
103906768316d9521a32d9a7eebc9edaf76c06a98a7Brian * If A is a signed integer, A % B doesn't give the right value for A < 0
104906768316d9521a32d9a7eebc9edaf76c06a98a7Brian * (in terms of texture repeat).  Just casting to unsigned fixes that.
1050dc4eea64f56cc93e5359372b08b99a2d600273cBrian */
106906768316d9521a32d9a7eebc9edaf76c06a98a7Brian#define REMAINDER(A, B) ((unsigned) (A) % (unsigned) (B))
10708f33a025100dea2d951e6d628891fe294b18082Brian
10808f33a025100dea2d951e6d628891fe294b18082Brian
10908f33a025100dea2d951e6d628891fe294b18082Brian/**
11038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * Apply texture coord wrapping mode and return integer texture indexes
11138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * for a vector of four texcoords (S or T or P).
11208f33a025100dea2d951e6d628891fe294b18082Brian * \param wrapMode  PIPE_TEX_WRAP_x
11338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param s  the incoming texcoords
11408f33a025100dea2d951e6d628891fe294b18082Brian * \param size  the texture image size
11538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param icoord  returns the integer texcoords
11608f33a025100dea2d951e6d628891fe294b18082Brian * \return  integer texture index
11708f33a025100dea2d951e6d628891fe294b18082Brian */
11838bee46e83b18ff4ad42d340b507b1a15b4326c7Brianstatic INLINE void
11938bee46e83b18ff4ad42d340b507b1a15b4326c7Briannearest_texcoord_4(unsigned wrapMode, const float s[4], unsigned size,
12038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                   int icoord[4])
1210dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
12238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   uint ch;
1230dc4eea64f56cc93e5359372b08b99a2d600273cBrian   switch (wrapMode) {
1240dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_WRAP_REPEAT:
12508f33a025100dea2d951e6d628891fe294b18082Brian      /* s limited to [0,1) */
12608f33a025100dea2d951e6d628891fe294b18082Brian      /* i limited to [0,size-1] */
12738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
12838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         int i = util_ifloor(s[ch] * size);
12938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord[ch] = REMAINDER(i, size);
13038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
13138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
1320dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_WRAP_CLAMP:
13308f33a025100dea2d951e6d628891fe294b18082Brian      /* s limited to [0,1] */
13408f33a025100dea2d951e6d628891fe294b18082Brian      /* i limited to [0,size-1] */
13538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
13638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (s[ch] <= 0.0F)
13738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord[ch] = 0;
13838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         else if (s[ch] >= 1.0F)
13938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord[ch] = size - 1;
14038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         else
14138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord[ch] = util_ifloor(s[ch] * size);
14238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
14338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
14408f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
14508f33a025100dea2d951e6d628891fe294b18082Brian      {
14608f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [min,max] */
14708f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [0, size-1] */
148b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = 1.0F / (2.0F * size);
149b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
15038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (ch = 0; ch < 4; ch++) {
15138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (s[ch] < min)
15238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = 0;
15338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else if (s[ch] > max)
15438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = size - 1;
15538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else
15638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = util_ifloor(s[ch] * size);
15738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         }
15808f33a025100dea2d951e6d628891fe294b18082Brian      }
15938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
16008f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
16108f33a025100dea2d951e6d628891fe294b18082Brian      {
16208f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [min,max] */
16308f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [-1, size] */
164b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = -1.0F / (2.0F * size);
165b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
16638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (ch = 0; ch < 4; ch++) {
16738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (s[ch] <= min)
16838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = -1;
16938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else if (s[ch] >= max)
17038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = size;
17138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else
17238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = util_ifloor(s[ch] * size);
17338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         }
17408f33a025100dea2d951e6d628891fe294b18082Brian      }
17538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
17608f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_REPEAT:
17708f33a025100dea2d951e6d628891fe294b18082Brian      {
178b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = 1.0F / (2.0F * size);
179b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
18038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (ch = 0; ch < 4; ch++) {
18138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            const int flr = util_ifloor(s[ch]);
18238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            float u;
18338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (flr & 1)
18438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               u = 1.0F - (s[ch] - (float) flr);
18538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else
18638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               u = s[ch] - (float) flr;
18738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (u < min)
18838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = 0;
18938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else if (u > max)
19038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = size - 1;
19138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else
19238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = util_ifloor(u * size);
19338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         }
19408f33a025100dea2d951e6d628891fe294b18082Brian      }
19538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
19608f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP:
19738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
19808f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [0,1] */
19908f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [0,size-1] */
20038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         const float u = fabsf(s[ch]);
20108f33a025100dea2d951e6d628891fe294b18082Brian         if (u <= 0.0F)
20238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord[ch] = 0;
20308f33a025100dea2d951e6d628891fe294b18082Brian         else if (u >= 1.0F)
20438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord[ch] = size - 1;
20508f33a025100dea2d951e6d628891fe294b18082Brian         else
20638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord[ch] = util_ifloor(u * size);
20708f33a025100dea2d951e6d628891fe294b18082Brian      }
20838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
20908f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
21008f33a025100dea2d951e6d628891fe294b18082Brian      {
21108f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [min,max] */
21208f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [0, size-1] */
213b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = 1.0F / (2.0F * size);
214b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
21538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (ch = 0; ch < 4; ch++) {
21638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            const float u = fabsf(s[ch]);
21738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (u < min)
21838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = 0;
21938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else if (u > max)
22038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = size - 1;
22138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else
22238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = util_ifloor(u * size);
22338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         }
22408f33a025100dea2d951e6d628891fe294b18082Brian      }
22538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
22608f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
22708f33a025100dea2d951e6d628891fe294b18082Brian      {
22808f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [min,max] */
22908f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [0, size-1] */
230b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = -1.0F / (2.0F * size);
231b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
23238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (ch = 0; ch < 4; ch++) {
23338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            const float u = fabsf(s[ch]);
23438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (u < min)
23538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = -1;
23638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else if (u > max)
23738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = size;
23838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else
23938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               icoord[ch] = util_ifloor(u * size);
24038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         }
24108f33a025100dea2d951e6d628891fe294b18082Brian      }
24238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
2430dc4eea64f56cc93e5359372b08b99a2d600273cBrian   default:
2440dc4eea64f56cc93e5359372b08b99a2d600273cBrian      assert(0);
2450dc4eea64f56cc93e5359372b08b99a2d600273cBrian   }
2460dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
2470dc4eea64f56cc93e5359372b08b99a2d600273cBrian
24808f33a025100dea2d951e6d628891fe294b18082Brian
24908f33a025100dea2d951e6d628891fe294b18082Brian/**
25038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * Used to compute texel locations for linear sampling for four texcoords.
25108f33a025100dea2d951e6d628891fe294b18082Brian * \param wrapMode  PIPE_TEX_WRAP_x
25238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param s  the texcoords
25308f33a025100dea2d951e6d628891fe294b18082Brian * \param size  the texture image size
25438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param icoord0  returns first texture indexes
25538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param icoord1  returns second texture indexes (usually icoord0 + 1)
25638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param w  returns blend factor/weight between texture indexes
25738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param icoord  returns the computed integer texture coords
25808f33a025100dea2d951e6d628891fe294b18082Brian */
2590dc4eea64f56cc93e5359372b08b99a2d600273cBrianstatic INLINE void
26038bee46e83b18ff4ad42d340b507b1a15b4326c7Brianlinear_texcoord_4(unsigned wrapMode, const float s[4], unsigned size,
26138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                  int icoord0[4], int icoord1[4], float w[4])
2620dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
26338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   uint ch;
26438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
2650dc4eea64f56cc93e5359372b08b99a2d600273cBrian   switch (wrapMode) {
2660dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_WRAP_REPEAT:
26738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
26838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float u = s[ch] * size - 0.5F;
26938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord0[ch] = REMAINDER(util_ifloor(u), size);
27038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord1[ch] = REMAINDER(icoord0[ch] + 1, size);
27138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         w[ch] = FRAC(u);
27238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
27338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      break;;
2740dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_WRAP_CLAMP:
27538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
27638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float u = CLAMP(s[ch], 0.0F, 1.0F);
27738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         u = u * size - 0.5f;
27838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord0[ch] = util_ifloor(u);
27938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord1[ch] = icoord0[ch] + 1;
28038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         w[ch] = FRAC(u);
28138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
28238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      break;;
28308f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
28438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
28538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float u = CLAMP(s[ch], 0.0F, 1.0F);
28638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         u = u * size - 0.5f;
28738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord0[ch] = util_ifloor(u);
28838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord1[ch] = icoord0[ch] + 1;
28938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (icoord0[ch] < 0)
29038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord0[ch] = 0;
29138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (icoord1[ch] >= (int) size)
29238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord1[ch] = size - 1;
29338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         w[ch] = FRAC(u);
29438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
29538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      break;;
29608f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
29708f33a025100dea2d951e6d628891fe294b18082Brian      {
298b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = -1.0F / (2.0F * size);
299b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
30038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (ch = 0; ch < 4; ch++) {
30138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            float u = CLAMP(s[ch], min, max);
30238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            u = u * size - 0.5f;
30338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord0[ch] = util_ifloor(u);
30438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord1[ch] = icoord0[ch] + 1;
30538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            w[ch] = FRAC(u);
30638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         }
30708f33a025100dea2d951e6d628891fe294b18082Brian      }
30838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      break;;
30908f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_REPEAT:
31038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
31138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         const int flr = util_ifloor(s[ch]);
31238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float u;
31308f33a025100dea2d951e6d628891fe294b18082Brian         if (flr & 1)
31438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            u = 1.0F - (s[ch] - (float) flr);
31508f33a025100dea2d951e6d628891fe294b18082Brian         else
31638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            u = s[ch] - (float) flr;
31738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         u = u * size - 0.5F;
31838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord0[ch] = util_ifloor(u);
31938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord1[ch] = icoord0[ch] + 1;
32038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (icoord0[ch] < 0)
32138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord0[ch] = 0;
32238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (icoord1[ch] >= (int) size)
32338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord1[ch] = size - 1;
32438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         w[ch] = FRAC(u);
32508f33a025100dea2d951e6d628891fe294b18082Brian      }
32638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      break;;
32708f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP:
32838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
32938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float u = fabsf(s[ch]);
33038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (u >= 1.0F)
33138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            u = (float) size;
33238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         else
33338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            u *= size;
33438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         u -= 0.5F;
33538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord0[ch] = util_ifloor(u);
33638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord1[ch] = icoord0[ch] + 1;
33738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         w[ch] = FRAC(u);
33838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
33938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      break;;
34008f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
34138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
34238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float u = fabsf(s[ch]);
34338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (u >= 1.0F)
34438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            u = (float) size;
34538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         else
34638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            u *= size;
34738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         u -= 0.5F;
34838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord0[ch] = util_ifloor(u);
34938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord1[ch] = icoord0[ch] + 1;
35038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (icoord0[ch] < 0)
35138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord0[ch] = 0;
35238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (icoord1[ch] >= (int) size)
35338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord1[ch] = size - 1;
35438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         w[ch] = FRAC(u);
35538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
35638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      break;;
35708f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
35808f33a025100dea2d951e6d628891fe294b18082Brian      {
359b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = -1.0F / (2.0F * size);
360b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
36138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (ch = 0; ch < 4; ch++) {
36238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            float u = fabsf(s[ch]);
36338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (u <= min)
36438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               u = min * size;
36538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else if (u >= max)
36638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               u = max * size;
36738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            else
36838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               u *= size;
36938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            u -= 0.5F;
37038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord0[ch] = util_ifloor(u);
37138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord1[ch] = icoord0[ch] + 1;
37238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            w[ch] = FRAC(u);
37338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         }
37408f33a025100dea2d951e6d628891fe294b18082Brian      }
37538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      break;;
3760dc4eea64f56cc93e5359372b08b99a2d600273cBrian   default:
3770dc4eea64f56cc93e5359372b08b99a2d600273cBrian      assert(0);
3780dc4eea64f56cc93e5359372b08b99a2d600273cBrian   }
3790dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
3800dc4eea64f56cc93e5359372b08b99a2d600273cBrian
3810dc4eea64f56cc93e5359372b08b99a2d600273cBrian
382b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian/**
383b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * For RECT textures / unnormalized texcoords
384b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * Only a subset of wrap modes supported.
385b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian */
38638bee46e83b18ff4ad42d340b507b1a15b4326c7Brianstatic INLINE void
38738bee46e83b18ff4ad42d340b507b1a15b4326c7Briannearest_texcoord_unnorm_4(unsigned wrapMode, const float s[4], unsigned size,
38838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                          int icoord[4])
389b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{
39038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   uint ch;
391b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   switch (wrapMode) {
392b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP:
39338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
39438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         int i = util_ifloor(s[ch]);
39538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord[ch]= CLAMP(i, 0, (int) size-1);
39638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
39738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
398b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
399b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      /* fall-through */
400b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
40138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
40238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord[ch]= util_ifloor( CLAMP(s[ch], 0.5F, (float) size - 0.5F) );
40338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
40438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
405b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   default:
406b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      assert(0);
407b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   }
408b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian}
409b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
410b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
411b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian/**
412b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * For RECT textures / unnormalized texcoords.
413b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * Only a subset of wrap modes supported.
414b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian */
415b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrianstatic INLINE void
41638bee46e83b18ff4ad42d340b507b1a15b4326c7Brianlinear_texcoord_unnorm_4(unsigned wrapMode, const float s[4], unsigned size,
41738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                         int icoord0[4], int icoord1[4], float w[4])
418b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{
41938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   uint ch;
420b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   switch (wrapMode) {
421b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP:
42238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
42338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         /* Not exactly what the spec says, but it matches NVIDIA output */
42438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float u = CLAMP(s[ch] - 0.5F, 0.0f, (float) size - 1.0f);
42538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord0[ch] = util_ifloor(u);
42638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord1[ch] = icoord0[ch] + 1;
42738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         w[ch] = FRAC(u);
42838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
42938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      return;
430b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
431b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      /* fall-through */
432b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
43338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      for (ch = 0; ch < 4; ch++) {
43438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float u = CLAMP(s[ch], 0.5F, (float) size - 0.5F);
43538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         u -= 0.5F;
43638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord0[ch] = util_ifloor(u);
43738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         icoord1[ch] = icoord0[ch] + 1;
43838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         if (icoord1[ch] > (int) size - 1)
43938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            icoord1[ch] = size - 1;
44038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         w[ch] = FRAC(u);
44138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      }
442b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      break;
443b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   default:
444b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      assert(0);
445b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   }
446b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian}
447b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
448b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
44970af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwellstatic unsigned
450a34b8594b7b2d00404bb639621ec1ce918ba0786Brianchoose_cube_face(float rx, float ry, float rz, float *newS, float *newT)
45134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
45234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   /*
45334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      major axis
45434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      direction     target                             sc     tc    ma
45534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      ----------    -------------------------------    ---    ---   ---
45634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       +rx          TEXTURE_CUBE_MAP_POSITIVE_X_EXT    -rz    -ry   rx
45734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       -rx          TEXTURE_CUBE_MAP_NEGATIVE_X_EXT    +rz    -ry   rx
45834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       +ry          TEXTURE_CUBE_MAP_POSITIVE_Y_EXT    +rx    +rz   ry
45934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       -ry          TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT    +rx    -rz   ry
46034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       +rz          TEXTURE_CUBE_MAP_POSITIVE_Z_EXT    +rx    -ry   rz
46134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       -rz          TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT    -rx    -ry   rz
46234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   */
4639935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul   const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz);
46470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   unsigned face;
465b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   float sc, tc, ma;
46634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
46734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   if (arx > ary && arx > arz) {
46834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      if (rx >= 0.0F) {
46934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_POS_X;
47034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = -rz;
47134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
47234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arx;
47334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
47434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      else {
47534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_NEG_X;
47634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rz;
47734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
47834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arx;
47934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
48034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
48134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   else if (ary > arx && ary > arz) {
48234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      if (ry >= 0.0F) {
48334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_POS_Y;
48434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rx;
48534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = rz;
48634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = ary;
48734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
48834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      else {
48934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_NEG_Y;
49034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rx;
49134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -rz;
49234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = ary;
49334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
49434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
49534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   else {
49634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      if (rz > 0.0F) {
49734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_POS_Z;
49834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rx;
49934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
50034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arz;
50134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
50234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      else {
50334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_NEG_Z;
50434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = -rx;
50534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
50634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arz;
50734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
50834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
50934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
510a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   *newS = ( sc / ma + 1.0F ) * 0.5F;
511a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   *newT = ( tc / ma + 1.0F ) * 0.5F;
51234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
51334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   return face;
51434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
51534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
51634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
517b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/**
518b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * Examine the quad's texture coordinates to compute the partial
519b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * derivatives w.r.t X and Y, then compute lambda (level of detail).
520b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian *
521b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * This is only done for fragment shaders, not vertex shaders.
522b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian */
523b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic float
5240b9e96fae9493d5d58f046e01c983a3c4267090eBriancompute_lambda(const struct pipe_texture *tex,
5250b9e96fae9493d5d58f046e01c983a3c4267090eBrian               const struct pipe_sampler_state *sampler,
526b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float s[QUAD_SIZE],
527b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float t[QUAD_SIZE],
528f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian               const float p[QUAD_SIZE],
529f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian               float lodbias)
530b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian{
531b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   float rho, lambda;
532b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
5330b9e96fae9493d5d58f046e01c983a3c4267090eBrian   assert(sampler->normalized_coords);
534b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
535b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   assert(s);
536b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   {
537b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dsdx = s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT];
538b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dsdy = s[QUAD_TOP_LEFT]     - s[QUAD_BOTTOM_LEFT];
5399935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      dsdx = fabsf(dsdx);
5409935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      dsdy = fabsf(dsdy);
5410b9e96fae9493d5d58f046e01c983a3c4267090eBrian      rho = MAX2(dsdx, dsdy) * tex->width[0];
542b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
543b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   if (t) {
544b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT];
545b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dtdy = t[QUAD_TOP_LEFT]     - t[QUAD_BOTTOM_LEFT];
546b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float max;
5479935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      dtdx = fabsf(dtdx);
5489935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      dtdy = fabsf(dtdy);
5490b9e96fae9493d5d58f046e01c983a3c4267090eBrian      max = MAX2(dtdx, dtdy) * tex->height[0];
550b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      rho = MAX2(rho, max);
551b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
552b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   if (p) {
553b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dpdx = p[QUAD_BOTTOM_RIGHT] - p[QUAD_BOTTOM_LEFT];
554b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dpdy = p[QUAD_TOP_LEFT]     - p[QUAD_BOTTOM_LEFT];
555b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float max;
5569935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      dpdx = fabsf(dpdx);
5579935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul      dpdy = fabsf(dpdy);
5580b9e96fae9493d5d58f046e01c983a3c4267090eBrian      max = MAX2(dpdx, dpdy) * tex->depth[0];
559b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      rho = MAX2(rho, max);
560b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
561b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
5621a46dcc8a927dfb38ca1381e7b3dafb789f8257cBrian Paul   lambda = util_fast_log2(rho);
5630b9e96fae9493d5d58f046e01c983a3c4267090eBrian   lambda += lodbias + sampler->lod_bias;
5640b9e96fae9493d5d58f046e01c983a3c4267090eBrian   lambda = CLAMP(lambda, sampler->min_lod, sampler->max_lod);
565b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
566b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   return lambda;
567b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian}
568b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
569b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
570f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian/**
571c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * Do several things here:
572c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 1. Compute lambda from the texcoords, if needed
573c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 2. Determine if we're minifying or magnifying
574c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 3. If minifying, choose mipmap levels
575c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 4. Return image filter to use within mipmap images
576dd55083ac1c13723dba6be71f161e2ca7cac7c66Brian * \param level0  Returns first mipmap level to sample from
577dd55083ac1c13723dba6be71f161e2ca7cac7c66Brian * \param level1  Returns second mipmap level to sample from
578dd55083ac1c13723dba6be71f161e2ca7cac7c66Brian * \param levelBlend  Returns blend factor between levels, in [0,1]
579dd55083ac1c13723dba6be71f161e2ca7cac7c66Brian * \param imgFilter  Returns either the min or mag filter, depending on lambda
580f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian */
581f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrianstatic void
5820b9e96fae9493d5d58f046e01c983a3c4267090eBrianchoose_mipmap_levels(const struct pipe_texture *texture,
5830b9e96fae9493d5d58f046e01c983a3c4267090eBrian                     const struct pipe_sampler_state *sampler,
584c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     const float s[QUAD_SIZE],
585c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     const float t[QUAD_SIZE],
586c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     const float p[QUAD_SIZE],
5873ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                     boolean computeLambda,
588c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     float lodbias,
589c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     unsigned *level0, unsigned *level1, float *levelBlend,
590c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     unsigned *imgFilter)
59109a1b912605ff48c8782dcc5aae55ac77e27037bBrian{
5920b9e96fae9493d5d58f046e01c983a3c4267090eBrian   if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) {
593c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      /* no mipmap selection needed */
5940b9e96fae9493d5d58f046e01c983a3c4267090eBrian      *level0 = *level1 = CLAMP((int) sampler->min_lod,
5950b9e96fae9493d5d58f046e01c983a3c4267090eBrian                                0, (int) texture->last_level);
59608c9534107fcaf06f9b801551524ed5dc724db13Brian
5970b9e96fae9493d5d58f046e01c983a3c4267090eBrian      if (sampler->min_img_filter != sampler->mag_img_filter) {
59808c9534107fcaf06f9b801551524ed5dc724db13Brian         /* non-mipmapped texture, but still need to determine if doing
59908c9534107fcaf06f9b801551524ed5dc724db13Brian          * minification or magnification.
60008c9534107fcaf06f9b801551524ed5dc724db13Brian          */
6010b9e96fae9493d5d58f046e01c983a3c4267090eBrian         float lambda = compute_lambda(texture, sampler, s, t, p, lodbias);
6023b2a291888d8e62787de03f8529806fb562bd186Brian         if (lambda <= 0.0) {
6030b9e96fae9493d5d58f046e01c983a3c4267090eBrian            *imgFilter = sampler->mag_img_filter;
60408c9534107fcaf06f9b801551524ed5dc724db13Brian         }
60508c9534107fcaf06f9b801551524ed5dc724db13Brian         else {
6060b9e96fae9493d5d58f046e01c983a3c4267090eBrian            *imgFilter = sampler->min_img_filter;
60708c9534107fcaf06f9b801551524ed5dc724db13Brian         }
60808c9534107fcaf06f9b801551524ed5dc724db13Brian      }
6093b2a291888d8e62787de03f8529806fb562bd186Brian      else {
6100b9e96fae9493d5d58f046e01c983a3c4267090eBrian         *imgFilter = sampler->mag_img_filter;
6113b2a291888d8e62787de03f8529806fb562bd186Brian      }
612c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian   }
613c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian   else {
614c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      float lambda;
615c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian
6163ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul      if (computeLambda)
617c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* fragment shader */
6180b9e96fae9493d5d58f046e01c983a3c4267090eBrian         lambda = compute_lambda(texture, sampler, s, t, p, lodbias);
619c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      else
620c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* vertex shader */
621c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         lambda = lodbias; /* not really a bias, but absolute LOD */
622c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian
6233b2a291888d8e62787de03f8529806fb562bd186Brian      if (lambda <= 0.0) { /* XXX threshold depends on the filter */
624c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* magnifying */
6250b9e96fae9493d5d58f046e01c983a3c4267090eBrian         *imgFilter = sampler->mag_img_filter;
6264da1cdf78fa3b954840650fa46cf72da5daf149fBrian         *level0 = *level1 = 0;
627f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      }
628c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      else {
629c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* minifying */
6300b9e96fae9493d5d58f046e01c983a3c4267090eBrian         *imgFilter = sampler->min_img_filter;
631c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian
632c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* choose mipmap level(s) and compute the blend factor between them */
6330b9e96fae9493d5d58f046e01c983a3c4267090eBrian         if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NEAREST) {
634c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            /* Nearest mipmap level */
635c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            const int lvl = (int) (lambda + 0.5);
636c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            *level0 =
6370b9e96fae9493d5d58f046e01c983a3c4267090eBrian            *level1 = CLAMP(lvl, 0, (int) texture->last_level);
638c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         }
639c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         else {
640c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            /* Linear interpolation between mipmap levels */
641c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            const int lvl = (int) lambda;
6420b9e96fae9493d5d58f046e01c983a3c4267090eBrian            *level0 = CLAMP(lvl,     0, (int) texture->last_level);
6430b9e96fae9493d5d58f046e01c983a3c4267090eBrian            *level1 = CLAMP(lvl + 1, 0, (int) texture->last_level);
644c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            *levelBlend = FRAC(lambda);  /* blending weight between levels */
645c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         }
646f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      }
64709a1b912605ff48c8782dcc5aae55ac77e27037bBrian   }
64809a1b912605ff48c8782dcc5aae55ac77e27037bBrian}
64909a1b912605ff48c8782dcc5aae55ac77e27037bBrian
65008f33a025100dea2d951e6d628891fe294b18082Brian
651b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/**
652a13de2464dd034ff117f9314df5757d068cae8e5Brian * Get a texel from a texture, using the texture tile cache.
653a13de2464dd034ff117f9314df5757d068cae8e5Brian *
654b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param face  the cube face in 0..5
655b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param level  the mipmap level
656b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param x  the x coord of texel within 2D image
657b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param y  the y coord of texel within 2D image
65870eb7996f265f3634dabda078f13d1be3533cc65Brian * \param z  which slice of a 3D texture
659b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param rgba  the quad to put the texel/color into
660b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param j  which element of the rgba quad to write to
66170eb7996f265f3634dabda078f13d1be3533cc65Brian *
66270eb7996f265f3634dabda078f13d1be3533cc65Brian * XXX maybe move this into sp_tile_cache.c and merge with the
66370eb7996f265f3634dabda078f13d1be3533cc65Brian * sp_get_cached_tile_tex() function.  Also, get 4 texels instead of 1...
664b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian */
665b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic void
666dd55083ac1c13723dba6be71f161e2ca7cac7c66Brianget_texel(const struct tgsi_sampler *tgsi_sampler,
66770eb7996f265f3634dabda078f13d1be3533cc65Brian          unsigned face, unsigned level, int x, int y, int z,
668a13de2464dd034ff117f9314df5757d068cae8e5Brian          float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j)
669b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian{
6700b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
671aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell   const struct pipe_texture *texture = samp->texture;
672aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell   const struct pipe_sampler_state *sampler = samp->sampler;
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 {
683f911c3b9897b90132c8621a72bfeb824eb3b01e5Keith Whitwell      const unsigned tx = x % TILE_SIZE;
684f911c3b9897b90132c8621a72bfeb824eb3b01e5Keith Whitwell      const unsigned ty = y % TILE_SIZE;
685f911c3b9897b90132c8621a72bfeb824eb3b01e5Keith Whitwell      const struct softpipe_cached_tile *tile;
686f911c3b9897b90132c8621a72bfeb824eb3b01e5Keith Whitwell
687f911c3b9897b90132c8621a72bfeb824eb3b01e5Keith Whitwell      tile = sp_get_cached_tile_tex(samp->cache,
688f911c3b9897b90132c8621a72bfeb824eb3b01e5Keith Whitwell                                    tile_address(x, y, z, face, level));
689f911c3b9897b90132c8621a72bfeb824eb3b01e5Keith Whitwell
690ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul      rgba[0][j] = tile->data.color[ty][tx][0];
691ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul      rgba[1][j] = tile->data.color[ty][tx][1];
692ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul      rgba[2][j] = tile->data.color[ty][tx][2];
693ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul      rgba[3][j] = tile->data.color[ty][tx][3];
694b1ff7dac537947d412bf423a73e7eacd76f90d84Brian Paul      if (0)
695b1ff7dac537947d412bf423a73e7eacd76f90d84Brian Paul      {
696ae2195caf56d2eb782475254c68858a25ee7c857Brian Paul         debug_printf("Get texel %f %f %f %f from %s\n",
6978fb55dab783f2de5111e7440093e1458fce5fb3dBrian Paul                      rgba[0][j], rgba[1][j], rgba[2][j], rgba[3][j],
6980b9e96fae9493d5d58f046e01c983a3c4267090eBrian                      pf_name(texture->format));
699b1ff7dac537947d412bf423a73e7eacd76f90d84Brian Paul      }
700ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul   }
701b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian}
702b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
703b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
7043d8c05f7320151898dd224c1daaf3118e1f7ea34Brian/**
7053d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * Compare texcoord 'p' (aka R) against texture value 'rgba[0]'
7063d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * When we sampled the depth texture, the depth value was put into all
7073d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * RGBA channels.  We look at the red channel here.
708efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul * \param rgba  quad of (depth) texel values
709efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul * \param p  texture 'P' components for four pixels in quad
710efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul * \param j  which pixel in the quad to test [0..3]
7113d8c05f7320151898dd224c1daaf3118e1f7ea34Brian */
7123d8c05f7320151898dd224c1daaf3118e1f7ea34Brianstatic INLINE void
713005ee9f4e05b487d455e87c6843d1d1a3c1536ffBrian Paulshadow_compare(const struct pipe_sampler_state *sampler,
7143d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               float rgba[NUM_CHANNELS][QUAD_SIZE],
7153d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               const float p[QUAD_SIZE],
7163d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               uint j)
7173d8c05f7320151898dd224c1daaf3118e1f7ea34Brian{
7183d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   int k;
719005ee9f4e05b487d455e87c6843d1d1a3c1536ffBrian Paul   switch (sampler->compare_func) {
7203d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_LESS:
7213d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] < rgba[0][j];
7223d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
7233d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_LEQUAL:
7243d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] <= rgba[0][j];
7253d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
7263d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_GREATER:
7273d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] > rgba[0][j];
7283d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
7293d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_GEQUAL:
7303d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] >= rgba[0][j];
7313d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
7323d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_EQUAL:
7333d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] == rgba[0][j];
7343d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
7353d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_NOTEQUAL:
7363d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] != rgba[0][j];
7373d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
7383d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_ALWAYS:
7393d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = 1;
7403d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
7413d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_NEVER:
7423d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = 0;
7433d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
7443d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   default:
745f9b1d47d652778012fd35552ffc51717ac0b6f79Keith Whitwell      k = 0;
7463d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      assert(0);
747f9b1d47d652778012fd35552ffc51717ac0b6f79Keith Whitwell      break;
7483d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   }
7493d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
750048765624598e6c60b9fe4dc82a72b7110f16715Brian Paul   /* XXX returning result for default GL_DEPTH_TEXTURE_MODE = GL_LUMINANCE */
7513d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   rgba[0][j] = rgba[1][j] = rgba[2][j] = (float) k;
752048765624598e6c60b9fe4dc82a72b7110f16715Brian Paul   rgba[3][j] = 1.0F;
7533d8c05f7320151898dd224c1daaf3118e1f7ea34Brian}
7543d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
755b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
756b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/**
757efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul * As above, but do four z/texture comparisons.
758efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul */
759efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paulstatic INLINE void
760efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paulshadow_compare4(const struct pipe_sampler_state *sampler,
761efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul                float rgba[NUM_CHANNELS][QUAD_SIZE],
762efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul                const float p[QUAD_SIZE])
763efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul{
764efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   int j, k0, k1, k2, k3;
765efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   float val;
766efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul
767efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   /* compare four texcoords vs. four texture samples */
768efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   switch (sampler->compare_func) {
769efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_LESS:
770efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k0 = p[0] < rgba[0][0];
771efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k1 = p[1] < rgba[0][1];
772efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k2 = p[2] < rgba[0][2];
773efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k3 = p[3] < rgba[0][3];
774efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
775efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_LEQUAL:
776efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k0 = p[0] <= rgba[0][0];
777efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k1 = p[1] <= rgba[0][1];
778efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k2 = p[2] <= rgba[0][2];
779efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k3 = p[3] <= rgba[0][3];
780efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
781efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_GREATER:
782efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k0 = p[0] > rgba[0][0];
783efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k1 = p[1] > rgba[0][1];
784efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k2 = p[2] > rgba[0][2];
785efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k3 = p[3] > rgba[0][3];
786efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
787efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_GEQUAL:
788efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k0 = p[0] >= rgba[0][0];
789efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k1 = p[1] >= rgba[0][1];
790efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k2 = p[2] >= rgba[0][2];
791efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k3 = p[3] >= rgba[0][3];
792efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
793efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_EQUAL:
794efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k0 = p[0] == rgba[0][0];
795efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k1 = p[1] == rgba[0][1];
796efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k2 = p[2] == rgba[0][2];
797efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k3 = p[3] == rgba[0][3];
798efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
799efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_NOTEQUAL:
800efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k0 = p[0] != rgba[0][0];
801efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k1 = p[1] != rgba[0][1];
802efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k2 = p[2] != rgba[0][2];
803efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k3 = p[3] != rgba[0][3];
804efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
805efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_ALWAYS:
806efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k0 = k1 = k2 = k3 = 1;
807efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
808efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_NEVER:
809efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k0 = k1 = k2 = k3 = 0;
810efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
811efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   default:
812efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k0 = k1 = k2 = k3 = 0;
813efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      assert(0);
814efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
815efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   }
816efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul
817efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   /* convert four pass/fail values to an intensity in [0,1] */
818efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   val = 0.25F * (k0 + k1 + k2 + k3);
819efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul
820efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   /* XXX returning result for default GL_DEPTH_TEXTURE_MODE = GL_LUMINANCE */
821efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   for (j = 0; j < 4; j++) {
822efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      rgba[0][j] = rgba[1][j] = rgba[2][j] = val;
823efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      rgba[3][j] = 1.0F;
824efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   }
825efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul}
826efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul
827efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul
828efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul/**
829a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Common code for sampling 1D/2D/cube textures.
830a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Could probably extend for 3D...
8310dc4eea64f56cc93e5359372b08b99a2d600273cBrian */
832e12810d92ffb3547680b227bf88937c03018112bBrianstatic void
833dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler,
834a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         const float s[QUAD_SIZE],
835a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         const float t[QUAD_SIZE],
836a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         const float p[QUAD_SIZE],
8373ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                         boolean computeLambda,
838a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         float lodbias,
839a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         float rgba[NUM_CHANNELS][QUAD_SIZE],
840a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         const unsigned faces[4])
8410dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
8420b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
843aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell   const struct pipe_texture *texture = samp->texture;
844aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell   const struct pipe_sampler_state *sampler = samp->sampler;
845f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian   unsigned level0, level1, j, imgFilter;
846f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian   int width, height;
847c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian   float levelBlend;
848a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
8493ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul   choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias,
850c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                        &level0, &level1, &levelBlend, &imgFilter);
85109a1b912605ff48c8782dcc5aae55ac77e27037bBrian
8520b9e96fae9493d5d58f046e01c983a3c4267090eBrian   assert(sampler->normalized_coords);
853b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
8540b9e96fae9493d5d58f046e01c983a3c4267090eBrian   width = texture->width[level0];
8550b9e96fae9493d5d58f046e01c983a3c4267090eBrian   height = texture->height[level0];
85609a1b912605ff48c8782dcc5aae55ac77e27037bBrian
857b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   assert(width > 0);
858612cfb749c3526eeb446bbc631bf24716522f373Brian
859b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   switch (imgFilter) {
8600dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_FILTER_NEAREST:
86138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      {
86238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         int x[4], y[4];
86338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         nearest_texcoord_4(sampler->wrap_s, s, width, x);
86438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         nearest_texcoord_4(sampler->wrap_t, t, height, y);
86538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
86638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (j = 0; j < QUAD_SIZE; j++) {
86738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, faces[j], level0, x[j], y[j], 0, rgba, j);
86838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
869005ee9f4e05b487d455e87c6843d1d1a3c1536ffBrian Paul               shadow_compare(sampler, rgba, p, j);
8703d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            }
8713d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
87238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (level0 != level1) {
87338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               /* get texels from second mipmap level and blend */
87438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               float rgba2[4][4];
87538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               unsigned c;
87638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               x[j] /= 2;
87738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               y[j] /= 2;
87838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, faces[j], level1, x[j], y[j], 0,
87938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                         rgba2, j);
88038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
881005ee9f4e05b487d455e87c6843d1d1a3c1536ffBrian Paul                  shadow_compare(sampler, rgba2, p, j);
88238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               }
88338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
88438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               for (c = 0; c < NUM_CHANNELS; c++) {
88538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                  rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]);
88638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               }
887f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            }
888f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian         }
8890dc4eea64f56cc93e5359372b08b99a2d600273cBrian      }
8900dc4eea64f56cc93e5359372b08b99a2d600273cBrian      break;
8910dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_FILTER_LINEAR:
89298ae83d5cc73b61826823c915b5c59746c2e85c7Keith Whitwell   case PIPE_TEX_FILTER_ANISO:
89338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      {
89438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         int x0[4], y0[4], x1[4], y1[4];
89538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float xw[4], yw[4]; /* weights */
89638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
89738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         linear_texcoord_4(sampler->wrap_s, s, width, x0, x1, xw);
89838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         linear_texcoord_4(sampler->wrap_t, t, height, y0, y1, yw);
89938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
90038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (j = 0; j < QUAD_SIZE; j++) {
90138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            float tx[4][4]; /* texels */
90238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            int c;
90338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, faces[j], level0, x0[j], y0[j], 0, tx, 0);
90438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, faces[j], level0, x1[j], y0[j], 0, tx, 1);
90538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, faces[j], level0, x0[j], y1[j], 0, tx, 2);
90638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, faces[j], level0, x1[j], y1[j], 0, tx, 3);
90738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
908efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul               shadow_compare4(sampler, tx, p);
9093d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            }
9103d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
91138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            /* interpolate R, G, B, A */
912f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            for (c = 0; c < 4; c++) {
91338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               rgba[c][j] = lerp_2d(xw[j], yw[j],
91438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                    tx[c][0], tx[c][1],
91538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                    tx[c][2], tx[c][3]);
916f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            }
917f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian
91838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (level0 != level1) {
91938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               /* get texels from second mipmap level and blend */
92038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               float rgba2[4][4];
92138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               x0[j] /= 2;
92238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               y0[j] /= 2;
92338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               x1[j] /= 2;
92438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               y1[j] /= 2;
92538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, faces[j], level1, x0[j], y0[j], 0, tx, 0);
92638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, faces[j], level1, x1[j], y0[j], 0, tx, 1);
92738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, faces[j], level1, x0[j], y1[j], 0, tx, 2);
92838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, faces[j], level1, x1[j], y1[j], 0, tx, 3);
92938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
930efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul                  shadow_compare4(sampler, tx, p);
93138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               }
93238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
93338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               /* interpolate R, G, B, A */
93438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               for (c = 0; c < 4; c++) {
93538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                  rgba2[c][j] = lerp_2d(xw[j], yw[j],
93638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                        tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
93738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               }
93838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
93938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               for (c = 0; c < NUM_CHANNELS; c++) {
94038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                  rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]);
94138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               }
942f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            }
943f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian         }
94409a1b912605ff48c8782dcc5aae55ac77e27037bBrian      }
94509a1b912605ff48c8782dcc5aae55ac77e27037bBrian      break;
9460dc4eea64f56cc93e5359372b08b99a2d600273cBrian   default:
9470dc4eea64f56cc93e5359372b08b99a2d600273cBrian      assert(0);
9480dc4eea64f56cc93e5359372b08b99a2d600273cBrian   }
9490dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
95034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
95134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
952dd55083ac1c13723dba6be71f161e2ca7cac7c66Brianstatic INLINE void
953dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_1d(const struct tgsi_sampler *sampler,
954a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float s[QUAD_SIZE],
955a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float t[QUAD_SIZE],
956a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float p[QUAD_SIZE],
9573ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                  boolean computeLambda,
958a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  float lodbias,
959a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  float rgba[NUM_CHANNELS][QUAD_SIZE])
960a34b8594b7b2d00404bb639621ec1ce918ba0786Brian{
961a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   static const unsigned faces[4] = {0, 0, 0, 0};
962d16b4bc32a731cb6ae320e8c187af3bc751d4138Brian   static const float tzero[4] = {0, 0, 0, 0};
9633ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul   sp_get_samples_2d_common(sampler, s, tzero, NULL,
9643ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                            computeLambda, lodbias, rgba, faces);
965a34b8594b7b2d00404bb639621ec1ce918ba0786Brian}
966a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
967a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
968dd55083ac1c13723dba6be71f161e2ca7cac7c66Brianstatic INLINE void
969dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_2d(const struct tgsi_sampler *sampler,
970a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float s[QUAD_SIZE],
971a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float t[QUAD_SIZE],
972a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float p[QUAD_SIZE],
9733ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                  boolean computeLambda,
974a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  float lodbias,
975a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  float rgba[NUM_CHANNELS][QUAD_SIZE])
976a34b8594b7b2d00404bb639621ec1ce918ba0786Brian{
977a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   static const unsigned faces[4] = {0, 0, 0, 0};
9783ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul   sp_get_samples_2d_common(sampler, s, t, p,
9793ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                            computeLambda, lodbias, rgba, faces);
980a34b8594b7b2d00404bb639621ec1ce918ba0786Brian}
981a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
982a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
983dd55083ac1c13723dba6be71f161e2ca7cac7c66Brianstatic INLINE void
984dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_3d(const struct tgsi_sampler *tgsi_sampler,
985b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  const float s[QUAD_SIZE],
986b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  const float t[QUAD_SIZE],
987b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  const float p[QUAD_SIZE],
9883ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                  boolean computeLambda,
989f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian                  float lodbias,
990b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  float rgba[NUM_CHANNELS][QUAD_SIZE])
99134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
9920b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
993aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell   const struct pipe_texture *texture = samp->texture;
994aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell   const struct pipe_sampler_state *sampler = samp->sampler;
99534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   /* get/map pipe_surfaces corresponding to 3D tex slices */
9963d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   unsigned level0, level1, j, imgFilter;
9973d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   int width, height, depth;
9983d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   float levelBlend;
9993d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   const uint face = 0;
10003d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
10013ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul   choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias,
10023d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                        &level0, &level1, &levelBlend, &imgFilter);
10033d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
10040b9e96fae9493d5d58f046e01c983a3c4267090eBrian   assert(sampler->normalized_coords);
1005b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
10060b9e96fae9493d5d58f046e01c983a3c4267090eBrian   width = texture->width[level0];
10070b9e96fae9493d5d58f046e01c983a3c4267090eBrian   height = texture->height[level0];
10080b9e96fae9493d5d58f046e01c983a3c4267090eBrian   depth = texture->depth[level0];
10093d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
10103d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   assert(width > 0);
10113d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   assert(height > 0);
10123d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   assert(depth > 0);
10133d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
10143d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   switch (imgFilter) {
10153d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   case PIPE_TEX_FILTER_NEAREST:
101638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      {
101738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         int x[4], y[4], z[4];
101838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         nearest_texcoord_4(sampler->wrap_s, s, width, x);
101938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         nearest_texcoord_4(sampler->wrap_t, t, height, y);
102038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         nearest_texcoord_4(sampler->wrap_r, p, depth, z);
102138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (j = 0; j < QUAD_SIZE; j++) {
102238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x[j], y[j], z[j], rgba, j);
102338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (level0 != level1) {
102438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               /* get texels from second mipmap level and blend */
102538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               float rgba2[4][4];
102638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               unsigned c;
102738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               x[j] /= 2;
102838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               y[j] /= 2;
102938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               z[j] /= 2;
103038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, face, level1, x[j], y[j], z[j], rgba2, j);
103138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               for (c = 0; c < NUM_CHANNELS; c++) {
103238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                  rgba[c][j] = lerp(levelBlend, rgba2[c][j], rgba[c][j]);
103338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               }
10343d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            }
10353d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         }
10363d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      }
10373d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      break;
10383d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   case PIPE_TEX_FILTER_LINEAR:
103998ae83d5cc73b61826823c915b5c59746c2e85c7Keith Whitwell   case PIPE_TEX_FILTER_ANISO:
104038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      {
104138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         int x0[4], x1[4], y0[4], y1[4], z0[4], z1[4];
104238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float xw[4], yw[4], zw[4]; /* interpolation weights */
104338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         linear_texcoord_4(sampler->wrap_s, s, width,  x0, x1, xw);
104438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         linear_texcoord_4(sampler->wrap_t, t, height, y0, y1, yw);
104538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         linear_texcoord_4(sampler->wrap_r, p, depth,  z0, z1, zw);
104638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
104738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (j = 0; j < QUAD_SIZE; j++) {
104838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            int c;
104938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            float tx0[4][4], tx1[4][4];
105038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x0[j], y0[j], z0[j], tx0, 0);
105138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x1[j], y0[j], z0[j], tx0, 1);
105238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x0[j], y1[j], z0[j], tx0, 2);
105338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x1[j], y1[j], z0[j], tx0, 3);
105438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x0[j], y0[j], z1[j], tx1, 0);
105538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x1[j], y0[j], z1[j], tx1, 1);
105638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x0[j], y1[j], z1[j], tx1, 2);
105738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x1[j], y1[j], z1[j], tx1, 3);
105838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
105938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            /* interpolate R, G, B, A */
10603d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            for (c = 0; c < 4; c++) {
106138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               rgba[c][j] = lerp_3d(xw[j], yw[j], zw[j],
106238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                    tx0[c][0], tx0[c][1],
106338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                    tx0[c][2], tx0[c][3],
106438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                    tx1[c][0], tx1[c][1],
106538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                    tx1[c][2], tx1[c][3]);
10663d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            }
10673d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
106838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (level0 != level1) {
106938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               /* get texels from second mipmap level and blend */
107038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               float rgba2[4][4];
107138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               x0[j] /= 2;
107238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               y0[j] /= 2;
107338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               z0[j] /= 2;
107438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               x1[j] /= 2;
107538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               y1[j] /= 2;
107638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               z1[j] /= 2;
107738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, face, level1, x0[j], y0[j], z0[j], tx0, 0);
107838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, face, level1, x1[j], y0[j], z0[j], tx0, 1);
107938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, face, level1, x0[j], y1[j], z0[j], tx0, 2);
108038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, face, level1, x1[j], y1[j], z0[j], tx0, 3);
108138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, face, level1, x0[j], y0[j], z1[j], tx1, 0);
108238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, face, level1, x1[j], y0[j], z1[j], tx1, 1);
108338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, face, level1, x0[j], y1[j], z1[j], tx1, 2);
108438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               get_texel(tgsi_sampler, face, level1, x1[j], y1[j], z1[j], tx1, 3);
108538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
108638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               /* interpolate R, G, B, A */
108738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               for (c = 0; c < 4; c++) {
108838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                  rgba2[c][j] = lerp_3d(xw[j], yw[j], zw[j],
108938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                        tx0[c][0], tx0[c][1],
109038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                        tx0[c][2], tx0[c][3],
109138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                        tx1[c][0], tx1[c][1],
109238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                        tx1[c][2], tx1[c][3]);
109338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               }
109438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
109538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               /* blend mipmap levels */
109638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               for (c = 0; c < NUM_CHANNELS; c++) {
109738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                  rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]);
109838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               }
10993d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            }
11003d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         }
11013d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      }
11023d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      break;
11033d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   default:
11043d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      assert(0);
11053d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   }
110634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
110734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
110834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
110934a48abd5ff82ce9748fc29191e35a0985d47c5fBrianstatic void
1110dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_cube(const struct tgsi_sampler *sampler,
1111b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                    const float s[QUAD_SIZE],
1112b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                    const float t[QUAD_SIZE],
1113b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                    const float p[QUAD_SIZE],
11143ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                    boolean computeLambda,
1115f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian                    float lodbias,
1116b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                    float rgba[NUM_CHANNELS][QUAD_SIZE])
111734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
1118a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   unsigned faces[QUAD_SIZE], j;
1119a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   float ssss[4], tttt[4];
1120b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   for (j = 0; j < QUAD_SIZE; j++) {
1121a34b8594b7b2d00404bb639621ec1ce918ba0786Brian      faces[j] = choose_cube_face(s[j], t[j], p[j], ssss + j, tttt + j);
1122b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
11233ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul   sp_get_samples_2d_common(sampler, ssss, tttt, NULL,
11243ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                            computeLambda, lodbias, rgba, faces);
112534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
112634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
112734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
1128b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrianstatic void
1129dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler,
1130b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                    const float s[QUAD_SIZE],
1131b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                    const float t[QUAD_SIZE],
1132b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                    const float p[QUAD_SIZE],
11333ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                    boolean computeLambda,
1134b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                    float lodbias,
1135b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                    float rgba[NUM_CHANNELS][QUAD_SIZE])
1136b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{
11370b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
1138aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell   const struct pipe_texture *texture = samp->texture;
1139aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell   const struct pipe_sampler_state *sampler = samp->sampler;
114036b941cdbf83bc23c95598baf7638def1632db01Brian   const uint face = 0;
1141b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   unsigned level0, level1, j, imgFilter;
1142b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   int width, height;
1143b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   float levelBlend;
1144b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
11453ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul   choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias,
1146b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                        &level0, &level1, &levelBlend, &imgFilter);
1147b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
1148b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   /* texture RECTS cannot be mipmapped */
1149b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   assert(level0 == level1);
1150b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
11510b9e96fae9493d5d58f046e01c983a3c4267090eBrian   width = texture->width[level0];
11520b9e96fae9493d5d58f046e01c983a3c4267090eBrian   height = texture->height[level0];
1153b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
1154b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   assert(width > 0);
1155b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
1156b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   switch (imgFilter) {
1157b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_FILTER_NEAREST:
115838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      {
115938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         int x[4], y[4];
116038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         nearest_texcoord_unnorm_4(sampler->wrap_s, s, width, x);
116138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         nearest_texcoord_unnorm_4(sampler->wrap_t, t, height, y);
116238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (j = 0; j < QUAD_SIZE; j++) {
116338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x[j], y[j], 0, rgba, j);
116438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
1165005ee9f4e05b487d455e87c6843d1d1a3c1536ffBrian Paul               shadow_compare(sampler, rgba, p, j);
116638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            }
1167b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         }
1168b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      }
1169b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      break;
1170b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_FILTER_LINEAR:
117198ae83d5cc73b61826823c915b5c59746c2e85c7Keith Whitwell   case PIPE_TEX_FILTER_ANISO:
117238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      {
117338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         int x0[4], y0[4], x1[4], y1[4];
117438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         float xw[4], yw[4]; /* weights */
117538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         linear_texcoord_unnorm_4(sampler->wrap_s, s, width,  x0, x1, xw);
117638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         linear_texcoord_unnorm_4(sampler->wrap_t, t, height, y0, y1, yw);
117738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian         for (j = 0; j < QUAD_SIZE; j++) {
117838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            float tx[4][4]; /* texels */
117938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            int c;
118038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x0[j], y0[j], 0, tx, 0);
118138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x1[j], y0[j], 0, tx, 1);
118238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x0[j], y1[j], 0, tx, 2);
118338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            get_texel(tgsi_sampler, face, level0, x1[j], y1[j], 0, tx, 3);
118438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
1185efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul               shadow_compare4(sampler, tx, p);
118638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            }
118738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            for (c = 0; c < 4; c++) {
118838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian               rgba[c][j] = lerp_2d(xw[j], yw[j],
118938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian                                    tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
119038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            }
1191b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         }
1192b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      }
1193b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      break;
1194b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   default:
1195b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      assert(0);
1196b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   }
1197b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian}
1198b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
1199b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
1200a34b8594b7b2d00404bb639621ec1ce918ba0786Brian/**
12013ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul * Common code for vertex/fragment program texture sampling.
1202a34b8594b7b2d00404bb639621ec1ce918ba0786Brian */
12033ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paulstatic INLINE void
12040b9e96fae9493d5d58f046e01c983a3c4267090eBriansp_get_samples(struct tgsi_sampler *tgsi_sampler,
1205b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float s[QUAD_SIZE],
1206b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float t[QUAD_SIZE],
1207b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float p[QUAD_SIZE],
12083ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul               boolean computeLambda,
1209f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian               float lodbias,
1210b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               float rgba[NUM_CHANNELS][QUAD_SIZE])
121134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
12120b9e96fae9493d5d58f046e01c983a3c4267090eBrian   const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
1213aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell   const struct pipe_texture *texture = samp->texture;
1214aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell   const struct pipe_sampler_state *sampler = samp->sampler;
12150b9e96fae9493d5d58f046e01c983a3c4267090eBrian
12160b9e96fae9493d5d58f046e01c983a3c4267090eBrian   if (!texture)
12174f23468bd0d14b8ed687a641003d587b91ad39a7Brian      return;
12184f23468bd0d14b8ed687a641003d587b91ad39a7Brian
12190b9e96fae9493d5d58f046e01c983a3c4267090eBrian   switch (texture->target) {
122070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   case PIPE_TEXTURE_1D:
12210b9e96fae9493d5d58f046e01c983a3c4267090eBrian      assert(sampler->normalized_coords);
12223ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul      sp_get_samples_1d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
122334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
122470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   case PIPE_TEXTURE_2D:
12250b9e96fae9493d5d58f046e01c983a3c4267090eBrian      if (sampler->normalized_coords)
12263ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul         sp_get_samples_2d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
1227b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      else
12283ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul         sp_get_samples_rect(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
122934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
123070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   case PIPE_TEXTURE_3D:
12310b9e96fae9493d5d58f046e01c983a3c4267090eBrian      assert(sampler->normalized_coords);
12323ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul      sp_get_samples_3d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
123334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
123470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   case PIPE_TEXTURE_CUBE:
12350b9e96fae9493d5d58f046e01c983a3c4267090eBrian      assert(sampler->normalized_coords);
12363ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul      sp_get_samples_cube(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
123734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
123834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   default:
123934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      assert(0);
124034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
12413d53d38d5e35386de4793162b9dd32e171927059Brian Paul
12423d53d38d5e35386de4793162b9dd32e171927059Brian Paul#if 0 /* DEBUG */
12433d53d38d5e35386de4793162b9dd32e171927059Brian Paul   {
12443d53d38d5e35386de4793162b9dd32e171927059Brian Paul      int i;
12453d53d38d5e35386de4793162b9dd32e171927059Brian Paul      printf("Sampled at %f, %f, %f:\n", s[0], t[0], p[0]);
12463d53d38d5e35386de4793162b9dd32e171927059Brian Paul      for (i = 0; i < 4; i++) {
12473d53d38d5e35386de4793162b9dd32e171927059Brian Paul         printf("Frag %d: %f %f %f %f\n", i,
12483d53d38d5e35386de4793162b9dd32e171927059Brian Paul                rgba[0][i],
12493d53d38d5e35386de4793162b9dd32e171927059Brian Paul                rgba[1][i],
12503d53d38d5e35386de4793162b9dd32e171927059Brian Paul                rgba[2][i],
12513d53d38d5e35386de4793162b9dd32e171927059Brian Paul                rgba[3][i]);
12523d53d38d5e35386de4793162b9dd32e171927059Brian Paul      }
12533d53d38d5e35386de4793162b9dd32e171927059Brian Paul   }
12543d53d38d5e35386de4793162b9dd32e171927059Brian Paul#endif
125534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
125634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
12573ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul
12583ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul/**
12593ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul * Called via tgsi_sampler::get_samples() when running a fragment shader.
12603ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul * Get four filtered RGBA values from the sampler's texture.
12613ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul */
12623ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paulvoid
12633ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paulsp_get_samples_fragment(struct tgsi_sampler *tgsi_sampler,
12643ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                        const float s[QUAD_SIZE],
12653ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                        const float t[QUAD_SIZE],
12663ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                        const float p[QUAD_SIZE],
12673ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                        float lodbias,
12683ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                        float rgba[NUM_CHANNELS][QUAD_SIZE])
12693ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul{
12703ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul   sp_get_samples(tgsi_sampler, s, t, p, TRUE, lodbias, rgba);
12713ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul}
12723ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul
12733ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul
12743ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul/**
12753ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul * Called via tgsi_sampler::get_samples() when running a vertex shader.
12763ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul * Get four filtered RGBA values from the sampler's texture.
12773ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul */
12783ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paulvoid
12793ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paulsp_get_samples_vertex(struct tgsi_sampler *tgsi_sampler,
12803ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                      const float s[QUAD_SIZE],
12813ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                      const float t[QUAD_SIZE],
12823ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                      const float p[QUAD_SIZE],
12833ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                      float lodbias,
12843ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul                      float rgba[NUM_CHANNELS][QUAD_SIZE])
12853ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul{
12863ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul   sp_get_samples(tgsi_sampler, s, t, p, FALSE, lodbias, rgba);
12873ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul}
1288