sp_tex_sample.c revision 612cfb749c3526eeb446bbc631bf24716522f373
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
350dc4eea64f56cc93e5359372b08b99a2d600273cBrian
360dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "main/macros.h"
3708f33a025100dea2d951e6d628891fe294b18082Brian#include "sp_context.h"
380dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "sp_surface.h"
390dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "sp_tex_sample.h"
400dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "pipe/p_context.h"
410dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "pipe/p_defines.h"
420dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "pipe/tgsi/core/tgsi_exec.h"
430dc4eea64f56cc93e5359372b08b99a2d600273cBrian
440dc4eea64f56cc93e5359372b08b99a2d600273cBrian
4508f33a025100dea2d951e6d628891fe294b18082Brian/*
4608f33a025100dea2d951e6d628891fe294b18082Brian * Note, the FRAC macro has to work perfectly.  Otherwise you'll sometimes
4708f33a025100dea2d951e6d628891fe294b18082Brian * see 1-pixel bands of improperly weighted linear-filtered textures.
4808f33a025100dea2d951e6d628891fe294b18082Brian * The tests/texwrap.c demo is a good test.
4908f33a025100dea2d951e6d628891fe294b18082Brian * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0.
5008f33a025100dea2d951e6d628891fe294b18082Brian * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x).
5108f33a025100dea2d951e6d628891fe294b18082Brian */
5208f33a025100dea2d951e6d628891fe294b18082Brian#define FRAC(f)  ((f) - IFLOOR(f))
5308f33a025100dea2d951e6d628891fe294b18082Brian
5408f33a025100dea2d951e6d628891fe294b18082Brian
5508f33a025100dea2d951e6d628891fe294b18082Brian/**
5608f33a025100dea2d951e6d628891fe294b18082Brian * Linear interpolation macro
5708f33a025100dea2d951e6d628891fe294b18082Brian */
580dc4eea64f56cc93e5359372b08b99a2d600273cBrian#define LERP(T, A, B)  ( (A) + (T) * ((B) - (A)) )
590dc4eea64f56cc93e5359372b08b99a2d600273cBrian
600dc4eea64f56cc93e5359372b08b99a2d600273cBrian
610dc4eea64f56cc93e5359372b08b99a2d600273cBrian/**
620dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Do 2D/biliner interpolation of float values.
630dc4eea64f56cc93e5359372b08b99a2d600273cBrian * v00, v10, v01 and v11 are typically four texture samples in a square/box.
640dc4eea64f56cc93e5359372b08b99a2d600273cBrian * a and b are the horizontal and vertical interpolants.
650dc4eea64f56cc93e5359372b08b99a2d600273cBrian * It's important that this function is inlined when compiled with
660dc4eea64f56cc93e5359372b08b99a2d600273cBrian * optimization!  If we find that's not true on some systems, convert
670dc4eea64f56cc93e5359372b08b99a2d600273cBrian * to a macro.
680dc4eea64f56cc93e5359372b08b99a2d600273cBrian */
690dc4eea64f56cc93e5359372b08b99a2d600273cBrianstatic INLINE GLfloat
700dc4eea64f56cc93e5359372b08b99a2d600273cBrianlerp_2d(GLfloat a, GLfloat b,
710dc4eea64f56cc93e5359372b08b99a2d600273cBrian        GLfloat v00, GLfloat v10, GLfloat v01, GLfloat v11)
720dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
730dc4eea64f56cc93e5359372b08b99a2d600273cBrian   const GLfloat temp0 = LERP(a, v00, v10);
740dc4eea64f56cc93e5359372b08b99a2d600273cBrian   const GLfloat temp1 = LERP(a, v01, v11);
750dc4eea64f56cc93e5359372b08b99a2d600273cBrian   return LERP(b, temp0, temp1);
760dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
770dc4eea64f56cc93e5359372b08b99a2d600273cBrian
780dc4eea64f56cc93e5359372b08b99a2d600273cBrian
790dc4eea64f56cc93e5359372b08b99a2d600273cBrian/**
8008f33a025100dea2d951e6d628891fe294b18082Brian * Compute the remainder of a divided by b, but be careful with
8108f33a025100dea2d951e6d628891fe294b18082Brian * negative values so that REPEAT mode works right.
820dc4eea64f56cc93e5359372b08b99a2d600273cBrian */
8308f33a025100dea2d951e6d628891fe294b18082Brianstatic INLINE GLint
8408f33a025100dea2d951e6d628891fe294b18082Brianrepeat_remainder(GLint a, GLint b)
8508f33a025100dea2d951e6d628891fe294b18082Brian{
8608f33a025100dea2d951e6d628891fe294b18082Brian   if (a >= 0)
8708f33a025100dea2d951e6d628891fe294b18082Brian      return a % b;
8808f33a025100dea2d951e6d628891fe294b18082Brian   else
8908f33a025100dea2d951e6d628891fe294b18082Brian      return (a + 1) % b + b - 1;
9008f33a025100dea2d951e6d628891fe294b18082Brian}
9108f33a025100dea2d951e6d628891fe294b18082Brian
9208f33a025100dea2d951e6d628891fe294b18082Brian
9308f33a025100dea2d951e6d628891fe294b18082Brian/**
9408f33a025100dea2d951e6d628891fe294b18082Brian * Apply texture coord wrapping mode and return integer texture index.
9508f33a025100dea2d951e6d628891fe294b18082Brian * \param wrapMode  PIPE_TEX_WRAP_x
9608f33a025100dea2d951e6d628891fe294b18082Brian * \param s  the texcoord
9708f33a025100dea2d951e6d628891fe294b18082Brian * \param size  the texture image size
9808f33a025100dea2d951e6d628891fe294b18082Brian * \return  integer texture index
9908f33a025100dea2d951e6d628891fe294b18082Brian */
10008f33a025100dea2d951e6d628891fe294b18082Brianstatic INLINE GLint
10108f33a025100dea2d951e6d628891fe294b18082Briannearest_texcoord(GLuint wrapMode, GLfloat s, GLuint size)
1020dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
10308f33a025100dea2d951e6d628891fe294b18082Brian   GLint i;
1040dc4eea64f56cc93e5359372b08b99a2d600273cBrian   switch (wrapMode) {
1050dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_WRAP_REPEAT:
10608f33a025100dea2d951e6d628891fe294b18082Brian      /* s limited to [0,1) */
10708f33a025100dea2d951e6d628891fe294b18082Brian      /* i limited to [0,size-1] */
10808f33a025100dea2d951e6d628891fe294b18082Brian      i = IFLOOR(s * size);
10908f33a025100dea2d951e6d628891fe294b18082Brian      i = repeat_remainder(i, size);
11008f33a025100dea2d951e6d628891fe294b18082Brian      return i;
1110dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_WRAP_CLAMP:
11208f33a025100dea2d951e6d628891fe294b18082Brian      /* s limited to [0,1] */
11308f33a025100dea2d951e6d628891fe294b18082Brian      /* i limited to [0,size-1] */
11408f33a025100dea2d951e6d628891fe294b18082Brian      if (s <= 0.0F)
11508f33a025100dea2d951e6d628891fe294b18082Brian         i = 0;
11608f33a025100dea2d951e6d628891fe294b18082Brian      else if (s >= 1.0F)
11708f33a025100dea2d951e6d628891fe294b18082Brian         i = size - 1;
11808f33a025100dea2d951e6d628891fe294b18082Brian      else
11908f33a025100dea2d951e6d628891fe294b18082Brian         i = IFLOOR(s * size);
12008f33a025100dea2d951e6d628891fe294b18082Brian      return i;
12108f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
12208f33a025100dea2d951e6d628891fe294b18082Brian      {
12308f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [min,max] */
12408f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [0, size-1] */
12508f33a025100dea2d951e6d628891fe294b18082Brian         const GLfloat min = 1.0F / (2.0F * size);
12608f33a025100dea2d951e6d628891fe294b18082Brian         const GLfloat max = 1.0F - min;
12708f33a025100dea2d951e6d628891fe294b18082Brian         if (s < min)
12808f33a025100dea2d951e6d628891fe294b18082Brian            i = 0;
12908f33a025100dea2d951e6d628891fe294b18082Brian         else if (s > max)
13008f33a025100dea2d951e6d628891fe294b18082Brian            i = size - 1;
13108f33a025100dea2d951e6d628891fe294b18082Brian         else
13208f33a025100dea2d951e6d628891fe294b18082Brian            i = IFLOOR(s * size);
13308f33a025100dea2d951e6d628891fe294b18082Brian      }
13408f33a025100dea2d951e6d628891fe294b18082Brian      return i;
13508f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
13608f33a025100dea2d951e6d628891fe294b18082Brian      {
13708f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [min,max] */
13808f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [-1, size] */
13908f33a025100dea2d951e6d628891fe294b18082Brian         const GLfloat min = -1.0F / (2.0F * size);
14008f33a025100dea2d951e6d628891fe294b18082Brian         const GLfloat max = 1.0F - min;
14108f33a025100dea2d951e6d628891fe294b18082Brian         if (s <= min)
14208f33a025100dea2d951e6d628891fe294b18082Brian            i = -1;
14308f33a025100dea2d951e6d628891fe294b18082Brian         else if (s >= max)
14408f33a025100dea2d951e6d628891fe294b18082Brian            i = size;
14508f33a025100dea2d951e6d628891fe294b18082Brian         else
14608f33a025100dea2d951e6d628891fe294b18082Brian            i = IFLOOR(s * size);
14708f33a025100dea2d951e6d628891fe294b18082Brian      }
14808f33a025100dea2d951e6d628891fe294b18082Brian      return i;
14908f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_REPEAT:
15008f33a025100dea2d951e6d628891fe294b18082Brian      {
15108f33a025100dea2d951e6d628891fe294b18082Brian         const GLfloat min = 1.0F / (2.0F * size);
15208f33a025100dea2d951e6d628891fe294b18082Brian         const GLfloat max = 1.0F - min;
15308f33a025100dea2d951e6d628891fe294b18082Brian         const GLint flr = IFLOOR(s);
15408f33a025100dea2d951e6d628891fe294b18082Brian         GLfloat u;
15508f33a025100dea2d951e6d628891fe294b18082Brian         if (flr & 1)
15608f33a025100dea2d951e6d628891fe294b18082Brian            u = 1.0F - (s - (GLfloat) flr);
15708f33a025100dea2d951e6d628891fe294b18082Brian         else
15808f33a025100dea2d951e6d628891fe294b18082Brian            u = s - (GLfloat) flr;
15908f33a025100dea2d951e6d628891fe294b18082Brian         if (u < min)
16008f33a025100dea2d951e6d628891fe294b18082Brian            i = 0;
16108f33a025100dea2d951e6d628891fe294b18082Brian         else if (u > max)
16208f33a025100dea2d951e6d628891fe294b18082Brian            i = size - 1;
16308f33a025100dea2d951e6d628891fe294b18082Brian         else
16408f33a025100dea2d951e6d628891fe294b18082Brian            i = IFLOOR(u * size);
16508f33a025100dea2d951e6d628891fe294b18082Brian      }
16608f33a025100dea2d951e6d628891fe294b18082Brian      return i;
16708f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP:
16808f33a025100dea2d951e6d628891fe294b18082Brian      {
16908f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [0,1] */
17008f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [0,size-1] */
17108f33a025100dea2d951e6d628891fe294b18082Brian         const GLfloat u = FABSF(s);
17208f33a025100dea2d951e6d628891fe294b18082Brian         if (u <= 0.0F)
17308f33a025100dea2d951e6d628891fe294b18082Brian            i = 0;
17408f33a025100dea2d951e6d628891fe294b18082Brian         else if (u >= 1.0F)
17508f33a025100dea2d951e6d628891fe294b18082Brian            i = size - 1;
17608f33a025100dea2d951e6d628891fe294b18082Brian         else
17708f33a025100dea2d951e6d628891fe294b18082Brian            i = IFLOOR(u * size);
17808f33a025100dea2d951e6d628891fe294b18082Brian      }
17908f33a025100dea2d951e6d628891fe294b18082Brian      return i;
18008f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
18108f33a025100dea2d951e6d628891fe294b18082Brian      {
18208f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [min,max] */
18308f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [0, size-1] */
18408f33a025100dea2d951e6d628891fe294b18082Brian         const GLfloat min = 1.0F / (2.0F * size);
18508f33a025100dea2d951e6d628891fe294b18082Brian         const GLfloat max = 1.0F - min;
18608f33a025100dea2d951e6d628891fe294b18082Brian         const GLfloat u = FABSF(s);
18708f33a025100dea2d951e6d628891fe294b18082Brian         if (u < min)
18808f33a025100dea2d951e6d628891fe294b18082Brian            i = 0;
18908f33a025100dea2d951e6d628891fe294b18082Brian         else if (u > max)
19008f33a025100dea2d951e6d628891fe294b18082Brian            i = size - 1;
19108f33a025100dea2d951e6d628891fe294b18082Brian         else
19208f33a025100dea2d951e6d628891fe294b18082Brian            i = IFLOOR(u * size);
19308f33a025100dea2d951e6d628891fe294b18082Brian      }
19408f33a025100dea2d951e6d628891fe294b18082Brian      return i;
19508f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
19608f33a025100dea2d951e6d628891fe294b18082Brian      {
19708f33a025100dea2d951e6d628891fe294b18082Brian         /* s limited to [min,max] */
19808f33a025100dea2d951e6d628891fe294b18082Brian         /* i limited to [0, size-1] */
19908f33a025100dea2d951e6d628891fe294b18082Brian         const GLfloat min = -1.0F / (2.0F * size);
20008f33a025100dea2d951e6d628891fe294b18082Brian         const GLfloat max = 1.0F - min;
20108f33a025100dea2d951e6d628891fe294b18082Brian         const GLfloat u = FABSF(s);
20208f33a025100dea2d951e6d628891fe294b18082Brian         if (u < min)
20308f33a025100dea2d951e6d628891fe294b18082Brian            i = -1;
20408f33a025100dea2d951e6d628891fe294b18082Brian         else if (u > max)
20508f33a025100dea2d951e6d628891fe294b18082Brian            i = size;
20608f33a025100dea2d951e6d628891fe294b18082Brian         else
20708f33a025100dea2d951e6d628891fe294b18082Brian            i = IFLOOR(u * size);
20808f33a025100dea2d951e6d628891fe294b18082Brian      }
20908f33a025100dea2d951e6d628891fe294b18082Brian      return i;
2100dc4eea64f56cc93e5359372b08b99a2d600273cBrian   default:
2110dc4eea64f56cc93e5359372b08b99a2d600273cBrian      assert(0);
21208f33a025100dea2d951e6d628891fe294b18082Brian      return 0;
2130dc4eea64f56cc93e5359372b08b99a2d600273cBrian   }
2140dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
2150dc4eea64f56cc93e5359372b08b99a2d600273cBrian
21608f33a025100dea2d951e6d628891fe294b18082Brian
21708f33a025100dea2d951e6d628891fe294b18082Brian/**
21808f33a025100dea2d951e6d628891fe294b18082Brian * Used to compute texel locations for linear sampling.
21908f33a025100dea2d951e6d628891fe294b18082Brian * \param wrapMode  PIPE_TEX_WRAP_x
22008f33a025100dea2d951e6d628891fe294b18082Brian * \param s  the texcoord
22108f33a025100dea2d951e6d628891fe294b18082Brian * \param size  the texture image size
22208f33a025100dea2d951e6d628891fe294b18082Brian * \param i0  returns first texture index
22308f33a025100dea2d951e6d628891fe294b18082Brian * \param i1  returns second texture index (usually *i0 + 1)
22408f33a025100dea2d951e6d628891fe294b18082Brian * \param a  returns blend factor/weight between texture indexes
22508f33a025100dea2d951e6d628891fe294b18082Brian */
2260dc4eea64f56cc93e5359372b08b99a2d600273cBrianstatic INLINE void
22708f33a025100dea2d951e6d628891fe294b18082Brianlinear_texcoord(GLuint wrapMode, GLfloat s, GLuint size,
22808f33a025100dea2d951e6d628891fe294b18082Brian                GLint *i0, GLint *i1, GLfloat *a)
2290dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
23008f33a025100dea2d951e6d628891fe294b18082Brian   GLfloat u;
2310dc4eea64f56cc93e5359372b08b99a2d600273cBrian   switch (wrapMode) {
2320dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_WRAP_REPEAT:
23308f33a025100dea2d951e6d628891fe294b18082Brian      u = s * size - 0.5F;
23408f33a025100dea2d951e6d628891fe294b18082Brian      *i0 = repeat_remainder(IFLOOR(u), size);
23508f33a025100dea2d951e6d628891fe294b18082Brian      *i1 = repeat_remainder(*i0 + 1, size);
2360dc4eea64f56cc93e5359372b08b99a2d600273cBrian      break;
2370dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_WRAP_CLAMP:
23808f33a025100dea2d951e6d628891fe294b18082Brian      if (s <= 0.0F)
23908f33a025100dea2d951e6d628891fe294b18082Brian         u = 0.0F;
24008f33a025100dea2d951e6d628891fe294b18082Brian      else if (s >= 1.0F)
24108f33a025100dea2d951e6d628891fe294b18082Brian         u = (GLfloat) size;
24208f33a025100dea2d951e6d628891fe294b18082Brian      else
24308f33a025100dea2d951e6d628891fe294b18082Brian         u = s * size;
24408f33a025100dea2d951e6d628891fe294b18082Brian      u -= 0.5F;
24508f33a025100dea2d951e6d628891fe294b18082Brian      *i0 = IFLOOR(u);
24608f33a025100dea2d951e6d628891fe294b18082Brian      *i1 = *i0 + 1;
24708f33a025100dea2d951e6d628891fe294b18082Brian      break;
24808f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
24908f33a025100dea2d951e6d628891fe294b18082Brian      if (s <= 0.0F)
25008f33a025100dea2d951e6d628891fe294b18082Brian         u = 0.0F;
25108f33a025100dea2d951e6d628891fe294b18082Brian      else if (s >= 1.0F)
25208f33a025100dea2d951e6d628891fe294b18082Brian         u = (GLfloat) size;
25308f33a025100dea2d951e6d628891fe294b18082Brian      else
25408f33a025100dea2d951e6d628891fe294b18082Brian         u = s * size;
25508f33a025100dea2d951e6d628891fe294b18082Brian      u -= 0.5F;
25608f33a025100dea2d951e6d628891fe294b18082Brian      *i0 = IFLOOR(u);
25708f33a025100dea2d951e6d628891fe294b18082Brian      *i1 = *i0 + 1;
25808f33a025100dea2d951e6d628891fe294b18082Brian      if (*i0 < 0)
25908f33a025100dea2d951e6d628891fe294b18082Brian         *i0 = 0;
26008f33a025100dea2d951e6d628891fe294b18082Brian      if (*i1 >= (GLint) size)
26108f33a025100dea2d951e6d628891fe294b18082Brian         *i1 = size - 1;
26208f33a025100dea2d951e6d628891fe294b18082Brian      break;
26308f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
26408f33a025100dea2d951e6d628891fe294b18082Brian      {
26508f33a025100dea2d951e6d628891fe294b18082Brian         const GLfloat min = -1.0F / (2.0F * size);
26608f33a025100dea2d951e6d628891fe294b18082Brian         const GLfloat max = 1.0F - min;
26708f33a025100dea2d951e6d628891fe294b18082Brian         if (s <= min)
26808f33a025100dea2d951e6d628891fe294b18082Brian            u = min * size;
26908f33a025100dea2d951e6d628891fe294b18082Brian         else if (s >= max)
27008f33a025100dea2d951e6d628891fe294b18082Brian            u = max * size;
27108f33a025100dea2d951e6d628891fe294b18082Brian         else
27208f33a025100dea2d951e6d628891fe294b18082Brian            u = s * size;
27308f33a025100dea2d951e6d628891fe294b18082Brian         u -= 0.5F;
27408f33a025100dea2d951e6d628891fe294b18082Brian         *i0 = IFLOOR(u);
27508f33a025100dea2d951e6d628891fe294b18082Brian         *i1 = *i0 + 1;
27608f33a025100dea2d951e6d628891fe294b18082Brian      }
27708f33a025100dea2d951e6d628891fe294b18082Brian      break;
27808f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_REPEAT:
27908f33a025100dea2d951e6d628891fe294b18082Brian      {
28008f33a025100dea2d951e6d628891fe294b18082Brian         const GLint flr = IFLOOR(s);
28108f33a025100dea2d951e6d628891fe294b18082Brian         if (flr & 1)
28208f33a025100dea2d951e6d628891fe294b18082Brian            u = 1.0F - (s - (GLfloat) flr);
28308f33a025100dea2d951e6d628891fe294b18082Brian         else
28408f33a025100dea2d951e6d628891fe294b18082Brian            u = s - (GLfloat) flr;
28508f33a025100dea2d951e6d628891fe294b18082Brian         u = (u * size) - 0.5F;
28608f33a025100dea2d951e6d628891fe294b18082Brian         *i0 = IFLOOR(u);
28708f33a025100dea2d951e6d628891fe294b18082Brian         *i1 = *i0 + 1;
28808f33a025100dea2d951e6d628891fe294b18082Brian         if (*i0 < 0)
28908f33a025100dea2d951e6d628891fe294b18082Brian            *i0 = 0;
29008f33a025100dea2d951e6d628891fe294b18082Brian         if (*i1 >= (GLint) size)
29108f33a025100dea2d951e6d628891fe294b18082Brian            *i1 = size - 1;
29208f33a025100dea2d951e6d628891fe294b18082Brian      }
29308f33a025100dea2d951e6d628891fe294b18082Brian      break;
29408f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP:
29508f33a025100dea2d951e6d628891fe294b18082Brian      u = FABSF(s);
29608f33a025100dea2d951e6d628891fe294b18082Brian      if (u >= 1.0F)
29708f33a025100dea2d951e6d628891fe294b18082Brian         u = (GLfloat) size;
29808f33a025100dea2d951e6d628891fe294b18082Brian      else
29908f33a025100dea2d951e6d628891fe294b18082Brian         u *= size;
30008f33a025100dea2d951e6d628891fe294b18082Brian      u -= 0.5F;
30108f33a025100dea2d951e6d628891fe294b18082Brian      *i0 = IFLOOR(u);
30208f33a025100dea2d951e6d628891fe294b18082Brian      *i1 = *i0 + 1;
30308f33a025100dea2d951e6d628891fe294b18082Brian      break;
30408f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
30508f33a025100dea2d951e6d628891fe294b18082Brian      u = FABSF(s);
30608f33a025100dea2d951e6d628891fe294b18082Brian      if (u >= 1.0F)
30708f33a025100dea2d951e6d628891fe294b18082Brian         u = (GLfloat) size;
30808f33a025100dea2d951e6d628891fe294b18082Brian      else
30908f33a025100dea2d951e6d628891fe294b18082Brian         u *= size;
31008f33a025100dea2d951e6d628891fe294b18082Brian      u -= 0.5F;
31108f33a025100dea2d951e6d628891fe294b18082Brian      *i0 = IFLOOR(u);
31208f33a025100dea2d951e6d628891fe294b18082Brian      *i1 = *i0 + 1;
31308f33a025100dea2d951e6d628891fe294b18082Brian      if (*i0 < 0)
31408f33a025100dea2d951e6d628891fe294b18082Brian         *i0 = 0;
31508f33a025100dea2d951e6d628891fe294b18082Brian      if (*i1 >= (GLint) size)
31608f33a025100dea2d951e6d628891fe294b18082Brian         *i1 = size - 1;
31708f33a025100dea2d951e6d628891fe294b18082Brian      break;
31808f33a025100dea2d951e6d628891fe294b18082Brian   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
31908f33a025100dea2d951e6d628891fe294b18082Brian      {
32008f33a025100dea2d951e6d628891fe294b18082Brian         const GLfloat min = -1.0F / (2.0F * size);
32108f33a025100dea2d951e6d628891fe294b18082Brian         const GLfloat max = 1.0F - min;
32208f33a025100dea2d951e6d628891fe294b18082Brian         u = FABSF(s);
32308f33a025100dea2d951e6d628891fe294b18082Brian         if (u <= min)
32408f33a025100dea2d951e6d628891fe294b18082Brian            u = min * size;
32508f33a025100dea2d951e6d628891fe294b18082Brian         else if (u >= max)
32608f33a025100dea2d951e6d628891fe294b18082Brian            u = max * size;
32708f33a025100dea2d951e6d628891fe294b18082Brian         else
32808f33a025100dea2d951e6d628891fe294b18082Brian            u *= size;
32908f33a025100dea2d951e6d628891fe294b18082Brian         u -= 0.5F;
33008f33a025100dea2d951e6d628891fe294b18082Brian         *i0 = IFLOOR(u);
33108f33a025100dea2d951e6d628891fe294b18082Brian         *i1 = *i0 + 1;
33208f33a025100dea2d951e6d628891fe294b18082Brian      }
3330dc4eea64f56cc93e5359372b08b99a2d600273cBrian      break;
3340dc4eea64f56cc93e5359372b08b99a2d600273cBrian   default:
3350dc4eea64f56cc93e5359372b08b99a2d600273cBrian      assert(0);
3360dc4eea64f56cc93e5359372b08b99a2d600273cBrian   }
33708f33a025100dea2d951e6d628891fe294b18082Brian   *a = FRAC(u);
3380dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
3390dc4eea64f56cc93e5359372b08b99a2d600273cBrian
3400dc4eea64f56cc93e5359372b08b99a2d600273cBrian
34134a48abd5ff82ce9748fc29191e35a0985d47c5fBrianstatic GLuint
34234a48abd5ff82ce9748fc29191e35a0985d47c5fBrianchoose_cube_face(const GLfloat texcoord[4], GLfloat newCoord[4])
34334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
34434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   /*
34534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      major axis
34634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      direction     target                             sc     tc    ma
34734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      ----------    -------------------------------    ---    ---   ---
34834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       +rx          TEXTURE_CUBE_MAP_POSITIVE_X_EXT    -rz    -ry   rx
34934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       -rx          TEXTURE_CUBE_MAP_NEGATIVE_X_EXT    +rz    -ry   rx
35034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       +ry          TEXTURE_CUBE_MAP_POSITIVE_Y_EXT    +rx    +rz   ry
35134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       -ry          TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT    +rx    -rz   ry
35234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       +rz          TEXTURE_CUBE_MAP_POSITIVE_Z_EXT    +rx    -ry   rz
35334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       -rz          TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT    -rx    -ry   rz
35434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   */
35534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   const GLfloat rx = texcoord[0];
35634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   const GLfloat ry = texcoord[1];
35734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   const GLfloat rz = texcoord[2];
35834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   const GLfloat arx = FABSF(rx), ary = FABSF(ry), arz = FABSF(rz);
35934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   GLuint face;
36034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   GLfloat sc, tc, ma;
36134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
36234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   if (arx > ary && arx > arz) {
36334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      if (rx >= 0.0F) {
36434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_POS_X;
36534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = -rz;
36634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
36734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arx;
36834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
36934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      else {
37034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_NEG_X;
37134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rz;
37234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
37334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arx;
37434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
37534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
37634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   else if (ary > arx && ary > arz) {
37734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      if (ry >= 0.0F) {
37834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_POS_Y;
37934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rx;
38034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = rz;
38134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = ary;
38234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
38334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      else {
38434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_NEG_Y;
38534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rx;
38634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -rz;
38734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = ary;
38834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
38934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
39034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   else {
39134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      if (rz > 0.0F) {
39234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_POS_Z;
39334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rx;
39434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
39534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arz;
39634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
39734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      else {
39834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_NEG_Z;
39934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = -rx;
40034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
40134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arz;
40234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
40334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
40434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
40534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   newCoord[0] = ( sc / ma + 1.0F ) * 0.5F;
40634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   newCoord[1] = ( tc / ma + 1.0F ) * 0.5F;
40734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
40834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   return face;
40934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
41034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
41134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
41234a48abd5ff82ce9748fc29191e35a0985d47c5fBrianstatic void
41334a48abd5ff82ce9748fc29191e35a0985d47c5fBriansp_get_sample_1d(struct tgsi_sampler *sampler,
414e12810d92ffb3547680b227bf88937c03018112bBrian                 const GLfloat strq[4], GLfloat lambda, GLfloat rgba[4])
41534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
41634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   struct pipe_context *pipe = (struct pipe_context *) sampler->pipe;
41734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   struct pipe_surface *ps
41834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      = pipe->get_tex_surface(pipe, sampler->texture, 0, 0, 0);
41934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
42078b1a29a0da8d1877408421df5012d37084a96deKeith Whitwell   switch (sampler->state->min_img_filter) {
42134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   case PIPE_TEX_FILTER_NEAREST:
42234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      {
42334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         GLint x;
42434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         x = nearest_texcoord(sampler->state->wrap_s, strq[0],
42534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian                              sampler->texture->width0);
42634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ps->get_tile(ps, x, 0, 1, 1, rgba);
42734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
42834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
42934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   case PIPE_TEX_FILTER_LINEAR:
43034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      {
43134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         GLfloat t0[4], t1[4];
43234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         GLint x0, x1;
43334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         GLfloat a;
43434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         linear_texcoord(sampler->state->wrap_s, strq[0],
43534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian                         sampler->texture->width0, &x0, &x1, &a);
43634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ps->get_tile(ps, x0, 0, 1, 1, t0);
43734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ps->get_tile(ps, x1, 0, 1, 1, t1);
43834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
43934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         rgba[0] = LERP(a, t0[0], t1[0]);
44034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         rgba[1] = LERP(a, t0[1], t1[1]);
44134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         rgba[2] = LERP(a, t0[2], t1[2]);
44234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         rgba[3] = LERP(a, t0[3], t1[3]);
44334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
44434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
44534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   default:
44634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      assert(0);
44734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
44834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
44934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
45009a1b912605ff48c8782dcc5aae55ac77e27037bBrianstatic GLuint
45109a1b912605ff48c8782dcc5aae55ac77e27037bBrianchoose_mipmap_level(struct tgsi_sampler *sampler, GLfloat lambda)
45209a1b912605ff48c8782dcc5aae55ac77e27037bBrian{
45378b1a29a0da8d1877408421df5012d37084a96deKeith Whitwell   if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) {
45409a1b912605ff48c8782dcc5aae55ac77e27037bBrian      return 0;
45509a1b912605ff48c8782dcc5aae55ac77e27037bBrian   }
45609a1b912605ff48c8782dcc5aae55ac77e27037bBrian   else {
45709a1b912605ff48c8782dcc5aae55ac77e27037bBrian      GLint level = (int) lambda;
45809a1b912605ff48c8782dcc5aae55ac77e27037bBrian      level = CLAMP(level, sampler->texture->first_level,
45909a1b912605ff48c8782dcc5aae55ac77e27037bBrian		    sampler->texture->last_level);
46009a1b912605ff48c8782dcc5aae55ac77e27037bBrian      return level;
46109a1b912605ff48c8782dcc5aae55ac77e27037bBrian   }
46209a1b912605ff48c8782dcc5aae55ac77e27037bBrian}
46309a1b912605ff48c8782dcc5aae55ac77e27037bBrian
46408f33a025100dea2d951e6d628891fe294b18082Brian
4650dc4eea64f56cc93e5359372b08b99a2d600273cBrian/**
4660dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Called via tgsi_sampler::get_sample()
4670dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Use the sampler's state setting to get a filtered RGBA value
4680dc4eea64f56cc93e5359372b08b99a2d600273cBrian * from the sampler's texture (mipmap tree).
4690dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
4700dc4eea64f56cc93e5359372b08b99a2d600273cBrian * XXX we can implement many versions of this function, each
4710dc4eea64f56cc93e5359372b08b99a2d600273cBrian * tightly coded for a specific combination of sampler state
4720dc4eea64f56cc93e5359372b08b99a2d600273cBrian * (nearest + repeat), (bilinear mipmap + clamp), etc.
4730dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
4740dc4eea64f56cc93e5359372b08b99a2d600273cBrian * The update_samplers() function in st_atom_sampler.c could create
4750dc4eea64f56cc93e5359372b08b99a2d600273cBrian * a new tgsi_sampler object for each state combo it finds....
4760dc4eea64f56cc93e5359372b08b99a2d600273cBrian */
477e12810d92ffb3547680b227bf88937c03018112bBrianstatic void
47834a48abd5ff82ce9748fc29191e35a0985d47c5fBriansp_get_sample_2d(struct tgsi_sampler *sampler,
479e12810d92ffb3547680b227bf88937c03018112bBrian                 const GLfloat strq[4], GLfloat lambda, GLfloat rgba[4])
4800dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
4810dc4eea64f56cc93e5359372b08b99a2d600273cBrian   struct pipe_context *pipe = (struct pipe_context *) sampler->pipe;
48209a1b912605ff48c8782dcc5aae55ac77e27037bBrian   GLuint filter;
48309a1b912605ff48c8782dcc5aae55ac77e27037bBrian   GLint level0;
4840dc4eea64f56cc93e5359372b08b99a2d600273cBrian
48509a1b912605ff48c8782dcc5aae55ac77e27037bBrian   if (lambda < 0.0)
48678b1a29a0da8d1877408421df5012d37084a96deKeith Whitwell      filter = sampler->state->mag_img_filter;
48709a1b912605ff48c8782dcc5aae55ac77e27037bBrian   else
48878b1a29a0da8d1877408421df5012d37084a96deKeith Whitwell      filter = sampler->state->min_img_filter;
48909a1b912605ff48c8782dcc5aae55ac77e27037bBrian
49009a1b912605ff48c8782dcc5aae55ac77e27037bBrian   level0 = choose_mipmap_level(sampler, lambda);
49109a1b912605ff48c8782dcc5aae55ac77e27037bBrian
492612cfb749c3526eeb446bbc631bf24716522f373Brian   assert(sampler->texture->level[level0].width);
493612cfb749c3526eeb446bbc631bf24716522f373Brian
49409a1b912605ff48c8782dcc5aae55ac77e27037bBrian   switch (filter) {
4950dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_FILTER_NEAREST:
4960dc4eea64f56cc93e5359372b08b99a2d600273cBrian      {
4975671bba1cb103c00b44905dfa015c3338cb4af56Brian         GLint x = nearest_texcoord(sampler->state->wrap_s, strq[0],
4985671bba1cb103c00b44905dfa015c3338cb4af56Brian                                    sampler->texture->level[level0].width);
4995671bba1cb103c00b44905dfa015c3338cb4af56Brian         GLint y = nearest_texcoord(sampler->state->wrap_t, strq[1],
5005671bba1cb103c00b44905dfa015c3338cb4af56Brian                                    sampler->texture->level[level0].height);
5015671bba1cb103c00b44905dfa015c3338cb4af56Brian         GLint cx = x / SAMPLER_CACHE_SIZE;
5025671bba1cb103c00b44905dfa015c3338cb4af56Brian         GLint cy = y / SAMPLER_CACHE_SIZE;
50309a1b912605ff48c8782dcc5aae55ac77e27037bBrian         if (cx != sampler->cache_x || cy != sampler->cache_y ||
50409a1b912605ff48c8782dcc5aae55ac77e27037bBrian             level0 != sampler->cache_level) {
505267cf16e066f548a33c7b5f7c73deb59039d9b3dBrian            /* cache miss, replace cache with new tile */
50609a1b912605ff48c8782dcc5aae55ac77e27037bBrian            struct pipe_surface *ps
50709a1b912605ff48c8782dcc5aae55ac77e27037bBrian               = pipe->get_tex_surface(pipe, sampler->texture, 0, level0, 0);
5085671bba1cb103c00b44905dfa015c3338cb4af56Brian            assert(ps->width == sampler->texture->level[level0].width);
5095671bba1cb103c00b44905dfa015c3338cb4af56Brian            assert(ps->height == sampler->texture->level[level0].height);
51009a1b912605ff48c8782dcc5aae55ac77e27037bBrian            sampler->cache_level = level0;
511267cf16e066f548a33c7b5f7c73deb59039d9b3dBrian            sampler->cache_x = cx;
512267cf16e066f548a33c7b5f7c73deb59039d9b3dBrian            sampler->cache_y = cy;
513267cf16e066f548a33c7b5f7c73deb59039d9b3dBrian            ps->get_tile(ps,
514267cf16e066f548a33c7b5f7c73deb59039d9b3dBrian                         cx * SAMPLER_CACHE_SIZE,
515267cf16e066f548a33c7b5f7c73deb59039d9b3dBrian                         cy * SAMPLER_CACHE_SIZE,
516267cf16e066f548a33c7b5f7c73deb59039d9b3dBrian                         SAMPLER_CACHE_SIZE, SAMPLER_CACHE_SIZE,
517267cf16e066f548a33c7b5f7c73deb59039d9b3dBrian                         (GLfloat *) sampler->cache);
518267cf16e066f548a33c7b5f7c73deb59039d9b3dBrian            /*printf("cache miss (%d, %d)\n", x, y);*/
519267cf16e066f548a33c7b5f7c73deb59039d9b3dBrian         }
520267cf16e066f548a33c7b5f7c73deb59039d9b3dBrian         else {
521267cf16e066f548a33c7b5f7c73deb59039d9b3dBrian            /*printf("cache hit (%d, %d)\n", x, y);*/
522267cf16e066f548a33c7b5f7c73deb59039d9b3dBrian         }
5235671bba1cb103c00b44905dfa015c3338cb4af56Brian         /* get texel from cache */
524267cf16e066f548a33c7b5f7c73deb59039d9b3dBrian         cx = x % SAMPLER_CACHE_SIZE;
525267cf16e066f548a33c7b5f7c73deb59039d9b3dBrian         cy = y % SAMPLER_CACHE_SIZE;
52609a1b912605ff48c8782dcc5aae55ac77e27037bBrian         COPY_4V(rgba, sampler->cache[cy][cx]);
5270dc4eea64f56cc93e5359372b08b99a2d600273cBrian      }
5280dc4eea64f56cc93e5359372b08b99a2d600273cBrian      break;
5290dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_FILTER_LINEAR:
5300dc4eea64f56cc93e5359372b08b99a2d600273cBrian      {
5310dc4eea64f56cc93e5359372b08b99a2d600273cBrian         GLfloat t00[4], t01[4], t10[4], t11[4];
5320dc4eea64f56cc93e5359372b08b99a2d600273cBrian         GLint x0, y0, x1, y1;
5330dc4eea64f56cc93e5359372b08b99a2d600273cBrian         GLfloat a, b;
53409a1b912605ff48c8782dcc5aae55ac77e27037bBrian         struct pipe_surface *ps
53509a1b912605ff48c8782dcc5aae55ac77e27037bBrian            = pipe->get_tex_surface(pipe, sampler->texture, 0, level0, 0);
53609a1b912605ff48c8782dcc5aae55ac77e27037bBrian
5370dc4eea64f56cc93e5359372b08b99a2d600273cBrian         linear_texcoord(sampler->state->wrap_s, strq[0],
5380dc4eea64f56cc93e5359372b08b99a2d600273cBrian                         sampler->texture->width0, &x0, &x1, &a);
5390dc4eea64f56cc93e5359372b08b99a2d600273cBrian         linear_texcoord(sampler->state->wrap_t, strq[1],
5400dc4eea64f56cc93e5359372b08b99a2d600273cBrian                         sampler->texture->height0, &y0, &y1, &b);
5410dc4eea64f56cc93e5359372b08b99a2d600273cBrian         ps->get_tile(ps, x0, y0, 1, 1, t00);
5420dc4eea64f56cc93e5359372b08b99a2d600273cBrian         ps->get_tile(ps, x1, y0, 1, 1, t10);
5430dc4eea64f56cc93e5359372b08b99a2d600273cBrian         ps->get_tile(ps, x0, y1, 1, 1, t01);
5440dc4eea64f56cc93e5359372b08b99a2d600273cBrian         ps->get_tile(ps, x1, y1, 1, 1, t11);
5450dc4eea64f56cc93e5359372b08b99a2d600273cBrian
5460dc4eea64f56cc93e5359372b08b99a2d600273cBrian         rgba[0] = lerp_2d(a, b, t00[0], t10[0], t01[0], t11[0]);
5470dc4eea64f56cc93e5359372b08b99a2d600273cBrian         rgba[1] = lerp_2d(a, b, t00[1], t10[1], t01[1], t11[1]);
5480dc4eea64f56cc93e5359372b08b99a2d600273cBrian         rgba[2] = lerp_2d(a, b, t00[2], t10[2], t01[2], t11[2]);
5490dc4eea64f56cc93e5359372b08b99a2d600273cBrian         rgba[3] = lerp_2d(a, b, t00[3], t10[3], t01[3], t11[3]);
5500dc4eea64f56cc93e5359372b08b99a2d600273cBrian      }
5510dc4eea64f56cc93e5359372b08b99a2d600273cBrian      break;
55209a1b912605ff48c8782dcc5aae55ac77e27037bBrian      /*
55309a1b912605ff48c8782dcc5aae55ac77e27037bBrian      {
55409a1b912605ff48c8782dcc5aae55ac77e27037bBrian	 GLuint level0, level1;
55509a1b912605ff48c8782dcc5aae55ac77e27037bBrian	 level0 = choose_mipmap_level(sampler, lambda);
55609a1b912605ff48c8782dcc5aae55ac77e27037bBrian      }
55709a1b912605ff48c8782dcc5aae55ac77e27037bBrian      break;
55809a1b912605ff48c8782dcc5aae55ac77e27037bBrian      */
5590dc4eea64f56cc93e5359372b08b99a2d600273cBrian   default:
5600dc4eea64f56cc93e5359372b08b99a2d600273cBrian      assert(0);
5610dc4eea64f56cc93e5359372b08b99a2d600273cBrian   }
5620dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
56334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
56434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
56534a48abd5ff82ce9748fc29191e35a0985d47c5fBrianstatic void
56634a48abd5ff82ce9748fc29191e35a0985d47c5fBriansp_get_sample_3d(struct tgsi_sampler *sampler,
567e12810d92ffb3547680b227bf88937c03018112bBrian                 const GLfloat strq[4], GLfloat lamba, GLfloat rgba[4])
56834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
56934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   /* get/map pipe_surfaces corresponding to 3D tex slices */
57034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
57134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
57234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
57334a48abd5ff82ce9748fc29191e35a0985d47c5fBrianstatic void
57434a48abd5ff82ce9748fc29191e35a0985d47c5fBriansp_get_sample_cube(struct tgsi_sampler *sampler,
575e12810d92ffb3547680b227bf88937c03018112bBrian                   const GLfloat strq[4], GLfloat lambda, GLfloat rgba[4])
57634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
57734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   GLfloat st[4];
57834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   GLuint face = choose_cube_face(strq, st);
57934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
58034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   /* get/map surface corresponding to the face */
58134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
58234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
58334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
58434a48abd5ff82ce9748fc29191e35a0985d47c5fBrianvoid
58534a48abd5ff82ce9748fc29191e35a0985d47c5fBriansp_get_sample(struct tgsi_sampler *sampler,
586e12810d92ffb3547680b227bf88937c03018112bBrian              const GLfloat strq[4], GLfloat lambda, GLfloat rgba[4])
58734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
58834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   switch (sampler->texture->target) {
58934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   case GL_TEXTURE_1D:
590e12810d92ffb3547680b227bf88937c03018112bBrian      sp_get_sample_1d(sampler, strq, lambda, rgba);
59134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
59234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   case GL_TEXTURE_2D:
593e12810d92ffb3547680b227bf88937c03018112bBrian      sp_get_sample_2d(sampler, strq, lambda, rgba);
59434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
59534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   case GL_TEXTURE_3D:
596e12810d92ffb3547680b227bf88937c03018112bBrian      sp_get_sample_3d(sampler, strq, lambda, rgba);
59734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
59834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   case GL_TEXTURE_CUBE_MAP:
599e12810d92ffb3547680b227bf88937c03018112bBrian      sp_get_sample_cube(sampler, strq, lambda, rgba);
60034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
60134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   default:
60234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      assert(0);
60334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
60434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
60534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
606