sp_tex_sample.c revision a13de2464dd034ff117f9314df5757d068cae8e5
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 */
69b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic INLINE float
70b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianlerp_2d(float a, float b,
71b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian        float v00, float v10, float v01, float v11)
720dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
73b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   const float temp0 = LERP(a, v00, v10);
74b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   const float 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
101b4480285ed5098f1c862690ee105dd46f5e6cd1eBriannearest_texcoord(GLuint wrapMode, float 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] */
125b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = 1.0F / (2.0F * size);
126b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float 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] */
139b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = -1.0F / (2.0F * size);
140b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float 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      {
151b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = 1.0F / (2.0F * size);
152b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
15308f33a025100dea2d951e6d628891fe294b18082Brian         const GLint flr = IFLOOR(s);
154b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         float u;
15508f33a025100dea2d951e6d628891fe294b18082Brian         if (flr & 1)
156b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian            u = 1.0F - (s - (float) flr);
15708f33a025100dea2d951e6d628891fe294b18082Brian         else
158b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian            u = s - (float) 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] */
171b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float 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] */
184b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = 1.0F / (2.0F * size);
185b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
186b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float 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] */
199b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = -1.0F / (2.0F * size);
200b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float max = 1.0F - min;
201b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float 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
227b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianlinear_texcoord(GLuint wrapMode, float s, GLuint size,
228b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                GLint *i0, GLint *i1, float *a)
2290dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
230b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   float 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)
241b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         u = (float) 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)
252b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         u = (float) 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      {
265b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = -1.0F / (2.0F * size);
266b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float 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)
282b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian            u = 1.0F - (s - (float) flr);
28308f33a025100dea2d951e6d628891fe294b18082Brian         else
284b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian            u = s - (float) 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)
297b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         u = (float) 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)
307b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         u = (float) 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      {
320b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float min = -1.0F / (2.0F * size);
321b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         const float 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
342b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianchoose_cube_face(float rx, float ry, float rz,
343b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                 float newCoord[4])
34434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
34534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   /*
34634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      major axis
34734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      direction     target                             sc     tc    ma
34834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      ----------    -------------------------------    ---    ---   ---
34934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       +rx          TEXTURE_CUBE_MAP_POSITIVE_X_EXT    -rz    -ry   rx
35034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       -rx          TEXTURE_CUBE_MAP_NEGATIVE_X_EXT    +rz    -ry   rx
35134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       +ry          TEXTURE_CUBE_MAP_POSITIVE_Y_EXT    +rx    +rz   ry
35234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       -ry          TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT    +rx    -rz   ry
35334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       +rz          TEXTURE_CUBE_MAP_POSITIVE_Z_EXT    +rx    -ry   rz
35434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian       -rz          TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT    -rx    -ry   rz
35534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   */
356b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   const float arx = FABSF(rx), ary = FABSF(ry), arz = FABSF(rz);
35734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   GLuint face;
358b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   float sc, tc, ma;
35934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
36034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   if (arx > ary && arx > arz) {
36134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      if (rx >= 0.0F) {
36234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_POS_X;
36334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = -rz;
36434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
36534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arx;
36634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
36734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      else {
36834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_NEG_X;
36934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rz;
37034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
37134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arx;
37234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
37334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
37434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   else if (ary > arx && ary > arz) {
37534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      if (ry >= 0.0F) {
37634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_POS_Y;
37734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rx;
37834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = rz;
37934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = ary;
38034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
38134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      else {
38234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_NEG_Y;
38334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rx;
38434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -rz;
38534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = ary;
38634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
38734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
38834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   else {
38934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      if (rz > 0.0F) {
39034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_POS_Z;
39134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = rx;
39234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
39334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arz;
39434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
39534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      else {
39634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         face = PIPE_TEX_FACE_NEG_Z;
39734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         sc = -rx;
39834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         tc = -ry;
39934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian         ma = arz;
40034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      }
40134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
40234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
40334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   newCoord[0] = ( sc / ma + 1.0F ) * 0.5F;
40434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   newCoord[1] = ( tc / ma + 1.0F ) * 0.5F;
40534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
40634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   return face;
40734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
40834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
40934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
410b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/**
411b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * Examine the quad's texture coordinates to compute the partial
412b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * derivatives w.r.t X and Y, then compute lambda (level of detail).
413b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian *
414b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * This is only done for fragment shaders, not vertex shaders.
415b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian */
416b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic float
417b4480285ed5098f1c862690ee105dd46f5e6cd1eBriancompute_lambda(struct tgsi_sampler *sampler,
418b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float s[QUAD_SIZE],
419b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float t[QUAD_SIZE],
420f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian               const float p[QUAD_SIZE],
421f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian               float lodbias)
422b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian{
423b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   float rho, lambda;
424b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
425b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   assert(s);
426b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   {
427b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dsdx = s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT];
428b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dsdy = s[QUAD_TOP_LEFT]     - s[QUAD_BOTTOM_LEFT];
429b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      dsdx = FABSF(dsdx);
430b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      dsdy = FABSF(dsdy);
431c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      /* XXX only multiply by width for NORMALIZEd texcoords */
432b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      rho = MAX2(dsdx, dsdy) * sampler->texture->width0;
433b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
434b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   if (t) {
435b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT];
436b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dtdy = t[QUAD_TOP_LEFT]     - t[QUAD_BOTTOM_LEFT];
437b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float max;
438b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      dtdx = FABSF(dtdx);
439b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      dtdy = FABSF(dtdy);
440c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      /* XXX only multiply by height for NORMALIZEd texcoords */
441b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      max = MAX2(dtdx, dtdy) * sampler->texture->height0;
442b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      rho = MAX2(rho, max);
443b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
444b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   if (p) {
445b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dpdx = p[QUAD_BOTTOM_RIGHT] - p[QUAD_BOTTOM_LEFT];
446b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float dpdy = p[QUAD_TOP_LEFT]     - p[QUAD_BOTTOM_LEFT];
447b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float max;
448b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      dpdx = FABSF(dpdx);
449b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      dpdy = FABSF(dpdy);
450c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      /* XXX only multiply by depth for NORMALIZEd texcoords */
451b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      max = MAX2(dpdx, dpdy) * sampler->texture->depth0;
452b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      rho = MAX2(rho, max);
453b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
454b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
455b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   lambda = LOG2(rho);
456b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
457f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian   lambda += lodbias + sampler->state->lod_bias;
458b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   lambda = CLAMP(lambda, sampler->state->min_lod, sampler->state->max_lod);
459b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
460b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   return lambda;
461b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian}
462b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
463b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
464f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian
465f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian/**
466c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * Do several things here:
467c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 1. Compute lambda from the texcoords, if needed
468c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 2. Determine if we're minifying or magnifying
469c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 3. If minifying, choose mipmap levels
470c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 4. Return image filter to use within mipmap images
471f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian */
472f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrianstatic void
473c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brianchoose_mipmap_levels(struct tgsi_sampler *sampler,
474c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     const float s[QUAD_SIZE],
475c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     const float t[QUAD_SIZE],
476c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     const float p[QUAD_SIZE],
477c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     float lodbias,
478c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     unsigned *level0, unsigned *level1, float *levelBlend,
479c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                     unsigned *imgFilter)
48009a1b912605ff48c8782dcc5aae55ac77e27037bBrian{
481c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian   if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) {
482c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      /* no mipmap selection needed */
483c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      assert(sampler->state->min_img_filter ==
484c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian             sampler->state->mag_img_filter);
485c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      *imgFilter = sampler->state->mag_img_filter;
486f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      *level0 = *level1 = 0;
487c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian   }
488c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian   else {
489c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      float lambda;
490c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian
491c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      if (1)
492c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* fragment shader */
493c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         lambda = compute_lambda(sampler, s, t, p, lodbias);
494c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      else
495c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* vertex shader */
496c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         lambda = lodbias; /* not really a bias, but absolute LOD */
497c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian
498c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      if (lambda < 0.0) { /* XXX threshold depends on the filter */
499c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* magnifying */
500c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         *imgFilter = sampler->state->mag_img_filter;
501c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         *level0 = *level1 = 0;
502f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      }
503c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian      else {
504c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* minifying */
505c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         *imgFilter = sampler->state->min_img_filter;
506c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian
507c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         /* choose mipmap level(s) and compute the blend factor between them */
508c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NEAREST) {
509c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            /* Nearest mipmap level */
510c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            const int lvl = (int) (lambda + 0.5);
511c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            *level0 =
512c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            *level1 = CLAMP(lvl,
513c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                            (int) sampler->texture->first_level,
514c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                            (int) sampler->texture->last_level);
515c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         }
516c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         else {
517c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            /* Linear interpolation between mipmap levels */
518c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            const int lvl = (int) lambda;
519c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            *level0 = CLAMP(lvl,
520c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                            (int) sampler->texture->first_level,
521c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                            (int) sampler->texture->last_level);
522c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            *level1 = CLAMP(lvl + 1,
523c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                            (int) sampler->texture->first_level,
524c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                            (int) sampler->texture->last_level);
525c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian            *levelBlend = FRAC(lambda);  /* blending weight between levels */
526c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian         }
527f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      }
52809a1b912605ff48c8782dcc5aae55ac77e27037bBrian   }
52909a1b912605ff48c8782dcc5aae55ac77e27037bBrian}
53009a1b912605ff48c8782dcc5aae55ac77e27037bBrian
53108f33a025100dea2d951e6d628891fe294b18082Brian
532a13de2464dd034ff117f9314df5757d068cae8e5Brian
5330dc4eea64f56cc93e5359372b08b99a2d600273cBrian/**
534a13de2464dd034ff117f9314df5757d068cae8e5Brian * Given the texture face, level, zslice, x and y values, compute
535a13de2464dd034ff117f9314df5757d068cae8e5Brian * the cache entry position/index where we'd hope to find the
536a13de2464dd034ff117f9314df5757d068cae8e5Brian * cached texture tile.
537a13de2464dd034ff117f9314df5757d068cae8e5Brian * This is basically a direct-map cache.
538a13de2464dd034ff117f9314df5757d068cae8e5Brian * XXX There's probably lots of ways in which we can improve
539a13de2464dd034ff117f9314df5757d068cae8e5Brian * texture caching....
540b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian */
541a13de2464dd034ff117f9314df5757d068cae8e5Brianstatic unsigned
542a13de2464dd034ff117f9314df5757d068cae8e5Briancompute_cache_pos(unsigned face, unsigned level, unsigned zslice,
543a13de2464dd034ff117f9314df5757d068cae8e5Brian                  int tx, int ty)
544b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian{
545a13de2464dd034ff117f9314df5757d068cae8e5Brian   unsigned entry = tx + ty * 2 + zslice *4 + level + face;
546a13de2464dd034ff117f9314df5757d068cae8e5Brian   return entry % TEX_CACHE_NUM_ENTRIES;
547b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian}
548b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
549b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
550b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/**
551a13de2464dd034ff117f9314df5757d068cae8e5Brian * Get a texel from a texture, using the texture tile cache.
552a13de2464dd034ff117f9314df5757d068cae8e5Brian *
553b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param face  the cube face in 0..5
554b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param level  the mipmap level
555b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param zslize  which slice of a 3D texture
556b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param x  the x coord of texel within 2D image
557b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param y  the y coord of texel within 2D image
558b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param rgba  the quad to put the texel/color into
559b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param j  which element of the rgba quad to write to
560b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian */
561b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic void
562b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianget_texel(struct tgsi_sampler *sampler,
563b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian          unsigned face, unsigned level, unsigned zslice, int x, int y,
564a13de2464dd034ff117f9314df5757d068cae8e5Brian          float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j)
565b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian{
566a13de2464dd034ff117f9314df5757d068cae8e5Brian   int tx = x / TEX_CACHE_TILE_SIZE;
567a13de2464dd034ff117f9314df5757d068cae8e5Brian   int ty = y / TEX_CACHE_TILE_SIZE;
568a13de2464dd034ff117f9314df5757d068cae8e5Brian   unsigned entry = compute_cache_pos(face, level, zslice, tx, ty);
569a13de2464dd034ff117f9314df5757d068cae8e5Brian
570a13de2464dd034ff117f9314df5757d068cae8e5Brian   if (tx != sampler->cache[entry].x ||
571a13de2464dd034ff117f9314df5757d068cae8e5Brian       ty != sampler->cache[entry].y ||
572a13de2464dd034ff117f9314df5757d068cae8e5Brian       face != sampler->cache[entry].face ||
573a13de2464dd034ff117f9314df5757d068cae8e5Brian       level != sampler->cache[entry].level ||
574a13de2464dd034ff117f9314df5757d068cae8e5Brian       zslice != sampler->cache[entry].zslice) {
575a13de2464dd034ff117f9314df5757d068cae8e5Brian      /* entry is not what's expected */
576a13de2464dd034ff117f9314df5757d068cae8e5Brian      struct pipe_context *pipe = (struct pipe_context *) sampler->pipe;
577a13de2464dd034ff117f9314df5757d068cae8e5Brian      struct pipe_surface *ps
578a13de2464dd034ff117f9314df5757d068cae8e5Brian         = pipe->get_tex_surface(pipe, sampler->texture, face, level, zslice);
579b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
580b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      printf("cache miss (%d, %d)\n", x, y);
581a13de2464dd034ff117f9314df5757d068cae8e5Brian
582a13de2464dd034ff117f9314df5757d068cae8e5Brian      assert(ps->width == sampler->texture->level[level].width);
583a13de2464dd034ff117f9314df5757d068cae8e5Brian      assert(ps->height == sampler->texture->level[level].height);
584a13de2464dd034ff117f9314df5757d068cae8e5Brian      sampler->cache[entry].x = tx;
585a13de2464dd034ff117f9314df5757d068cae8e5Brian      sampler->cache[entry].y = ty;
586a13de2464dd034ff117f9314df5757d068cae8e5Brian      sampler->cache[entry].level = level;
587a13de2464dd034ff117f9314df5757d068cae8e5Brian      sampler->cache[entry].face = face;
588a13de2464dd034ff117f9314df5757d068cae8e5Brian      sampler->cache[entry].zslice = zslice;
589a13de2464dd034ff117f9314df5757d068cae8e5Brian      ps->get_tile(ps,
590a13de2464dd034ff117f9314df5757d068cae8e5Brian                   tx * TEX_CACHE_TILE_SIZE,
591a13de2464dd034ff117f9314df5757d068cae8e5Brian                   ty * TEX_CACHE_TILE_SIZE,
592a13de2464dd034ff117f9314df5757d068cae8e5Brian                   TEX_CACHE_TILE_SIZE, TEX_CACHE_TILE_SIZE,
593a13de2464dd034ff117f9314df5757d068cae8e5Brian                   (float *) sampler->cache[entry].data);
594b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
595b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   else {
596f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      /*
597b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      printf("cache hit (%d, %d)\n", x, y);
598f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      */
599b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
600b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
601a13de2464dd034ff117f9314df5757d068cae8e5Brian   /* get the texel from cache entry */
602a13de2464dd034ff117f9314df5757d068cae8e5Brian   tx = x % TEX_CACHE_TILE_SIZE;
603a13de2464dd034ff117f9314df5757d068cae8e5Brian   ty = y % TEX_CACHE_TILE_SIZE;
604a13de2464dd034ff117f9314df5757d068cae8e5Brian   rgba[0][j] = sampler->cache[entry].data[ty][tx][0];
605a13de2464dd034ff117f9314df5757d068cae8e5Brian   rgba[1][j] = sampler->cache[entry].data[ty][tx][1];
606a13de2464dd034ff117f9314df5757d068cae8e5Brian   rgba[2][j] = sampler->cache[entry].data[ty][tx][2];
607a13de2464dd034ff117f9314df5757d068cae8e5Brian   rgba[3][j] = sampler->cache[entry].data[ty][tx][3];
608b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian}
609b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
610b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
611b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
612c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brianstatic void
613c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Briansp_get_samples_1d(struct tgsi_sampler *sampler,
614c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                  const float s[QUAD_SIZE],
615c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                  const float t[QUAD_SIZE],
616c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                  const float p[QUAD_SIZE],
617c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                  float lodbias,
618c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                  float rgba[NUM_CHANNELS][QUAD_SIZE])
619c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian{
620c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian}
621c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian
622c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian
623b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/**
624b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * Called via tgsi_sampler::get_samples()
6250dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Use the sampler's state setting to get a filtered RGBA value
6260dc4eea64f56cc93e5359372b08b99a2d600273cBrian * from the sampler's texture (mipmap tree).
6270dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
6280dc4eea64f56cc93e5359372b08b99a2d600273cBrian * XXX we can implement many versions of this function, each
6290dc4eea64f56cc93e5359372b08b99a2d600273cBrian * tightly coded for a specific combination of sampler state
6300dc4eea64f56cc93e5359372b08b99a2d600273cBrian * (nearest + repeat), (bilinear mipmap + clamp), etc.
6310dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
6320dc4eea64f56cc93e5359372b08b99a2d600273cBrian * The update_samplers() function in st_atom_sampler.c could create
6330dc4eea64f56cc93e5359372b08b99a2d600273cBrian * a new tgsi_sampler object for each state combo it finds....
6340dc4eea64f56cc93e5359372b08b99a2d600273cBrian */
635e12810d92ffb3547680b227bf88937c03018112bBrianstatic void
636b4480285ed5098f1c862690ee105dd46f5e6cd1eBriansp_get_samples_2d(struct tgsi_sampler *sampler,
637b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  const float s[QUAD_SIZE],
638b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  const float t[QUAD_SIZE],
639b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  const float p[QUAD_SIZE],
640f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian                  float lodbias,
641b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  float rgba[NUM_CHANNELS][QUAD_SIZE])
6420dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
643f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian   unsigned level0, level1, j, imgFilter;
644f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian   int width, height;
645c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian   float levelBlend;
646b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
647c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian   choose_mipmap_levels(sampler, s, t, p, lodbias,
648c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian                        &level0, &level1, &levelBlend, &imgFilter);
64909a1b912605ff48c8782dcc5aae55ac77e27037bBrian
650b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   width = sampler->texture->level[level0].width;
651b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   height = sampler->texture->level[level0].height;
65209a1b912605ff48c8782dcc5aae55ac77e27037bBrian
653b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   assert(width > 0);
654612cfb749c3526eeb446bbc631bf24716522f373Brian
655b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   switch (imgFilter) {
6560dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_FILTER_NEAREST:
657b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      for (j = 0; j < QUAD_SIZE; j++) {
658b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         int x = nearest_texcoord(sampler->state->wrap_s, s[j], width);
659b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         int y = nearest_texcoord(sampler->state->wrap_t, t[j], height);
660b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         get_texel(sampler, 0, level0, 0, x, y, rgba, j);
661f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian
662f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian         if (level0 != level1) {
663f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            /* get texels from second mipmap level and blend */
664f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            float rgba2[4][4];
665f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            unsigned c;
666f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            x = x / 2;
667f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            y = y / 2;
668f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            get_texel(sampler, 0, level1, 0, x, y, rgba2, j);
669f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            for (c = 0; c < NUM_CHANNELS; c++) {
670c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian               rgba[c][j] = LERP(levelBlend, rgba2[c][j], rgba[c][j]);
671f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            }
672f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian         }
6730dc4eea64f56cc93e5359372b08b99a2d600273cBrian      }
6740dc4eea64f56cc93e5359372b08b99a2d600273cBrian      break;
6750dc4eea64f56cc93e5359372b08b99a2d600273cBrian   case PIPE_TEX_FILTER_LINEAR:
676b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      for (j = 0; j < QUAD_SIZE; j++) {
677b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         float tx[4][4], a, b;
678b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         int x0, y0, x1, y1, c;
679b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         linear_texcoord(sampler->state->wrap_s, s[j], width,  &x0, &x1, &a);
680b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         linear_texcoord(sampler->state->wrap_t, t[j], height, &y0, &y1, &b);
681b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         get_texel(sampler, 0, level0, 0, x0, y0, tx, 0);
682b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         get_texel(sampler, 0, level0, 0, x1, y0, tx, 1);
683b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         get_texel(sampler, 0, level0, 0, x0, y1, tx, 2);
684b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         get_texel(sampler, 0, level0, 0, x1, y1, tx, 3);
685b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         for (c = 0; c < 4; c++) {
686b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian            rgba[c][j] = lerp_2d(a, b, tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
687b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian         }
688f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian
689f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian         if (level0 != level1) {
690f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            /* get texels from second mipmap level and blend */
691f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            float rgba2[4][4];
692f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            unsigned c;
693f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            x0 = x0 / 2;
694f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            y0 = y0 / 2;
695f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            x1 = x1 / 2;
696f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            y1 = y1 / 2;
697f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            get_texel(sampler, 0, level1, 0, x0, y0, tx, 0);
698f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            get_texel(sampler, 0, level1, 0, x1, y0, tx, 1);
699f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            get_texel(sampler, 0, level1, 0, x0, y1, tx, 2);
700f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            get_texel(sampler, 0, level1, 0, x1, y1, tx, 3);
701f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            for (c = 0; c < 4; c++) {
702f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian               rgba2[c][j] = lerp_2d(a, b,
703f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian                                     tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
704f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            }
705f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian
706f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            for (c = 0; c < NUM_CHANNELS; c++) {
707c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian               rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]);
708f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian            }
709f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian         }
71009a1b912605ff48c8782dcc5aae55ac77e27037bBrian      }
71109a1b912605ff48c8782dcc5aae55ac77e27037bBrian      break;
7120dc4eea64f56cc93e5359372b08b99a2d600273cBrian   default:
7130dc4eea64f56cc93e5359372b08b99a2d600273cBrian      assert(0);
7140dc4eea64f56cc93e5359372b08b99a2d600273cBrian   }
7150dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
71634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
71734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
71834a48abd5ff82ce9748fc29191e35a0985d47c5fBrianstatic void
719b4480285ed5098f1c862690ee105dd46f5e6cd1eBriansp_get_samples_3d(struct tgsi_sampler *sampler,
720b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  const float s[QUAD_SIZE],
721b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  const float t[QUAD_SIZE],
722b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  const float p[QUAD_SIZE],
723f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian                  float lodbias,
724b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                  float rgba[NUM_CHANNELS][QUAD_SIZE])
72534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
72634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   /* get/map pipe_surfaces corresponding to 3D tex slices */
72734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
72834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
72934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
73034a48abd5ff82ce9748fc29191e35a0985d47c5fBrianstatic void
731b4480285ed5098f1c862690ee105dd46f5e6cd1eBriansp_get_samples_cube(struct tgsi_sampler *sampler,
732b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                    const float s[QUAD_SIZE],
733b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                    const float t[QUAD_SIZE],
734b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                    const float p[QUAD_SIZE],
735f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian                    float lodbias,
736b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian                    float rgba[NUM_CHANNELS][QUAD_SIZE])
73734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
738b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   GLuint j;
739b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   for (j = 0; j < QUAD_SIZE; j++) {
740b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      float st[4];
741b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      GLuint face = choose_cube_face(s[j], t[j], p[j], st);
742b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      (void) face;
743b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian      /* get/map surface corresponding to the face */
744b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
74534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
74634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
74734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
74834a48abd5ff82ce9748fc29191e35a0985d47c5fBrianvoid
749b4480285ed5098f1c862690ee105dd46f5e6cd1eBriansp_get_samples(struct tgsi_sampler *sampler,
750b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float s[QUAD_SIZE],
751b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float t[QUAD_SIZE],
752b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               const float p[QUAD_SIZE],
753f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian               float lodbias,
754b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian               float rgba[NUM_CHANNELS][QUAD_SIZE])
75534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
75634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   switch (sampler->texture->target) {
75734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   case GL_TEXTURE_1D:
758f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      sp_get_samples_1d(sampler, s, t, p, lodbias, rgba);
75934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
76034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   case GL_TEXTURE_2D:
761f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      sp_get_samples_2d(sampler, s, t, p, lodbias, rgba);
76234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
76334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   case GL_TEXTURE_3D:
764f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      sp_get_samples_3d(sampler, s, t, p, lodbias, rgba);
76534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
76634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   case GL_TEXTURE_CUBE_MAP:
767f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian      sp_get_samples_cube(sampler, s, t, p, lodbias, rgba);
76834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
76934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   default:
77034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      assert(0);
77134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
77234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
77334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
774