sp_tex_sample.c revision b1c8fa5b6002296d9abe21c06d5cb81a3f70828a
10dc4eea64f56cc93e5359372b08b99a2d600273cBrian/**************************************************************************
20dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
30dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
40dc4eea64f56cc93e5359372b08b99a2d600273cBrian * All Rights Reserved.
50dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
60dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Permission is hereby granted, free of charge, to any person obtaining a
70dc4eea64f56cc93e5359372b08b99a2d600273cBrian * copy of this software and associated documentation files (the
80dc4eea64f56cc93e5359372b08b99a2d600273cBrian * "Software"), to deal in the Software without restriction, including
90dc4eea64f56cc93e5359372b08b99a2d600273cBrian * without limitation the rights to use, copy, modify, merge, publish,
100dc4eea64f56cc93e5359372b08b99a2d600273cBrian * distribute, sub license, and/or sell copies of the Software, and to
110dc4eea64f56cc93e5359372b08b99a2d600273cBrian * permit persons to whom the Software is furnished to do so, subject to
120dc4eea64f56cc93e5359372b08b99a2d600273cBrian * the following conditions:
130dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
140dc4eea64f56cc93e5359372b08b99a2d600273cBrian * The above copyright notice and this permission notice (including the
150dc4eea64f56cc93e5359372b08b99a2d600273cBrian * next paragraph) shall be included in all copies or substantial portions
160dc4eea64f56cc93e5359372b08b99a2d600273cBrian * of the Software.
170dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
180dc4eea64f56cc93e5359372b08b99a2d600273cBrian * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
190dc4eea64f56cc93e5359372b08b99a2d600273cBrian * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
200dc4eea64f56cc93e5359372b08b99a2d600273cBrian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
210dc4eea64f56cc93e5359372b08b99a2d600273cBrian * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
220dc4eea64f56cc93e5359372b08b99a2d600273cBrian * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
230dc4eea64f56cc93e5359372b08b99a2d600273cBrian * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
240dc4eea64f56cc93e5359372b08b99a2d600273cBrian * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
250dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
260dc4eea64f56cc93e5359372b08b99a2d600273cBrian **************************************************************************/
270dc4eea64f56cc93e5359372b08b99a2d600273cBrian
280dc4eea64f56cc93e5359372b08b99a2d600273cBrian/**
290dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Texture sampling
300dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
310dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Authors:
320dc4eea64f56cc93e5359372b08b99a2d600273cBrian *   Brian Paul
330dc4eea64f56cc93e5359372b08b99a2d600273cBrian */
340dc4eea64f56cc93e5359372b08b99a2d600273cBrian
3508f33a025100dea2d951e6d628891fe294b18082Brian#include "sp_context.h"
36b91de8a6e7d74d38698b6dad9f34040e484e69afBrian#include "sp_headers.h"
370dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "sp_surface.h"
380dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "sp_tex_sample.h"
3970eb7996f265f3634dabda078f13d1be3533cc65Brian#include "sp_tile_cache.h"
400dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "pipe/p_context.h"
410dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "pipe/p_defines.h"
427de874ec2c7b9e3aff7f81b7e30045b45381fbadMichal Krol#include "pipe/p_util.h"
436acd63a4980951727939c0dd545a0324965b3834José Fonseca#include "tgsi/exec/tgsi_exec.h"
440dc4eea64f56cc93e5359372b08b99a2d600273cBrian
450dc4eea64f56cc93e5359372b08b99a2d600273cBrian
4608f33a025100dea2d951e6d628891fe294b18082Brian/*
4708f33a025100dea2d951e6d628891fe294b18082Brian * Note, the FRAC macro has to work perfectly.  Otherwise you'll sometimes
4808f33a025100dea2d951e6d628891fe294b18082Brian * see 1-pixel bands of improperly weighted linear-filtered textures.
4908f33a025100dea2d951e6d628891fe294b18082Brian * The tests/texwrap.c demo is a good test.
5008f33a025100dea2d951e6d628891fe294b18082Brian * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0.
5108f33a025100dea2d951e6d628891fe294b18082Brian * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x).
5208f33a025100dea2d951e6d628891fe294b18082Brian */
5370af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell#define FRAC(f)  ((f) - ifloor(f))
5408f33a025100dea2d951e6d628891fe294b18082Brian
5508f33a025100dea2d951e6d628891fe294b18082Brian
5608f33a025100dea2d951e6d628891fe294b18082Brian/**
5708f33a025100dea2d951e6d628891fe294b18082Brian * Linear interpolation macro
5808f33a025100dea2d951e6d628891fe294b18082Brian */
590dc4eea64f56cc93e5359372b08b99a2d600273cBrian#define LERP(T, A, B)  ( (A) + (T) * ((B) - (A)) )
600dc4eea64f56cc93e5359372b08b99a2d600273cBrian
610dc4eea64f56cc93e5359372b08b99a2d600273cBrian
620dc4eea64f56cc93e5359372b08b99a2d600273cBrian/**
630dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Do 2D/biliner interpolation of float values.
640dc4eea64f56cc93e5359372b08b99a2d600273cBrian * v00, v10, v01 and v11 are typically four texture samples in a square/box.
650dc4eea64f56cc93e5359372b08b99a2d600273cBrian * a and b are the horizontal and vertical interpolants.
660dc4eea64f56cc93e5359372b08b99a2d600273cBrian * It's important that this function is inlined when compiled with
670dc4eea64f56cc93e5359372b08b99a2d600273cBrian * optimization!  If we find that's not true on some systems, convert
680dc4eea64f56cc93e5359372b08b99a2d600273cBrian * to a macro.
690dc4eea64f56cc93e5359372b08b99a2d600273cBrian */
70b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic INLINE float
71b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianlerp_2d(float a, float b,
72b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian        float v00, float v10, float v01, float v11)
730dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
74b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   const float temp0 = LERP(a, v00, v10);
75b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   const float temp1 = LERP(a, v01, v11);
760dc4eea64f56cc93e5359372b08b99a2d600273cBrian   return LERP(b, temp0, temp1);
770dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
780dc4eea64f56cc93e5359372b08b99a2d600273cBrian
790dc4eea64f56cc93e5359372b08b99a2d600273cBrian
800dc4eea64f56cc93e5359372b08b99a2d600273cBrian/**
81906768316d9521a32d9a7eebc9edaf76c06a98a7Brian * If A is a signed integer, A % B doesn't give the right value for A < 0
82906768316d9521a32d9a7eebc9edaf76c06a98a7Brian * (in terms of texture repeat).  Just casting to unsigned fixes that.
830dc4eea64f56cc93e5359372b08b99a2d600273cBrian */
84906768316d9521a32d9a7eebc9edaf76c06a98a7Brian#define REMAINDER(A, B) ((unsigned) (A) % (unsigned) (B))
8508f33a025100dea2d951e6d628891fe294b18082Brian
8608f33a025100dea2d951e6d628891fe294b18082Brian
8708f33a025100dea2d951e6d628891fe294b18082Brian/**
8808f33a025100dea2d951e6d628891fe294b18082Brian * Apply texture coord wrapping mode and return integer texture index.
8908f33a025100dea2d951e6d628891fe294b18082Brian * \param wrapMode  PIPE_TEX_WRAP_x
9008f33a025100dea2d951e6d628891fe294b18082Brian * \param s  the texcoord
9108f33a025100dea2d951e6d628891fe294b18082Brian * \param size  the texture image size
9208f33a025100dea2d951e6d628891fe294b18082Brian * \return  integer texture index
9308f33a025100dea2d951e6d628891fe294b18082Brian */
9470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwellstatic INLINE int
9570af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwellnearest_texcoord(unsigned wrapMode, float s, unsigned size)
960dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
9770af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   int i;
980dc4eea64f56cc93e5359372b08b99a2d600273cBrian   switch (wrapMode) {
990dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_WRAP_REPEAT:
10008f33a025100dea2d951e6d628891fe294b18082Brian      /* s limited to [0,1) */
10108f33a025100dea2d951e6d628891fe294b18082Brian      /* i limited to [0,size-1] */
10270af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell      i = ifloor(s * size);
103906768316d9521a32d9a7eebc9edaf76c06a98a7Brian      i = REMAINDER(i, size);
10408f33a025100dea2d951e6d628891fe294b18082Brian      return i;
1050dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_WRAP_CLAMP:
10608f33a025100dea2d951e6d628891fe294b18082Brian      /* s limited to [0,1] */
10708f33a025100dea2d951e6d628891fe294b18082Brian      /* i limited to [0,size-1] */
10808f33a025100dea2d951e6d628891fe294b18082Brian      if (s <= 0.0F)
10908f33a025100dea2d951e6d628891fe294b18082Brian         i = 0;
11008f33a025100dea2d951e6d628891fe294b18082Brian      else if (s >= 1.0F)
11108f33a025100dea2d951e6d628891fe294b18082Brian         i = size - 1;
11208f33a025100dea2d951e6d628891fe294b18082Brian      else
11370af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell         i = ifloor(s * size);
11408f33a025100dea2d951e6d628891fe294b18082Brian      return i;
11508f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
11608f33a025100dea2d951e6d628891fe294b18082Brian      {
11708f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [min,max] */
11808f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [0, size-1] */
119b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = 1.0F / (2.0F * size);
120b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
12108f33a025100dea2d951e6d628891fe294b18082Brian         if (s < min)
12208f33a025100dea2d951e6d628891fe294b18082Brian            i = 0;
12308f33a025100dea2d951e6d628891fe294b18082Brian         else if (s > max)
12408f33a025100dea2d951e6d628891fe294b18082Brian            i = size - 1;
12508f33a025100dea2d951e6d628891fe294b18082Brian         else
12670af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell            i = ifloor(s * size);
12708f33a025100dea2d951e6d628891fe294b18082Brian      }
12808f33a025100dea2d951e6d628891fe294b18082Brian      return i;
12908f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
13008f33a025100dea2d951e6d628891fe294b18082Brian      {
13108f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [min,max] */
13208f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [-1, size] */
133b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = -1.0F / (2.0F * size);
134b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
13508f33a025100dea2d951e6d628891fe294b18082Brian         if (s <= min)
13608f33a025100dea2d951e6d628891fe294b18082Brian            i = -1;
13708f33a025100dea2d951e6d628891fe294b18082Brian         else if (s >= max)
13808f33a025100dea2d951e6d628891fe294b18082Brian            i = size;
13908f33a025100dea2d951e6d628891fe294b18082Brian         else
14070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell            i = ifloor(s * size);
14108f33a025100dea2d951e6d628891fe294b18082Brian      }
14208f33a025100dea2d951e6d628891fe294b18082Brian      return i;
14308f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_REPEAT:
14408f33a025100dea2d951e6d628891fe294b18082Brian      {
145b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = 1.0F / (2.0F * size);
146b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
14770af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell         const int flr = ifloor(s);
148b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         float u;
14908f33a025100dea2d951e6d628891fe294b18082Brian         if (flr & 1)
150b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian            u = 1.0F - (s - (float) flr);
15108f33a025100dea2d951e6d628891fe294b18082Brian         else
152b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian            u = s - (float) flr;
15308f33a025100dea2d951e6d628891fe294b18082Brian         if (u < min)
15408f33a025100dea2d951e6d628891fe294b18082Brian            i = 0;
15508f33a025100dea2d951e6d628891fe294b18082Brian         else if (u > max)
15608f33a025100dea2d951e6d628891fe294b18082Brian            i = size - 1;
15708f33a025100dea2d951e6d628891fe294b18082Brian         else
15870af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell            i = ifloor(u * size);
15908f33a025100dea2d951e6d628891fe294b18082Brian      }
16008f33a025100dea2d951e6d628891fe294b18082Brian      return i;
16108f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP:
16208f33a025100dea2d951e6d628891fe294b18082Brian      {
16308f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [0,1] */
16408f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [0,size-1] */
165b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float u = FABSF(s);
16608f33a025100dea2d951e6d628891fe294b18082Brian         if (u <= 0.0F)
16708f33a025100dea2d951e6d628891fe294b18082Brian            i = 0;
16808f33a025100dea2d951e6d628891fe294b18082Brian         else if (u >= 1.0F)
16908f33a025100dea2d951e6d628891fe294b18082Brian            i = size - 1;
17008f33a025100dea2d951e6d628891fe294b18082Brian         else
17170af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell            i = ifloor(u * size);
17208f33a025100dea2d951e6d628891fe294b18082Brian      }
17308f33a025100dea2d951e6d628891fe294b18082Brian      return i;
17408f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
17508f33a025100dea2d951e6d628891fe294b18082Brian      {
17608f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [min,max] */
17708f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [0, size-1] */
178b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = 1.0F / (2.0F * size);
179b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
180b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float u = FABSF(s);
18108f33a025100dea2d951e6d628891fe294b18082Brian         if (u < min)
18208f33a025100dea2d951e6d628891fe294b18082Brian            i = 0;
18308f33a025100dea2d951e6d628891fe294b18082Brian         else if (u > max)
18408f33a025100dea2d951e6d628891fe294b18082Brian            i = size - 1;
18508f33a025100dea2d951e6d628891fe294b18082Brian         else
18670af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell            i = ifloor(u * size);
18708f33a025100dea2d951e6d628891fe294b18082Brian      }
18808f33a025100dea2d951e6d628891fe294b18082Brian      return i;
18908f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
19008f33a025100dea2d951e6d628891fe294b18082Brian      {
19108f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [min,max] */
19208f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [0, size-1] */
193b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = -1.0F / (2.0F * size);
194b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
195b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float u = FABSF(s);
19608f33a025100dea2d951e6d628891fe294b18082Brian         if (u < min)
19708f33a025100dea2d951e6d628891fe294b18082Brian            i = -1;
19808f33a025100dea2d951e6d628891fe294b18082Brian         else if (u > max)
19908f33a025100dea2d951e6d628891fe294b18082Brian            i = size;
20008f33a025100dea2d951e6d628891fe294b18082Brian         else
20170af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell            i = ifloor(u * size);
20208f33a025100dea2d951e6d628891fe294b18082Brian      }
20308f33a025100dea2d951e6d628891fe294b18082Brian      return i;
2040dc4eea64f56cc93e5359372b08b99a2d600273cBrian   default:
2050dc4eea64f56cc93e5359372b08b99a2d600273cBrian      assert(0);
20608f33a025100dea2d951e6d628891fe294b18082Brian      return 0;
2070dc4eea64f56cc93e5359372b08b99a2d600273cBrian   }
2080dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
2090dc4eea64f56cc93e5359372b08b99a2d600273cBrian
21008f33a025100dea2d951e6d628891fe294b18082Brian
21108f33a025100dea2d951e6d628891fe294b18082Brian/**
21208f33a025100dea2d951e6d628891fe294b18082Brian * Used to compute texel locations for linear sampling.
21308f33a025100dea2d951e6d628891fe294b18082Brian * \param wrapMode  PIPE_TEX_WRAP_x
21408f33a025100dea2d951e6d628891fe294b18082Brian * \param s  the texcoord
21508f33a025100dea2d951e6d628891fe294b18082Brian * \param size  the texture image size
21608f33a025100dea2d951e6d628891fe294b18082Brian * \param i0  returns first texture index
21708f33a025100dea2d951e6d628891fe294b18082Brian * \param i1  returns second texture index (usually *i0 + 1)
21808f33a025100dea2d951e6d628891fe294b18082Brian * \param a  returns blend factor/weight between texture indexes
21908f33a025100dea2d951e6d628891fe294b18082Brian */
2200dc4eea64f56cc93e5359372b08b99a2d600273cBrianstatic INLINE void
22170af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwelllinear_texcoord(unsigned wrapMode, float s, unsigned size,
22270af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell                int *i0, int *i1, float *a)
2230dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
224b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   float u;
2250dc4eea64f56cc93e5359372b08b99a2d600273cBrian   switch (wrapMode) {
2260dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_WRAP_REPEAT:
22708f33a025100dea2d951e6d628891fe294b18082Brian      u = s * size - 0.5F;
228906768316d9521a32d9a7eebc9edaf76c06a98a7Brian      *i0 = REMAINDER(ifloor(u), size);
229906768316d9521a32d9a7eebc9edaf76c06a98a7Brian      *i1 = REMAINDER(*i0 + 1, size);
2300dc4eea64f56cc93e5359372b08b99a2d600273cBrian      break;
2310dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_WRAP_CLAMP:
23208f33a025100dea2d951e6d628891fe294b18082Brian      if (s <= 0.0F)
23308f33a025100dea2d951e6d628891fe294b18082Brian         u = 0.0F;
23408f33a025100dea2d951e6d628891fe294b18082Brian      else if (s >= 1.0F)
235b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         u = (float) size;
23608f33a025100dea2d951e6d628891fe294b18082Brian      else
23708f33a025100dea2d951e6d628891fe294b18082Brian         u = s * size;
23808f33a025100dea2d951e6d628891fe294b18082Brian      u -= 0.5F;
23970af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell      *i0 = ifloor(u);
24008f33a025100dea2d951e6d628891fe294b18082Brian      *i1 = *i0 + 1;
24108f33a025100dea2d951e6d628891fe294b18082Brian      break;
24208f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
24308f33a025100dea2d951e6d628891fe294b18082Brian      if (s <= 0.0F)
24408f33a025100dea2d951e6d628891fe294b18082Brian         u = 0.0F;
24508f33a025100dea2d951e6d628891fe294b18082Brian      else if (s >= 1.0F)
246b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         u = (float) size;
24708f33a025100dea2d951e6d628891fe294b18082Brian      else
24808f33a025100dea2d951e6d628891fe294b18082Brian         u = s * size;
24908f33a025100dea2d951e6d628891fe294b18082Brian      u -= 0.5F;
25070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell      *i0 = ifloor(u);
25108f33a025100dea2d951e6d628891fe294b18082Brian      *i1 = *i0 + 1;
25208f33a025100dea2d951e6d628891fe294b18082Brian      if (*i0 < 0)
25308f33a025100dea2d951e6d628891fe294b18082Brian         *i0 = 0;
25470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell      if (*i1 >= (int) size)
25508f33a025100dea2d951e6d628891fe294b18082Brian         *i1 = size - 1;
25608f33a025100dea2d951e6d628891fe294b18082Brian      break;
25708f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
25808f33a025100dea2d951e6d628891fe294b18082Brian      {
259b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = -1.0F / (2.0F * size);
260b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
26108f33a025100dea2d951e6d628891fe294b18082Brian         if (s <= min)
26208f33a025100dea2d951e6d628891fe294b18082Brian            u = min * size;
26308f33a025100dea2d951e6d628891fe294b18082Brian         else if (s >= max)
26408f33a025100dea2d951e6d628891fe294b18082Brian            u = max * size;
26508f33a025100dea2d951e6d628891fe294b18082Brian         else
26608f33a025100dea2d951e6d628891fe294b18082Brian            u = s * size;
26708f33a025100dea2d951e6d628891fe294b18082Brian         u -= 0.5F;
26870af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell         *i0 = ifloor(u);
26908f33a025100dea2d951e6d628891fe294b18082Brian         *i1 = *i0 + 1;
27008f33a025100dea2d951e6d628891fe294b18082Brian      }
27108f33a025100dea2d951e6d628891fe294b18082Brian      break;
27208f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_REPEAT:
27308f33a025100dea2d951e6d628891fe294b18082Brian      {
27470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell         const int flr = ifloor(s);
27508f33a025100dea2d951e6d628891fe294b18082Brian         if (flr & 1)
276b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian            u = 1.0F - (s - (float) flr);
27708f33a025100dea2d951e6d628891fe294b18082Brian         else
278b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian            u = s - (float) flr;
27908f33a025100dea2d951e6d628891fe294b18082Brian         u = (u * size) - 0.5F;
28070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell         *i0 = ifloor(u);
28108f33a025100dea2d951e6d628891fe294b18082Brian         *i1 = *i0 + 1;
28208f33a025100dea2d951e6d628891fe294b18082Brian         if (*i0 < 0)
28308f33a025100dea2d951e6d628891fe294b18082Brian            *i0 = 0;
28470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell         if (*i1 >= (int) size)
28508f33a025100dea2d951e6d628891fe294b18082Brian            *i1 = size - 1;
28608f33a025100dea2d951e6d628891fe294b18082Brian      }
28708f33a025100dea2d951e6d628891fe294b18082Brian      break;
28808f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP:
28908f33a025100dea2d951e6d628891fe294b18082Brian      u = FABSF(s);
29008f33a025100dea2d951e6d628891fe294b18082Brian      if (u >= 1.0F)
291b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         u = (float) size;
29208f33a025100dea2d951e6d628891fe294b18082Brian      else
29308f33a025100dea2d951e6d628891fe294b18082Brian         u *= size;
29408f33a025100dea2d951e6d628891fe294b18082Brian      u -= 0.5F;
29570af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell      *i0 = ifloor(u);
29608f33a025100dea2d951e6d628891fe294b18082Brian      *i1 = *i0 + 1;
29708f33a025100dea2d951e6d628891fe294b18082Brian      break;
29808f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
29908f33a025100dea2d951e6d628891fe294b18082Brian      u = FABSF(s);
30008f33a025100dea2d951e6d628891fe294b18082Brian      if (u >= 1.0F)
301b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         u = (float) size;
30208f33a025100dea2d951e6d628891fe294b18082Brian      else
30308f33a025100dea2d951e6d628891fe294b18082Brian         u *= size;
30408f33a025100dea2d951e6d628891fe294b18082Brian      u -= 0.5F;
30570af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell      *i0 = ifloor(u);
30608f33a025100dea2d951e6d628891fe294b18082Brian      *i1 = *i0 + 1;
30708f33a025100dea2d951e6d628891fe294b18082Brian      if (*i0 < 0)
30808f33a025100dea2d951e6d628891fe294b18082Brian         *i0 = 0;
30970af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell      if (*i1 >= (int) size)
31008f33a025100dea2d951e6d628891fe294b18082Brian         *i1 = size - 1;
31108f33a025100dea2d951e6d628891fe294b18082Brian      break;
31208f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
31308f33a025100dea2d951e6d628891fe294b18082Brian      {
314b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = -1.0F / (2.0F * size);
315b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
31608f33a025100dea2d951e6d628891fe294b18082Brian         u = FABSF(s);
31708f33a025100dea2d951e6d628891fe294b18082Brian         if (u <= min)
31808f33a025100dea2d951e6d628891fe294b18082Brian            u = min * size;
31908f33a025100dea2d951e6d628891fe294b18082Brian         else if (u >= max)
32008f33a025100dea2d951e6d628891fe294b18082Brian            u = max * size;
32108f33a025100dea2d951e6d628891fe294b18082Brian         else
32208f33a025100dea2d951e6d628891fe294b18082Brian            u *= size;
32308f33a025100dea2d951e6d628891fe294b18082Brian         u -= 0.5F;
32470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell         *i0 = ifloor(u);
32508f33a025100dea2d951e6d628891fe294b18082Brian         *i1 = *i0 + 1;
32608f33a025100dea2d951e6d628891fe294b18082Brian      }
3270dc4eea64f56cc93e5359372b08b99a2d600273cBrian      break;
3280dc4eea64f56cc93e5359372b08b99a2d600273cBrian   default:
3290dc4eea64f56cc93e5359372b08b99a2d600273cBrian      assert(0);
3300dc4eea64f56cc93e5359372b08b99a2d600273cBrian   }
33108f33a025100dea2d951e6d628891fe294b18082Brian   *a = FRAC(u);
3320dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
3330dc4eea64f56cc93e5359372b08b99a2d600273cBrian
3340dc4eea64f56cc93e5359372b08b99a2d600273cBrian
335b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian/**
336b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * For RECT textures / unnormalized texcoords
337b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * Only a subset of wrap modes supported.
338b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian */
339b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrianstatic INLINE int
340b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBriannearest_texcoord_unnorm(unsigned wrapMode, float s, unsigned size)
341b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{
342b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   int i;
343b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   switch (wrapMode) {
344b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP:
345b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      i = ifloor(s);
346b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      return CLAMP(i, 0, size-1);
347b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
348b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      /* fall-through */
349b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
350b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      return ifloor( CLAMP(s, 0.5F, size - 0.5F) );
351b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   default:
352b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      assert(0);
353b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      return 0;
354b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   }
355b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian}
356b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
357b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
358b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian/**
359b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * For RECT textures / unnormalized texcoords.
360b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * Only a subset of wrap modes supported.
361b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian */
362b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrianstatic INLINE void
363b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrianlinear_texcoord_unnorm(unsigned wrapMode, float s, unsigned size,
364b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                       int *i0, int *i1, float *a)
365b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{
366b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   switch (wrapMode) {
367b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP:
368b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      /* Not exactly what the spec says, but it matches NVIDIA output */
369b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      s = CLAMP(s - 0.5F, 0.0, size - 1.0);
370b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      *i0 = ifloor(s);
371b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      *i1 = *i0 + 1;
372b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      break;
373b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
374b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      /* fall-through */
375b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
376b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      s = CLAMP(s, 0.5F, size - 0.5F);
377b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      s -= 0.5F;
378b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      *i0 = ifloor(s);
379b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      *i1 = *i0 + 1;
380b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      if (*i1 > size - 1)
381b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         *i1 = size - 1;
382b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      break;
383b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   default:
384b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      assert(0);
385b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   }
386b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   *a = FRAC(s);
387b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian}
388b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
389b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
39070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwellstatic unsigned
391a34b8594b7b2d00404bb639621ec1ce918ba0786Brianchoose_cube_face(float rx, float ry, float rz, float *newS, float *newT)
39234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
39334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   /*
39434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      major axis
39534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      direction     target                             sc     tc    ma
39634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      ----------    -------------------------------    ---    ---   ---
39734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       +rx          TEXTURE_CUBE_MAP_POSITIVE_X_EXT    -rz    -ry   rx
39834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       -rx          TEXTURE_CUBE_MAP_NEGATIVE_X_EXT    +rz    -ry   rx
39934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       +ry          TEXTURE_CUBE_MAP_POSITIVE_Y_EXT    +rx    +rz   ry
40034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       -ry          TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT    +rx    -rz   ry
40134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       +rz          TEXTURE_CUBE_MAP_POSITIVE_Z_EXT    +rx    -ry   rz
40234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       -rz          TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT    -rx    -ry   rz
40334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   */
404b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   const float arx = FABSF(rx), ary = FABSF(ry), arz = FABSF(rz);
40570af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   unsigned face;
406b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   float sc, tc, ma;
40734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
40834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   if (arx > ary && arx > arz) {
40934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      if (rx >= 0.0F) {
41034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_POS_X;
41134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = -rz;
41234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
41334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arx;
41434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
41534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      else {
41634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_NEG_X;
41734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rz;
41834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
41934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arx;
42034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
42134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
42234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   else if (ary > arx && ary > arz) {
42334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      if (ry >= 0.0F) {
42434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_POS_Y;
42534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rx;
42634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = rz;
42734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = ary;
42834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
42934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      else {
43034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_NEG_Y;
43134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rx;
43234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -rz;
43334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = ary;
43434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
43534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
43634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   else {
43734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      if (rz > 0.0F) {
43834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_POS_Z;
43934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rx;
44034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
44134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arz;
44234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
44334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      else {
44434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_NEG_Z;
44534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = -rx;
44634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
44734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arz;
44834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
44934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
45034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
451a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   *newS = ( sc / ma + 1.0F ) * 0.5F;
452a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   *newT = ( tc / ma + 1.0F ) * 0.5F;
45334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
45434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   return face;
45534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
45634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
45734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
458b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/**
459b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * Examine the quad's texture coordinates to compute the partial
460b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * derivatives w.r.t X and Y, then compute lambda (level of detail).
461b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian *
462b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * This is only done for fragment shaders, not vertex shaders.
463b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian */
464b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic float
465b4480285ed5098f1c862690ee105dd46f5e6cd1eBriancompute_lambda(struct tgsi_sampler *sampler,
466b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float s[QUAD_SIZE],
467b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float t[QUAD_SIZE],
468f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian               const float p[QUAD_SIZE],
469f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian               float lodbias)
470b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian{
471b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   float rho, lambda;
472b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
473b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   assert(sampler->state->normalized_coords);
474b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
475b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   assert(s);
476b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   {
477b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dsdx = s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT];
478b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dsdy = s[QUAD_TOP_LEFT]     - s[QUAD_BOTTOM_LEFT];
479b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      dsdx = FABSF(dsdx);
480b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      dsdy = FABSF(dsdy);
481b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      rho = MAX2(dsdx, dsdy) * sampler->texture->width[0];
482b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
483b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   if (t) {
484b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT];
485b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dtdy = t[QUAD_TOP_LEFT]     - t[QUAD_BOTTOM_LEFT];
486b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float max;
487b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      dtdx = FABSF(dtdx);
488b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      dtdy = FABSF(dtdy);
489b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      max = MAX2(dtdx, dtdy) * sampler->texture->height[0];
490b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      rho = MAX2(rho, max);
491b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
492b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   if (p) {
493b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dpdx = p[QUAD_BOTTOM_RIGHT] - p[QUAD_BOTTOM_LEFT];
494b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dpdy = p[QUAD_TOP_LEFT]     - p[QUAD_BOTTOM_LEFT];
495b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float max;
496b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      dpdx = FABSF(dpdx);
497b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      dpdy = FABSF(dpdy);
498b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      max = MAX2(dpdx, dpdy) * sampler->texture->depth[0];
499b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      rho = MAX2(rho, max);
500b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
501b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
502b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   lambda = LOG2(rho);
503f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian   lambda += lodbias + sampler->state->lod_bias;
504b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   lambda = CLAMP(lambda, sampler->state->min_lod, sampler->state->max_lod);
505b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
506b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   return lambda;
507b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian}
508b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
509b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
510f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian/**
511c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * Do several things here:
512c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 1. Compute lambda from the texcoords, if needed
513c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 2. Determine if we're minifying or magnifying
514c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 3. If minifying, choose mipmap levels
515c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 4. Return image filter to use within mipmap images
516f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian */
517f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrianstatic void
518c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brianchoose_mipmap_levels(struct tgsi_sampler *sampler,
519c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     const float s[QUAD_SIZE],
520c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     const float t[QUAD_SIZE],
521c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     const float p[QUAD_SIZE],
522c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     float lodbias,
523c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     unsigned *level0, unsigned *level1, float *levelBlend,
524c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     unsigned *imgFilter)
52509a1b912605ff48c8782dcc5aae55ac77e27037bBrian{
526c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian   if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) {
527c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      /* no mipmap selection needed */
5280c6bbd41bd6dc1041eaca7c907d3768d107c1afaBrian      *level0 = *level1 = CLAMP((int) sampler->state->min_lod,
5290c6bbd41bd6dc1041eaca7c907d3768d107c1afaBrian                                0, (int) sampler->texture->last_level);
53008c9534107fcaf06f9b801551524ed5dc724db13Brian
53108c9534107fcaf06f9b801551524ed5dc724db13Brian      if (sampler->state->min_img_filter != sampler->state->mag_img_filter) {
53208c9534107fcaf06f9b801551524ed5dc724db13Brian         /* non-mipmapped texture, but still need to determine if doing
53308c9534107fcaf06f9b801551524ed5dc724db13Brian          * minification or magnification.
53408c9534107fcaf06f9b801551524ed5dc724db13Brian          */
53508c9534107fcaf06f9b801551524ed5dc724db13Brian         float lambda = compute_lambda(sampler, s, t, p, lodbias);
5363b2a291888d8e62787de03f8529806fb562bd186Brian         if (lambda <= 0.0) {
53708c9534107fcaf06f9b801551524ed5dc724db13Brian            *imgFilter = sampler->state->mag_img_filter;
53808c9534107fcaf06f9b801551524ed5dc724db13Brian         }
53908c9534107fcaf06f9b801551524ed5dc724db13Brian         else {
54008c9534107fcaf06f9b801551524ed5dc724db13Brian            *imgFilter = sampler->state->min_img_filter;
54108c9534107fcaf06f9b801551524ed5dc724db13Brian         }
54208c9534107fcaf06f9b801551524ed5dc724db13Brian      }
5433b2a291888d8e62787de03f8529806fb562bd186Brian      else {
5443b2a291888d8e62787de03f8529806fb562bd186Brian         *imgFilter = sampler->state->mag_img_filter;
5453b2a291888d8e62787de03f8529806fb562bd186Brian      }
546c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian   }
547c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian   else {
548c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      float lambda;
549c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian
550c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      if (1)
551c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* fragment shader */
552c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         lambda = compute_lambda(sampler, s, t, p, lodbias);
553c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      else
554c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* vertex shader */
555c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         lambda = lodbias; /* not really a bias, but absolute LOD */
556c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian
5573b2a291888d8e62787de03f8529806fb562bd186Brian      if (lambda <= 0.0) { /* XXX threshold depends on the filter */
558c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* magnifying */
559c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         *imgFilter = sampler->state->mag_img_filter;
5604da1cdf78fa3b954840650fa46cf72da5daf149fBrian         *level0 = *level1 = 0;
561f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      }
562c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      else {
563c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* minifying */
564c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         *imgFilter = sampler->state->min_img_filter;
565c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian
566c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* choose mipmap level(s) and compute the blend factor between them */
567c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NEAREST) {
568c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            /* Nearest mipmap level */
569c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            const int lvl = (int) (lambda + 0.5);
570c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            *level0 =
5714da1cdf78fa3b954840650fa46cf72da5daf149fBrian            *level1 = CLAMP(lvl, 0, (int) sampler->texture->last_level);
572c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         }
573c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         else {
574c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            /* Linear interpolation between mipmap levels */
575c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            const int lvl = (int) lambda;
5764da1cdf78fa3b954840650fa46cf72da5daf149fBrian            *level0 = CLAMP(lvl,     0, (int) sampler->texture->last_level);
5774da1cdf78fa3b954840650fa46cf72da5daf149fBrian            *level1 = CLAMP(lvl + 1, 0, (int) sampler->texture->last_level);
578c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            *levelBlend = FRAC(lambda);  /* blending weight between levels */
579c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         }
580f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      }
58109a1b912605ff48c8782dcc5aae55ac77e27037bBrian   }
58209a1b912605ff48c8782dcc5aae55ac77e27037bBrian}
58309a1b912605ff48c8782dcc5aae55ac77e27037bBrian
58408f33a025100dea2d951e6d628891fe294b18082Brian
585b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/**
586a13de2464dd034ff117f9314df5757d068cae8e5Brian * Get a texel from a texture, using the texture tile cache.
587a13de2464dd034ff117f9314df5757d068cae8e5Brian *
588b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param face  the cube face in 0..5
589b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param level  the mipmap level
590b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param x  the x coord of texel within 2D image
591b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param y  the y coord of texel within 2D image
59270eb7996f265f3634dabda078f13d1be3533cc65Brian * \param z  which slice of a 3D texture
593b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param rgba  the quad to put the texel/color into
594b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param j  which element of the rgba quad to write to
59570eb7996f265f3634dabda078f13d1be3533cc65Brian *
59670eb7996f265f3634dabda078f13d1be3533cc65Brian * XXX maybe move this into sp_tile_cache.c and merge with the
59770eb7996f265f3634dabda078f13d1be3533cc65Brian * sp_get_cached_tile_tex() function.  Also, get 4 texels instead of 1...
598b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian */
599b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic void
600b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianget_texel(struct tgsi_sampler *sampler,
60170eb7996f265f3634dabda078f13d1be3533cc65Brian          unsigned face, unsigned level, int x, int y, int z,
602a13de2464dd034ff117f9314df5757d068cae8e5Brian          float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j)
603b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian{
60470eb7996f265f3634dabda078f13d1be3533cc65Brian   const int tx = x % TILE_SIZE;
60570eb7996f265f3634dabda078f13d1be3533cc65Brian   const int ty = y % TILE_SIZE;
60670eb7996f265f3634dabda078f13d1be3533cc65Brian   const struct softpipe_cached_tile *tile
60770eb7996f265f3634dabda078f13d1be3533cc65Brian      = sp_get_cached_tile_tex(sampler->pipe, sampler->cache,
60870eb7996f265f3634dabda078f13d1be3533cc65Brian                               x, y, z, face, level);
60970eb7996f265f3634dabda078f13d1be3533cc65Brian   rgba[0][j] = tile->data.color[ty][tx][0];
61070eb7996f265f3634dabda078f13d1be3533cc65Brian   rgba[1][j] = tile->data.color[ty][tx][1];
61170eb7996f265f3634dabda078f13d1be3533cc65Brian   rgba[2][j] = tile->data.color[ty][tx][2];
61270eb7996f265f3634dabda078f13d1be3533cc65Brian   rgba[3][j] = tile->data.color[ty][tx][3];
613b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian}
614b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
615b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
6163d8c05f7320151898dd224c1daaf3118e1f7ea34Brian/**
6173d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * Compare texcoord 'p' (aka R) against texture value 'rgba[0]'
6183d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * When we sampled the depth texture, the depth value was put into all
6193d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * RGBA channels.  We look at the red channel here.
6203d8c05f7320151898dd224c1daaf3118e1f7ea34Brian */
6213d8c05f7320151898dd224c1daaf3118e1f7ea34Brianstatic INLINE void
6223d8c05f7320151898dd224c1daaf3118e1f7ea34Brianshadow_compare(uint compare_func,
6233d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               float rgba[NUM_CHANNELS][QUAD_SIZE],
6243d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               const float p[QUAD_SIZE],
6253d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               uint j)
6263d8c05f7320151898dd224c1daaf3118e1f7ea34Brian{
6273d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   int k;
6283d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   switch (compare_func) {
6293d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_LESS:
6303d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] < rgba[0][j];
6313d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
6323d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_LEQUAL:
6333d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] <= rgba[0][j];
6343d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
6353d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_GREATER:
6363d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] > rgba[0][j];
6373d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
6383d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_GEQUAL:
6393d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] >= rgba[0][j];
6403d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
6413d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_EQUAL:
6423d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] == rgba[0][j];
6433d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
6443d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_NOTEQUAL:
6453d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] != rgba[0][j];
6463d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
6473d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_ALWAYS:
6483d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = 1;
6493d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
6503d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_NEVER:
6513d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = 0;
6523d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
6533d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   default:
6543d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      assert(0);
6553d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   }
6563d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
6573d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   rgba[0][j] = rgba[1][j] = rgba[2][j] = (float) k;
6583d8c05f7320151898dd224c1daaf3118e1f7ea34Brian}
6593d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
660b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
661b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/**
662a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Common code for sampling 1D/2D/cube textures.
663a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Could probably extend for 3D...
6640dc4eea64f56cc93e5359372b08b99a2d600273cBrian */
665e12810d92ffb3547680b227bf88937c03018112bBrianstatic void
666a34b8594b7b2d00404bb639621ec1ce918ba0786Briansp_get_samples_2d_common(struct tgsi_sampler *sampler,
667a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         const float s[QUAD_SIZE],
668a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         const float t[QUAD_SIZE],
669a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         const float p[QUAD_SIZE],
670a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         float lodbias,
671a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         float rgba[NUM_CHANNELS][QUAD_SIZE],
672a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         const unsigned faces[4])
6730dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
6743d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   const uint compare_func = sampler->state->compare_func;
675f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian   unsigned level0, level1, j, imgFilter;
676f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian   int width, height;
677c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian   float levelBlend;
678a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
679c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian   choose_mipmap_levels(sampler, s, t, p, lodbias,
680c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                        &level0, &level1, &levelBlend, &imgFilter);
68109a1b912605ff48c8782dcc5aae55ac77e27037bBrian
682b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   assert(sampler->state->normalized_coords);
683b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
684b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   width = sampler->texture->width[level0];
685b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   height = sampler->texture->height[level0];
68609a1b912605ff48c8782dcc5aae55ac77e27037bBrian
687b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   assert(width > 0);
688612cfb749c3526eeb446bbc631bf24716522f373Brian
689b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   switch (imgFilter) {
6900dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_FILTER_NEAREST:
691b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      for (j = 0; j < QUAD_SIZE; j++) {
692b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         int x = nearest_texcoord(sampler->state->wrap_s, s[j], width);
693b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         int y = nearest_texcoord(sampler->state->wrap_t, t[j], height);
694df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, faces[j], level0, x, y, 0, rgba, j);
6953d8c05f7320151898dd224c1daaf3118e1f7ea34Brian         if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
6963d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            shadow_compare(compare_func, rgba, p, j);
6973d8c05f7320151898dd224c1daaf3118e1f7ea34Brian         }
698f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian
699f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian         if (level0 != level1) {
700f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            /* get texels from second mipmap level and blend */
701f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            float rgba2[4][4];
702f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            unsigned c;
703f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            x = x / 2;
704f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            y = y / 2;
705df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, faces[j], level1, x, y, 0, rgba2, j);
7063d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
7073d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               shadow_compare(compare_func, rgba2, p, j);
7083d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            }
7093d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
710f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            for (c = 0; c < NUM_CHANNELS; c++) {
71117c2f56dc3f2f58ba89d8e305e7d9b423e3cae16Brian               rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]);
712f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            }
713f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian         }
7140dc4eea64f56cc93e5359372b08b99a2d600273cBrian      }
7150dc4eea64f56cc93e5359372b08b99a2d600273cBrian      break;
7160dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_FILTER_LINEAR:
717b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      for (j = 0; j < QUAD_SIZE; j++) {
718b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         float tx[4][4], a, b;
719b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         int x0, y0, x1, y1, c;
720b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         linear_texcoord(sampler->state->wrap_s, s[j], width,  &x0, &x1, &a);
721b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         linear_texcoord(sampler->state->wrap_t, t[j], height, &y0, &y1, &b);
722df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, faces[j], level0, x0, y0, 0, tx, 0);
723df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, faces[j], level0, x1, y0, 0, tx, 1);
724df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, faces[j], level0, x0, y1, 0, tx, 2);
725df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, faces[j], level0, x1, y1, 0, tx, 3);
7263d8c05f7320151898dd224c1daaf3118e1f7ea34Brian         if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
7273d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            shadow_compare(compare_func, tx, p, 0);
7283d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            shadow_compare(compare_func, tx, p, 1);
7293d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            shadow_compare(compare_func, tx, p, 2);
7303d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            shadow_compare(compare_func, tx, p, 3);
7313d8c05f7320151898dd224c1daaf3118e1f7ea34Brian         }
7323d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
733b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         for (c = 0; c < 4; c++) {
734b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian            rgba[c][j] = lerp_2d(a, b, tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
735b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         }
736f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian
737f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian         if (level0 != level1) {
738f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            /* get texels from second mipmap level and blend */
739f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            float rgba2[4][4];
740f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            x0 = x0 / 2;
741f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            y0 = y0 / 2;
742f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            x1 = x1 / 2;
743f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            y1 = y1 / 2;
744df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, faces[j], level1, x0, y0, 0, tx, 0);
745df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, faces[j], level1, x1, y0, 0, tx, 1);
746df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, faces[j], level1, x0, y1, 0, tx, 2);
747df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, faces[j], level1, x1, y1, 0, tx, 3);
7483d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
7493d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               shadow_compare(compare_func, tx, p, 0);
7503d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               shadow_compare(compare_func, tx, p, 1);
7513d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               shadow_compare(compare_func, tx, p, 2);
7523d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               shadow_compare(compare_func, tx, p, 3);
7533d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            }
7543d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
755f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            for (c = 0; c < 4; c++) {
756f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian               rgba2[c][j] = lerp_2d(a, b,
757f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian                                     tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
758f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            }
759f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian
760f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            for (c = 0; c < NUM_CHANNELS; c++) {
761c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian               rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]);
762f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            }
763f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian         }
76409a1b912605ff48c8782dcc5aae55ac77e27037bBrian      }
76509a1b912605ff48c8782dcc5aae55ac77e27037bBrian      break;
7660dc4eea64f56cc93e5359372b08b99a2d600273cBrian   default:
7670dc4eea64f56cc93e5359372b08b99a2d600273cBrian      assert(0);
7680dc4eea64f56cc93e5359372b08b99a2d600273cBrian   }
7690dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
77034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
77134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
77234a48abd5ff82ce9748fc29191e35a0985d47c5fBrianstatic void
773a34b8594b7b2d00404bb639621ec1ce918ba0786Briansp_get_samples_1d(struct tgsi_sampler *sampler,
774a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float s[QUAD_SIZE],
775a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float t[QUAD_SIZE],
776a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float p[QUAD_SIZE],
777a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  float lodbias,
778a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  float rgba[NUM_CHANNELS][QUAD_SIZE])
779a34b8594b7b2d00404bb639621ec1ce918ba0786Brian{
780a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   static const unsigned faces[4] = {0, 0, 0, 0};
781d16b4bc32a731cb6ae320e8c187af3bc751d4138Brian   static const float tzero[4] = {0, 0, 0, 0};
782d16b4bc32a731cb6ae320e8c187af3bc751d4138Brian   sp_get_samples_2d_common(sampler, s, tzero, NULL, lodbias, rgba, faces);
783a34b8594b7b2d00404bb639621ec1ce918ba0786Brian}
784a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
785a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
786a34b8594b7b2d00404bb639621ec1ce918ba0786Brianstatic void
787a34b8594b7b2d00404bb639621ec1ce918ba0786Briansp_get_samples_2d(struct tgsi_sampler *sampler,
788a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float s[QUAD_SIZE],
789a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float t[QUAD_SIZE],
790a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float p[QUAD_SIZE],
791a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  float lodbias,
792a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  float rgba[NUM_CHANNELS][QUAD_SIZE])
793a34b8594b7b2d00404bb639621ec1ce918ba0786Brian{
794a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   static const unsigned faces[4] = {0, 0, 0, 0};
7953d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   sp_get_samples_2d_common(sampler, s, t, p, lodbias, rgba, faces);
796a34b8594b7b2d00404bb639621ec1ce918ba0786Brian}
797a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
798a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
799a34b8594b7b2d00404bb639621ec1ce918ba0786Brianstatic void
800b4480285ed5098f1c862690ee105dd46f5e6cd1eBriansp_get_samples_3d(struct tgsi_sampler *sampler,
801b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  const float s[QUAD_SIZE],
802b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  const float t[QUAD_SIZE],
803b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  const float p[QUAD_SIZE],
804f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian                  float lodbias,
805b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  float rgba[NUM_CHANNELS][QUAD_SIZE])
80634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
80734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   /* get/map pipe_surfaces corresponding to 3D tex slices */
8083d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   unsigned level0, level1, j, imgFilter;
8093d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   int width, height, depth;
8103d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   float levelBlend;
8113d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   const uint face = 0;
8123d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
8133d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   choose_mipmap_levels(sampler, s, t, p, lodbias,
8143d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                        &level0, &level1, &levelBlend, &imgFilter);
8153d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
816b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   assert(sampler->state->normalized_coords);
817b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
818b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   width = sampler->texture->width[level0];
819b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   height = sampler->texture->height[level0];
820b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   depth = sampler->texture->depth[level0];
8213d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
8223d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   assert(width > 0);
8233d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   assert(height > 0);
8243d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   assert(depth > 0);
8253d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
8263d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   switch (imgFilter) {
8273d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   case PIPE_TEX_FILTER_NEAREST:
8283d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      for (j = 0; j < QUAD_SIZE; j++) {
8293d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         int x = nearest_texcoord(sampler->state->wrap_s, s[j], width);
8303d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         int y = nearest_texcoord(sampler->state->wrap_t, t[j], height);
8313d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         int z = nearest_texcoord(sampler->state->wrap_r, p[j], depth);
832df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, face, level0, x, y, z, rgba, j);
8333d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
8343d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         if (level0 != level1) {
8353d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            /* get texels from second mipmap level and blend */
8363d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            float rgba2[4][4];
8373d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            unsigned c;
8383d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            x /= 2;
8393d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            y /= 2;
8403d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            z /= 2;
841df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, face, level1, x, y, z, rgba2, j);
8423d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            for (c = 0; c < NUM_CHANNELS; c++) {
8433d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian               rgba[c][j] = LERP(levelBlend, rgba2[c][j], rgba[c][j]);
8443d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            }
8453d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         }
8463d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      }
8473d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      break;
8483d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   case PIPE_TEX_FILTER_LINEAR:
8493d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      for (j = 0; j < QUAD_SIZE; j++) {
850df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         float texel0[4][4], texel1[4][4];
851df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         float xw, yw, zw; /* interpolation weights */
8523d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         int x0, x1, y0, y1, z0, z1, c;
8533d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         linear_texcoord(sampler->state->wrap_s, s[j], width,  &x0, &x1, &xw);
8543d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         linear_texcoord(sampler->state->wrap_t, t[j], height, &y0, &y1, &yw);
8553d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         linear_texcoord(sampler->state->wrap_r, p[j], depth,  &z0, &z1, &zw);
856df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, face, level0, x0, y0, z0, texel0, 0);
857df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, face, level0, x1, y0, z0, texel0, 1);
858df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, face, level0, x0, y1, z0, texel0, 2);
859df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, face, level0, x1, y1, z0, texel0, 3);
860df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, face, level0, x0, y0, z1, texel1, 0);
861df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, face, level0, x1, y0, z1, texel1, 1);
862df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, face, level0, x0, y1, z1, texel1, 2);
863df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, face, level0, x1, y1, z1, texel1, 3);
8643d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
8653d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         /* 3D lerp */
8663d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         for (c = 0; c < 4; c++) {
8673d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            float ctemp0[4][4], ctemp1[4][4];
8683d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            ctemp0[c][j] = lerp_2d(xw, yw,
8693d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                                   texel0[c][0], texel0[c][1],
8703d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                                   texel0[c][2], texel0[c][3]);
8713d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            ctemp1[c][j] = lerp_2d(xw, yw,
8723d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                                   texel1[c][0], texel1[c][1],
8733d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                                   texel1[c][2], texel1[c][3]);
8743d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            rgba[c][j] = LERP(zw, ctemp0[c][j], ctemp1[c][j]);
8753d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         }
8763d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
8773d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         if (level0 != level1) {
8783d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            /* get texels from second mipmap level and blend */
8793d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            float rgba2[4][4];
8803d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            x0 /= 2;
8813d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            y0 /= 2;
8823d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            z0 /= 2;
8833d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            x1 /= 2;
8843d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            y1 /= 2;
8853d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            z1 /= 2;
886df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, face, level1, x0, y0, z0, texel0, 0);
887df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, face, level1, x1, y0, z0, texel0, 1);
888df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, face, level1, x0, y1, z0, texel0, 2);
889df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, face, level1, x1, y1, z0, texel0, 3);
890df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, face, level1, x0, y0, z1, texel1, 0);
891df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, face, level1, x1, y0, z1, texel1, 1);
892df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, face, level1, x0, y1, z1, texel1, 2);
893df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, face, level1, x1, y1, z1, texel1, 3);
8943d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
8953d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            /* 3D lerp */
8963d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            for (c = 0; c < 4; c++) {
8973d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian               float ctemp0[4][4], ctemp1[4][4];
8983d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian               ctemp0[c][j] = lerp_2d(xw, yw,
8993d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                                      texel0[c][0], texel0[c][1],
9003d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                                      texel0[c][2], texel0[c][3]);
9013d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian               ctemp1[c][j] = lerp_2d(xw, yw,
9023d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                                      texel1[c][0], texel1[c][1],
9033d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                                      texel1[c][2], texel1[c][3]);
9043d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian               rgba2[c][j] = LERP(zw, ctemp0[c][j], ctemp1[c][j]);
9053d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            }
9063d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
9073d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            /* blend mipmap levels */
9083d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            for (c = 0; c < NUM_CHANNELS; c++) {
9093d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian               rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]);
9103d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            }
9113d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         }
9123d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      }
9133d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      break;
9143d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   default:
9153d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      assert(0);
9163d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   }
91734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
91834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
91934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
92034a48abd5ff82ce9748fc29191e35a0985d47c5fBrianstatic void
921b4480285ed5098f1c862690ee105dd46f5e6cd1eBriansp_get_samples_cube(struct tgsi_sampler *sampler,
922b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                    const float s[QUAD_SIZE],
923b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                    const float t[QUAD_SIZE],
924b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                    const float p[QUAD_SIZE],
925f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian                    float lodbias,
926b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                    float rgba[NUM_CHANNELS][QUAD_SIZE])
92734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
928a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   unsigned faces[QUAD_SIZE], j;
929a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   float ssss[4], tttt[4];
930b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   for (j = 0; j < QUAD_SIZE; j++) {
931a34b8594b7b2d00404bb639621ec1ce918ba0786Brian      faces[j] = choose_cube_face(s[j], t[j], p[j], ssss + j, tttt + j);
932b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
933a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   sp_get_samples_2d_common(sampler, ssss, tttt, NULL, lodbias, rgba, faces);
93434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
93534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
93634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
937b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrianstatic void
938b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBriansp_get_samples_rect(struct tgsi_sampler *sampler,
939b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                    const float s[QUAD_SIZE],
940b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                    const float t[QUAD_SIZE],
941b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                    const float p[QUAD_SIZE],
942b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                    float lodbias,
943b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                    float rgba[NUM_CHANNELS][QUAD_SIZE])
944b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{
945b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   //sp_get_samples_2d_common(sampler, s, t, p, lodbias, rgba, faces);
946b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   static const uint face = 0;
947b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   const uint compare_func = sampler->state->compare_func;
948b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   unsigned level0, level1, j, imgFilter;
949b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   int width, height;
950b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   float levelBlend;
951b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
952b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   choose_mipmap_levels(sampler, s, t, p, lodbias,
953b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian                        &level0, &level1, &levelBlend, &imgFilter);
954b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
955b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   /* texture RECTS cannot be mipmapped */
956b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   assert(level0 == level1);
957b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
958b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   width = sampler->texture->width[level0];
959b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   height = sampler->texture->height[level0];
960b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
961b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   assert(width > 0);
962b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
963b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   switch (imgFilter) {
964b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_FILTER_NEAREST:
965b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      for (j = 0; j < QUAD_SIZE; j++) {
966b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         int x = nearest_texcoord_unnorm(sampler->state->wrap_s, s[j], width);
967b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         int y = nearest_texcoord_unnorm(sampler->state->wrap_t, t[j], height);
968b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         get_texel(sampler, face, level0, x, y, 0, rgba, j);
969b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
970b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian            shadow_compare(compare_func, rgba, p, j);
971b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         }
972b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      }
973b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      break;
974b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   case PIPE_TEX_FILTER_LINEAR:
975b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      for (j = 0; j < QUAD_SIZE; j++) {
976b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         float tx[4][4], a, b;
977b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         int x0, y0, x1, y1, c;
978b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         linear_texcoord_unnorm(sampler->state->wrap_s, s[j], width,  &x0, &x1, &a);
979b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         linear_texcoord_unnorm(sampler->state->wrap_t, t[j], height, &y0, &y1, &b);
980b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         get_texel(sampler, face, level0, x0, y0, 0, tx, 0);
981b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         get_texel(sampler, face, level0, x1, y0, 0, tx, 1);
982b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         get_texel(sampler, face, level0, x0, y1, 0, tx, 2);
983b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         get_texel(sampler, face, level0, x1, y1, 0, tx, 3);
984b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
985b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian            shadow_compare(compare_func, tx, p, 0);
986b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian            shadow_compare(compare_func, tx, p, 1);
987b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian            shadow_compare(compare_func, tx, p, 2);
988b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian            shadow_compare(compare_func, tx, p, 3);
989b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         }
990b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
991b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         for (c = 0; c < 4; c++) {
992b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian            rgba[c][j] = lerp_2d(a, b, tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
993b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         }
994b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      }
995b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      break;
996b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   default:
997b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      assert(0);
998b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   }
999b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian}
1000b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
1001b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
1002b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
1003b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
1004a34b8594b7b2d00404bb639621ec1ce918ba0786Brian/**
1005a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Called via tgsi_sampler::get_samples()
1006a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Use the sampler's state setting to get a filtered RGBA value
1007753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * from the sampler's texture.
1008a34b8594b7b2d00404bb639621ec1ce918ba0786Brian *
1009a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * XXX we can implement many versions of this function, each
1010a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * tightly coded for a specific combination of sampler state
1011a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * (nearest + repeat), (bilinear mipmap + clamp), etc.
1012a34b8594b7b2d00404bb639621ec1ce918ba0786Brian *
1013a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * The update_samplers() function in st_atom_sampler.c could create
1014a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * a new tgsi_sampler object for each state combo it finds....
1015a34b8594b7b2d00404bb639621ec1ce918ba0786Brian */
101634a48abd5ff82ce9748fc29191e35a0985d47c5fBrianvoid
1017b4480285ed5098f1c862690ee105dd46f5e6cd1eBriansp_get_samples(struct tgsi_sampler *sampler,
1018b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float s[QUAD_SIZE],
1019b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float t[QUAD_SIZE],
1020b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float p[QUAD_SIZE],
1021f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian               float lodbias,
1022b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               float rgba[NUM_CHANNELS][QUAD_SIZE])
102334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
10244f23468bd0d14b8ed687a641003d587b91ad39a7Brian   if (!sampler->texture)
10254f23468bd0d14b8ed687a641003d587b91ad39a7Brian      return;
10264f23468bd0d14b8ed687a641003d587b91ad39a7Brian
102734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   switch (sampler->texture->target) {
102870af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   case PIPE_TEXTURE_1D:
1029b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      assert(sampler->state->normalized_coords);
1030f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      sp_get_samples_1d(sampler, s, t, p, lodbias, rgba);
103134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
103270af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   case PIPE_TEXTURE_2D:
1033b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      if (sampler->state->normalized_coords)
1034b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         sp_get_samples_2d(sampler, s, t, p, lodbias, rgba);
1035b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      else
1036b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         sp_get_samples_rect(sampler, s, t, p, lodbias, rgba);
103734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
103870af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   case PIPE_TEXTURE_3D:
1039b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      assert(sampler->state->normalized_coords);
1040f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      sp_get_samples_3d(sampler, s, t, p, lodbias, rgba);
104134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
104270af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   case PIPE_TEXTURE_CUBE:
1043b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      assert(sampler->state->normalized_coords);
1044f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      sp_get_samples_cube(sampler, s, t, p, lodbias, rgba);
104534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
104634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   default:
104734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      assert(0);
104834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
104934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
105034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
1051