sp_tex_sample.c revision 6acd63a4980951727939c0dd545a0324965b3834
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
33570af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwellstatic unsigned
336a34b8594b7b2d00404bb639621ec1ce918ba0786Brianchoose_cube_face(float rx, float ry, float rz, float *newS, float *newT)
33734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
33834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   /*
33934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      major axis
34034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      direction     target                             sc     tc    ma
34134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      ----------    -------------------------------    ---    ---   ---
34234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       +rx          TEXTURE_CUBE_MAP_POSITIVE_X_EXT    -rz    -ry   rx
34334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       -rx          TEXTURE_CUBE_MAP_NEGATIVE_X_EXT    +rz    -ry   rx
34434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       +ry          TEXTURE_CUBE_MAP_POSITIVE_Y_EXT    +rx    +rz   ry
34534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       -ry          TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT    +rx    -rz   ry
34634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       +rz          TEXTURE_CUBE_MAP_POSITIVE_Z_EXT    +rx    -ry   rz
34734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       -rz          TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT    -rx    -ry   rz
34834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   */
349b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   const float arx = FABSF(rx), ary = FABSF(ry), arz = FABSF(rz);
35070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   unsigned face;
351b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   float sc, tc, ma;
35234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
35334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   if (arx > ary && arx > arz) {
35434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      if (rx >= 0.0F) {
35534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_POS_X;
35634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = -rz;
35734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
35834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arx;
35934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
36034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      else {
36134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_NEG_X;
36234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rz;
36334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
36434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arx;
36534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
36634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
36734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   else if (ary > arx && ary > arz) {
36834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      if (ry >= 0.0F) {
36934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_POS_Y;
37034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rx;
37134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = rz;
37234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = ary;
37334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
37434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      else {
37534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_NEG_Y;
37634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rx;
37734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -rz;
37834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = ary;
37934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
38034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
38134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   else {
38234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      if (rz > 0.0F) {
38334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_POS_Z;
38434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rx;
38534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
38634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arz;
38734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
38834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      else {
38934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_NEG_Z;
39034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = -rx;
39134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
39234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arz;
39334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
39434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
39534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
396a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   *newS = ( sc / ma + 1.0F ) * 0.5F;
397a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   *newT = ( tc / ma + 1.0F ) * 0.5F;
39834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
39934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   return face;
40034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
40134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
40234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
403b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/**
404b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * Examine the quad's texture coordinates to compute the partial
405b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * derivatives w.r.t X and Y, then compute lambda (level of detail).
406b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian *
407b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * This is only done for fragment shaders, not vertex shaders.
408b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian */
409b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic float
410b4480285ed5098f1c862690ee105dd46f5e6cd1eBriancompute_lambda(struct tgsi_sampler *sampler,
411b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float s[QUAD_SIZE],
412b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float t[QUAD_SIZE],
413f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian               const float p[QUAD_SIZE],
414f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian               float lodbias)
415b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian{
416b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   float rho, lambda;
417b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
418b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   assert(s);
419b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   {
420b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dsdx = s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT];
421b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dsdy = s[QUAD_TOP_LEFT]     - s[QUAD_BOTTOM_LEFT];
422b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      dsdx = FABSF(dsdx);
423b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      dsdy = FABSF(dsdy);
424369eefc34c8d7acdb881ea5b0516406d71344fc4Brian      rho = MAX2(dsdx, dsdy);
425369eefc34c8d7acdb881ea5b0516406d71344fc4Brian      if (sampler->state->normalized_coords)
426753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer         rho *= sampler->texture->width[0];
427b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
428b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   if (t) {
429b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT];
430b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dtdy = t[QUAD_TOP_LEFT]     - t[QUAD_BOTTOM_LEFT];
431b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float max;
432b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      dtdx = FABSF(dtdx);
433b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      dtdy = FABSF(dtdy);
434369eefc34c8d7acdb881ea5b0516406d71344fc4Brian      max = MAX2(dtdx, dtdy);
435369eefc34c8d7acdb881ea5b0516406d71344fc4Brian      if (sampler->state->normalized_coords)
436753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer         max *= sampler->texture->height[0];
437b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      rho = MAX2(rho, max);
438b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
439b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   if (p) {
440b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dpdx = p[QUAD_BOTTOM_RIGHT] - p[QUAD_BOTTOM_LEFT];
441b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dpdy = p[QUAD_TOP_LEFT]     - p[QUAD_BOTTOM_LEFT];
442b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float max;
443b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      dpdx = FABSF(dpdx);
444b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      dpdy = FABSF(dpdy);
445369eefc34c8d7acdb881ea5b0516406d71344fc4Brian      max = MAX2(dpdx, dpdy);
446369eefc34c8d7acdb881ea5b0516406d71344fc4Brian      if (sampler->state->normalized_coords)
447753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer         max *= sampler->texture->depth[0];
448b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      rho = MAX2(rho, max);
449b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
450b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
451b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   lambda = LOG2(rho);
452f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian   lambda += lodbias + sampler->state->lod_bias;
453b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   lambda = CLAMP(lambda, sampler->state->min_lod, sampler->state->max_lod);
454b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
455b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   return lambda;
456b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian}
457b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
458b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
459f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian/**
460c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * Do several things here:
461c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 1. Compute lambda from the texcoords, if needed
462c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 2. Determine if we're minifying or magnifying
463c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 3. If minifying, choose mipmap levels
464c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 4. Return image filter to use within mipmap images
465f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian */
466f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrianstatic void
467c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brianchoose_mipmap_levels(struct tgsi_sampler *sampler,
468c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     const float s[QUAD_SIZE],
469c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     const float t[QUAD_SIZE],
470c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     const float p[QUAD_SIZE],
471c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     float lodbias,
472c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     unsigned *level0, unsigned *level1, float *levelBlend,
473c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     unsigned *imgFilter)
47409a1b912605ff48c8782dcc5aae55ac77e27037bBrian{
475c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian   if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) {
476c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      /* no mipmap selection needed */
477c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      *imgFilter = sampler->state->mag_img_filter;
4784da1cdf78fa3b954840650fa46cf72da5daf149fBrian      *level0 = *level1 = (int) sampler->state->min_lod;
479c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian   }
480c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian   else {
481c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      float lambda;
482c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian
483c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      if (1)
484c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* fragment shader */
485c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         lambda = compute_lambda(sampler, s, t, p, lodbias);
486c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      else
487c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* vertex shader */
488c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         lambda = lodbias; /* not really a bias, but absolute LOD */
489c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian
490c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      if (lambda < 0.0) { /* XXX threshold depends on the filter */
491c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* magnifying */
492c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         *imgFilter = sampler->state->mag_img_filter;
4934da1cdf78fa3b954840650fa46cf72da5daf149fBrian         *level0 = *level1 = 0;
494f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      }
495c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      else {
496c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* minifying */
497c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         *imgFilter = sampler->state->min_img_filter;
498c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian
499c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* choose mipmap level(s) and compute the blend factor between them */
500c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NEAREST) {
501c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            /* Nearest mipmap level */
502c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            const int lvl = (int) (lambda + 0.5);
503c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            *level0 =
5044da1cdf78fa3b954840650fa46cf72da5daf149fBrian            *level1 = CLAMP(lvl, 0, (int) sampler->texture->last_level);
505c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         }
506c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         else {
507c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            /* Linear interpolation between mipmap levels */
508c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            const int lvl = (int) lambda;
5094da1cdf78fa3b954840650fa46cf72da5daf149fBrian            *level0 = CLAMP(lvl,     0, (int) sampler->texture->last_level);
5104da1cdf78fa3b954840650fa46cf72da5daf149fBrian            *level1 = CLAMP(lvl + 1, 0, (int) sampler->texture->last_level);
511c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            *levelBlend = FRAC(lambda);  /* blending weight between levels */
512c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         }
513f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      }
51409a1b912605ff48c8782dcc5aae55ac77e27037bBrian   }
51509a1b912605ff48c8782dcc5aae55ac77e27037bBrian}
51609a1b912605ff48c8782dcc5aae55ac77e27037bBrian
51708f33a025100dea2d951e6d628891fe294b18082Brian
518b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/**
519a13de2464dd034ff117f9314df5757d068cae8e5Brian * Get a texel from a texture, using the texture tile cache.
520a13de2464dd034ff117f9314df5757d068cae8e5Brian *
521b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param face  the cube face in 0..5
522b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param level  the mipmap level
523b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param x  the x coord of texel within 2D image
524b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param y  the y coord of texel within 2D image
52570eb7996f265f3634dabda078f13d1be3533cc65Brian * \param z  which slice of a 3D texture
526b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param rgba  the quad to put the texel/color into
527b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param j  which element of the rgba quad to write to
52870eb7996f265f3634dabda078f13d1be3533cc65Brian *
52970eb7996f265f3634dabda078f13d1be3533cc65Brian * XXX maybe move this into sp_tile_cache.c and merge with the
53070eb7996f265f3634dabda078f13d1be3533cc65Brian * sp_get_cached_tile_tex() function.  Also, get 4 texels instead of 1...
531b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian */
532b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic void
533b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianget_texel(struct tgsi_sampler *sampler,
53470eb7996f265f3634dabda078f13d1be3533cc65Brian          unsigned face, unsigned level, int x, int y, int z,
535a13de2464dd034ff117f9314df5757d068cae8e5Brian          float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j)
536b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian{
53770eb7996f265f3634dabda078f13d1be3533cc65Brian   const int tx = x % TILE_SIZE;
53870eb7996f265f3634dabda078f13d1be3533cc65Brian   const int ty = y % TILE_SIZE;
53970eb7996f265f3634dabda078f13d1be3533cc65Brian   const struct softpipe_cached_tile *tile
54070eb7996f265f3634dabda078f13d1be3533cc65Brian      = sp_get_cached_tile_tex(sampler->pipe, sampler->cache,
54170eb7996f265f3634dabda078f13d1be3533cc65Brian                               x, y, z, face, level);
54270eb7996f265f3634dabda078f13d1be3533cc65Brian   rgba[0][j] = tile->data.color[ty][tx][0];
54370eb7996f265f3634dabda078f13d1be3533cc65Brian   rgba[1][j] = tile->data.color[ty][tx][1];
54470eb7996f265f3634dabda078f13d1be3533cc65Brian   rgba[2][j] = tile->data.color[ty][tx][2];
54570eb7996f265f3634dabda078f13d1be3533cc65Brian   rgba[3][j] = tile->data.color[ty][tx][3];
546b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian}
547b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
548b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
5493d8c05f7320151898dd224c1daaf3118e1f7ea34Brian/**
5503d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * Compare texcoord 'p' (aka R) against texture value 'rgba[0]'
5513d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * When we sampled the depth texture, the depth value was put into all
5523d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * RGBA channels.  We look at the red channel here.
5533d8c05f7320151898dd224c1daaf3118e1f7ea34Brian */
5543d8c05f7320151898dd224c1daaf3118e1f7ea34Brianstatic INLINE void
5553d8c05f7320151898dd224c1daaf3118e1f7ea34Brianshadow_compare(uint compare_func,
5563d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               float rgba[NUM_CHANNELS][QUAD_SIZE],
5573d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               const float p[QUAD_SIZE],
5583d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               uint j)
5593d8c05f7320151898dd224c1daaf3118e1f7ea34Brian{
5603d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   int k;
5613d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   switch (compare_func) {
5623d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_LESS:
5633d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] < rgba[0][j];
5643d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
5653d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_LEQUAL:
5663d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] <= rgba[0][j];
5673d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
5683d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_GREATER:
5693d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] > rgba[0][j];
5703d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
5713d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_GEQUAL:
5723d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] >= rgba[0][j];
5733d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
5743d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_EQUAL:
5753d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] == rgba[0][j];
5763d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
5773d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_NOTEQUAL:
5783d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = p[j] != rgba[0][j];
5793d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
5803d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_ALWAYS:
5813d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = 1;
5823d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
5833d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   case PIPE_FUNC_NEVER:
5843d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      k = 0;
5853d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      break;
5863d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   default:
5873d8c05f7320151898dd224c1daaf3118e1f7ea34Brian      assert(0);
5883d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   }
5893d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
5903d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   rgba[0][j] = rgba[1][j] = rgba[2][j] = (float) k;
5913d8c05f7320151898dd224c1daaf3118e1f7ea34Brian}
5923d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
593b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
594b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/**
595a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Common code for sampling 1D/2D/cube textures.
596a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Could probably extend for 3D...
5970dc4eea64f56cc93e5359372b08b99a2d600273cBrian */
598e12810d92ffb3547680b227bf88937c03018112bBrianstatic void
599a34b8594b7b2d00404bb639621ec1ce918ba0786Briansp_get_samples_2d_common(struct tgsi_sampler *sampler,
600a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         const float s[QUAD_SIZE],
601a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         const float t[QUAD_SIZE],
602a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         const float p[QUAD_SIZE],
603a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         float lodbias,
604a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         float rgba[NUM_CHANNELS][QUAD_SIZE],
605a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                         const unsigned faces[4])
6060dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
6073d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   const uint compare_func = sampler->state->compare_func;
608f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian   unsigned level0, level1, j, imgFilter;
609f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian   int width, height;
610c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian   float levelBlend;
611a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
612c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian   choose_mipmap_levels(sampler, s, t, p, lodbias,
613c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                        &level0, &level1, &levelBlend, &imgFilter);
61409a1b912605ff48c8782dcc5aae55ac77e27037bBrian
615369eefc34c8d7acdb881ea5b0516406d71344fc4Brian   if (sampler->state->normalized_coords) {
616753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      width = sampler->texture->width[level0];
617753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      height = sampler->texture->height[level0];
618369eefc34c8d7acdb881ea5b0516406d71344fc4Brian   }
619369eefc34c8d7acdb881ea5b0516406d71344fc4Brian   else {
620ee295fccdd0c94cb6b8af4dfb30283e39f548223Michal Krol      width = height = 1;
621369eefc34c8d7acdb881ea5b0516406d71344fc4Brian   }
62209a1b912605ff48c8782dcc5aae55ac77e27037bBrian
623b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   assert(width > 0);
624612cfb749c3526eeb446bbc631bf24716522f373Brian
625b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   switch (imgFilter) {
6260dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_FILTER_NEAREST:
627b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      for (j = 0; j < QUAD_SIZE; j++) {
628b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         int x = nearest_texcoord(sampler->state->wrap_s, s[j], width);
629b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         int y = nearest_texcoord(sampler->state->wrap_t, t[j], height);
630df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, faces[j], level0, x, y, 0, rgba, j);
6313d8c05f7320151898dd224c1daaf3118e1f7ea34Brian         if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
6323d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            shadow_compare(compare_func, rgba, p, j);
6333d8c05f7320151898dd224c1daaf3118e1f7ea34Brian         }
634f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian
635f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian         if (level0 != level1) {
636f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            /* get texels from second mipmap level and blend */
637f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            float rgba2[4][4];
638f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            unsigned c;
639f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            x = x / 2;
640f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            y = y / 2;
641df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, faces[j], level1, x, y, 0, rgba2, j);
6423d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
6433d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               shadow_compare(compare_func, rgba2, p, j);
6443d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            }
6453d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
646f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            for (c = 0; c < NUM_CHANNELS; c++) {
64717c2f56dc3f2f58ba89d8e305e7d9b423e3cae16Brian               rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]);
648f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            }
649f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian         }
6500dc4eea64f56cc93e5359372b08b99a2d600273cBrian      }
6510dc4eea64f56cc93e5359372b08b99a2d600273cBrian      break;
6520dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_FILTER_LINEAR:
653b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      for (j = 0; j < QUAD_SIZE; j++) {
654b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         float tx[4][4], a, b;
655b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         int x0, y0, x1, y1, c;
656b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         linear_texcoord(sampler->state->wrap_s, s[j], width,  &x0, &x1, &a);
657b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         linear_texcoord(sampler->state->wrap_t, t[j], height, &y0, &y1, &b);
658df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, faces[j], level0, x0, y0, 0, tx, 0);
659df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, faces[j], level0, x1, y0, 0, tx, 1);
660df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, faces[j], level0, x0, y1, 0, tx, 2);
661df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, faces[j], level0, x1, y1, 0, tx, 3);
6623d8c05f7320151898dd224c1daaf3118e1f7ea34Brian         if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
6633d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            shadow_compare(compare_func, tx, p, 0);
6643d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            shadow_compare(compare_func, tx, p, 1);
6653d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            shadow_compare(compare_func, tx, p, 2);
6663d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            shadow_compare(compare_func, tx, p, 3);
6673d8c05f7320151898dd224c1daaf3118e1f7ea34Brian         }
6683d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
669b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         for (c = 0; c < 4; c++) {
670b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian            rgba[c][j] = lerp_2d(a, b, tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
671b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         }
672f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian
673f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian         if (level0 != level1) {
674f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            /* get texels from second mipmap level and blend */
675f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            float rgba2[4][4];
676f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            x0 = x0 / 2;
677f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            y0 = y0 / 2;
678f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            x1 = x1 / 2;
679f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            y1 = y1 / 2;
680df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, faces[j], level1, x0, y0, 0, tx, 0);
681df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, faces[j], level1, x1, y0, 0, tx, 1);
682df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, faces[j], level1, x0, y1, 0, tx, 2);
683df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, faces[j], level1, x1, y1, 0, tx, 3);
6843d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
6853d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               shadow_compare(compare_func, tx, p, 0);
6863d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               shadow_compare(compare_func, tx, p, 1);
6873d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               shadow_compare(compare_func, tx, p, 2);
6883d8c05f7320151898dd224c1daaf3118e1f7ea34Brian               shadow_compare(compare_func, tx, p, 3);
6893d8c05f7320151898dd224c1daaf3118e1f7ea34Brian            }
6903d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
691f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            for (c = 0; c < 4; c++) {
692f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian               rgba2[c][j] = lerp_2d(a, b,
693f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian                                     tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
694f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            }
695f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian
696f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            for (c = 0; c < NUM_CHANNELS; c++) {
697c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian               rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]);
698f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            }
699f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian         }
70009a1b912605ff48c8782dcc5aae55ac77e27037bBrian      }
70109a1b912605ff48c8782dcc5aae55ac77e27037bBrian      break;
7020dc4eea64f56cc93e5359372b08b99a2d600273cBrian   default:
7030dc4eea64f56cc93e5359372b08b99a2d600273cBrian      assert(0);
7040dc4eea64f56cc93e5359372b08b99a2d600273cBrian   }
7050dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
70634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
70734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
70834a48abd5ff82ce9748fc29191e35a0985d47c5fBrianstatic void
709a34b8594b7b2d00404bb639621ec1ce918ba0786Briansp_get_samples_1d(struct tgsi_sampler *sampler,
710a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float s[QUAD_SIZE],
711a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float t[QUAD_SIZE],
712a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float p[QUAD_SIZE],
713a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  float lodbias,
714a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  float rgba[NUM_CHANNELS][QUAD_SIZE])
715a34b8594b7b2d00404bb639621ec1ce918ba0786Brian{
716a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   static const unsigned faces[4] = {0, 0, 0, 0};
717d16b4bc32a731cb6ae320e8c187af3bc751d4138Brian   static const float tzero[4] = {0, 0, 0, 0};
718d16b4bc32a731cb6ae320e8c187af3bc751d4138Brian   sp_get_samples_2d_common(sampler, s, tzero, NULL, lodbias, rgba, faces);
719a34b8594b7b2d00404bb639621ec1ce918ba0786Brian}
720a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
721a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
722a34b8594b7b2d00404bb639621ec1ce918ba0786Brianstatic void
723a34b8594b7b2d00404bb639621ec1ce918ba0786Briansp_get_samples_2d(struct tgsi_sampler *sampler,
724a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float s[QUAD_SIZE],
725a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float t[QUAD_SIZE],
726a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  const float p[QUAD_SIZE],
727a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  float lodbias,
728a34b8594b7b2d00404bb639621ec1ce918ba0786Brian                  float rgba[NUM_CHANNELS][QUAD_SIZE])
729a34b8594b7b2d00404bb639621ec1ce918ba0786Brian{
730a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   static const unsigned faces[4] = {0, 0, 0, 0};
7313d8c05f7320151898dd224c1daaf3118e1f7ea34Brian   sp_get_samples_2d_common(sampler, s, t, p, lodbias, rgba, faces);
732a34b8594b7b2d00404bb639621ec1ce918ba0786Brian}
733a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
734a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
735a34b8594b7b2d00404bb639621ec1ce918ba0786Brianstatic void
736b4480285ed5098f1c862690ee105dd46f5e6cd1eBriansp_get_samples_3d(struct tgsi_sampler *sampler,
737b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  const float s[QUAD_SIZE],
738b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  const float t[QUAD_SIZE],
739b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  const float p[QUAD_SIZE],
740f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian                  float lodbias,
741b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  float rgba[NUM_CHANNELS][QUAD_SIZE])
74234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
74334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   /* get/map pipe_surfaces corresponding to 3D tex slices */
7443d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   unsigned level0, level1, j, imgFilter;
7453d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   int width, height, depth;
7463d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   float levelBlend;
7473d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   const uint face = 0;
7483d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
7493d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   choose_mipmap_levels(sampler, s, t, p, lodbias,
7503d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                        &level0, &level1, &levelBlend, &imgFilter);
7513d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
7523d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   if (sampler->state->normalized_coords) {
753753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      width = sampler->texture->width[level0];
754753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      height = sampler->texture->height[level0];
755753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer      depth = sampler->texture->depth[level0];
7563d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   }
7573d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   else {
758ee295fccdd0c94cb6b8af4dfb30283e39f548223Michal Krol      width = height = depth = 1;
7593d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   }
7603d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
7613d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   assert(width > 0);
7623d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   assert(height > 0);
7633d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   assert(depth > 0);
7643d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
7653d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   switch (imgFilter) {
7663d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   case PIPE_TEX_FILTER_NEAREST:
7673d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      for (j = 0; j < QUAD_SIZE; j++) {
7683d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         int x = nearest_texcoord(sampler->state->wrap_s, s[j], width);
7693d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         int y = nearest_texcoord(sampler->state->wrap_t, t[j], height);
7703d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         int z = nearest_texcoord(sampler->state->wrap_r, p[j], depth);
771df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, face, level0, x, y, z, rgba, j);
7723d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
7733d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         if (level0 != level1) {
7743d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            /* get texels from second mipmap level and blend */
7753d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            float rgba2[4][4];
7763d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            unsigned c;
7773d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            x /= 2;
7783d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            y /= 2;
7793d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            z /= 2;
780df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, face, level1, x, y, z, rgba2, j);
7813d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            for (c = 0; c < NUM_CHANNELS; c++) {
7823d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian               rgba[c][j] = LERP(levelBlend, rgba2[c][j], rgba[c][j]);
7833d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            }
7843d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         }
7853d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      }
7863d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      break;
7873d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   case PIPE_TEX_FILTER_LINEAR:
7883d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      for (j = 0; j < QUAD_SIZE; j++) {
789df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         float texel0[4][4], texel1[4][4];
790df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         float xw, yw, zw; /* interpolation weights */
7913d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         int x0, x1, y0, y1, z0, z1, c;
7923d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         linear_texcoord(sampler->state->wrap_s, s[j], width,  &x0, &x1, &xw);
7933d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         linear_texcoord(sampler->state->wrap_t, t[j], height, &y0, &y1, &yw);
7943d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         linear_texcoord(sampler->state->wrap_r, p[j], depth,  &z0, &z1, &zw);
795df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, face, level0, x0, y0, z0, texel0, 0);
796df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, face, level0, x1, y0, z0, texel0, 1);
797df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, face, level0, x0, y1, z0, texel0, 2);
798df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, face, level0, x1, y1, z0, texel0, 3);
799df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, face, level0, x0, y0, z1, texel1, 0);
800df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, face, level0, x1, y0, z1, texel1, 1);
801df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, face, level0, x0, y1, z1, texel1, 2);
802df4410a59784482fcbd48f82788dd0a9f5a62c15Brian         get_texel(sampler, face, level0, x1, y1, z1, texel1, 3);
8033d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
8043d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         /* 3D lerp */
8053d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         for (c = 0; c < 4; c++) {
8063d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            float ctemp0[4][4], ctemp1[4][4];
8073d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            ctemp0[c][j] = lerp_2d(xw, yw,
8083d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                                   texel0[c][0], texel0[c][1],
8093d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                                   texel0[c][2], texel0[c][3]);
8103d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            ctemp1[c][j] = lerp_2d(xw, yw,
8113d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                                   texel1[c][0], texel1[c][1],
8123d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                                   texel1[c][2], texel1[c][3]);
8133d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            rgba[c][j] = LERP(zw, ctemp0[c][j], ctemp1[c][j]);
8143d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         }
8153d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
8163d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         if (level0 != level1) {
8173d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            /* get texels from second mipmap level and blend */
8183d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            float rgba2[4][4];
8193d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            x0 /= 2;
8203d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            y0 /= 2;
8213d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            z0 /= 2;
8223d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            x1 /= 2;
8233d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            y1 /= 2;
8243d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            z1 /= 2;
825df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, face, level1, x0, y0, z0, texel0, 0);
826df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, face, level1, x1, y0, z0, texel0, 1);
827df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, face, level1, x0, y1, z0, texel0, 2);
828df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, face, level1, x1, y1, z0, texel0, 3);
829df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, face, level1, x0, y0, z1, texel1, 0);
830df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, face, level1, x1, y0, z1, texel1, 1);
831df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, face, level1, x0, y1, z1, texel1, 2);
832df4410a59784482fcbd48f82788dd0a9f5a62c15Brian            get_texel(sampler, face, level1, x1, y1, z1, texel1, 3);
8333d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
8343d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            /* 3D lerp */
8353d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            for (c = 0; c < 4; c++) {
8363d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian               float ctemp0[4][4], ctemp1[4][4];
8373d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian               ctemp0[c][j] = lerp_2d(xw, yw,
8383d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                                      texel0[c][0], texel0[c][1],
8393d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                                      texel0[c][2], texel0[c][3]);
8403d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian               ctemp1[c][j] = lerp_2d(xw, yw,
8413d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                                      texel1[c][0], texel1[c][1],
8423d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian                                      texel1[c][2], texel1[c][3]);
8433d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian               rgba2[c][j] = LERP(zw, ctemp0[c][j], ctemp1[c][j]);
8443d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            }
8453d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
8463d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            /* blend mipmap levels */
8473d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            for (c = 0; c < NUM_CHANNELS; c++) {
8483d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian               rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]);
8493d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian            }
8503d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian         }
8513d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      }
8523d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      break;
8533d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   default:
8543d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      assert(0);
8553d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   }
85634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
85734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
85834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
85934a48abd5ff82ce9748fc29191e35a0985d47c5fBrianstatic void
860b4480285ed5098f1c862690ee105dd46f5e6cd1eBriansp_get_samples_cube(struct tgsi_sampler *sampler,
861b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                    const float s[QUAD_SIZE],
862b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                    const float t[QUAD_SIZE],
863b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                    const float p[QUAD_SIZE],
864f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian                    float lodbias,
865b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                    float rgba[NUM_CHANNELS][QUAD_SIZE])
86634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
867a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   unsigned faces[QUAD_SIZE], j;
868a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   float ssss[4], tttt[4];
869b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   for (j = 0; j < QUAD_SIZE; j++) {
870a34b8594b7b2d00404bb639621ec1ce918ba0786Brian      faces[j] = choose_cube_face(s[j], t[j], p[j], ssss + j, tttt + j);
871b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
872a34b8594b7b2d00404bb639621ec1ce918ba0786Brian   sp_get_samples_2d_common(sampler, ssss, tttt, NULL, lodbias, rgba, faces);
87334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
87434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
87534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
876a34b8594b7b2d00404bb639621ec1ce918ba0786Brian/**
877a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Called via tgsi_sampler::get_samples()
878a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Use the sampler's state setting to get a filtered RGBA value
879753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * from the sampler's texture.
880a34b8594b7b2d00404bb639621ec1ce918ba0786Brian *
881a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * XXX we can implement many versions of this function, each
882a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * tightly coded for a specific combination of sampler state
883a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * (nearest + repeat), (bilinear mipmap + clamp), etc.
884a34b8594b7b2d00404bb639621ec1ce918ba0786Brian *
885a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * The update_samplers() function in st_atom_sampler.c could create
886a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * a new tgsi_sampler object for each state combo it finds....
887a34b8594b7b2d00404bb639621ec1ce918ba0786Brian */
88834a48abd5ff82ce9748fc29191e35a0985d47c5fBrianvoid
889b4480285ed5098f1c862690ee105dd46f5e6cd1eBriansp_get_samples(struct tgsi_sampler *sampler,
890b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float s[QUAD_SIZE],
891b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float t[QUAD_SIZE],
892b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float p[QUAD_SIZE],
893f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian               float lodbias,
894b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               float rgba[NUM_CHANNELS][QUAD_SIZE])
89534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
8964f23468bd0d14b8ed687a641003d587b91ad39a7Brian   if (!sampler->texture)
8974f23468bd0d14b8ed687a641003d587b91ad39a7Brian      return;
8984f23468bd0d14b8ed687a641003d587b91ad39a7Brian
89934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   switch (sampler->texture->target) {
90070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   case PIPE_TEXTURE_1D:
901f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      sp_get_samples_1d(sampler, s, t, p, lodbias, rgba);
90234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
90370af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   case PIPE_TEXTURE_2D:
904f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      sp_get_samples_2d(sampler, s, t, p, lodbias, rgba);
90534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
90670af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   case PIPE_TEXTURE_3D:
907f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      sp_get_samples_3d(sampler, s, t, p, lodbias, rgba);
90834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
90970af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell   case PIPE_TEXTURE_CUBE:
910f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      sp_get_samples_cube(sampler, s, t, p, lodbias, rgba);
91134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
91234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   default:
91334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      assert(0);
91434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
91534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
91634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
917