12cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/*
22cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Mesa 3-D graphics library
3249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian * Version:  7.3
42cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *
5249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
62cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *
72cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Permission is hereby granted, free of charge, to any person obtaining a
82cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * copy of this software and associated documentation files (the "Software"),
92cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * to deal in the Software without restriction, including without limitation
102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * the rights to use, copy, modify, merge, publish, distribute, sublicense,
112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * and/or sell copies of the Software, and to permit persons to whom the
122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Software is furnished to do so, subject to the following conditions:
132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *
142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * The above copyright notice and this permission notice shall be included
152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * in all copies or substantial portions of the Software.
162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *
172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */
242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
26bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/glheader.h"
27bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/context.h"
28bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/colormac.h"
29bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/imports.h"
30f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul#include "main/texobj.h"
31cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen#include "main/samplerobj.h"
322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#include "s_context.h"
342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#include "s_texfilter.h"
352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
37249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian/*
38249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian * Note, the FRAC macro has to work perfectly.  Otherwise you'll sometimes
39249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian * see 1-pixel bands of improperly weighted linear-filtered textures.
40249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian * The tests/texwrap.c demo is a good test.
41249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0.
42249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x).
43249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian */
44249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian#define FRAC(f)  ((f) - IFLOOR(f))
45249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian
46249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian
472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**
49bd32640f77c72e79fb5dda0e5fd077e564b33b02Brian Paul * Linear interpolation macro
502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */
512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#define LERP(T, A, B)  ( (A) + (T) * ((B) - (A)) )
522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**
552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Do 2D/biliner interpolation of float values.
562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * v00, v10, v01 and v11 are typically four texture samples in a square/box.
572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * a and b are the horizontal and vertical interpolants.
582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * It's important that this function is inlined when compiled with
592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * optimization!  If we find that's not true on some systems, convert
602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * to a macro.
612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */
629520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLfloat
632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paullerp_2d(GLfloat a, GLfloat b,
642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul        GLfloat v00, GLfloat v10, GLfloat v01, GLfloat v11)
652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLfloat temp0 = LERP(a, v00, v10);
672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLfloat temp1 = LERP(a, v01, v11);
682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   return LERP(b, temp0, temp1);
692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**
732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Do 3D/trilinear interpolation of float values.
742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * \sa lerp_2d
752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */
769520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLfloat
772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paullerp_3d(GLfloat a, GLfloat b, GLfloat c,
782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul        GLfloat v000, GLfloat v100, GLfloat v010, GLfloat v110,
792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul        GLfloat v001, GLfloat v101, GLfloat v011, GLfloat v111)
802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLfloat temp00 = LERP(a, v000, v100);
822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLfloat temp10 = LERP(a, v010, v110);
832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLfloat temp01 = LERP(a, v001, v101);
842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLfloat temp11 = LERP(a, v011, v111);
852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLfloat temp0 = LERP(b, temp00, temp10);
862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLfloat temp1 = LERP(b, temp01, temp11);
872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   return LERP(c, temp0, temp1);
882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**
922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Do linear interpolation of colors.
932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */
949520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void
95de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paullerp_rgba(GLfloat result[4], GLfloat t, const GLfloat a[4], const GLfloat b[4])
962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   result[0] = LERP(t, a[0], b[0]);
982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   result[1] = LERP(t, a[1], b[1]);
992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   result[2] = LERP(t, a[2], b[2]);
1002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   result[3] = LERP(t, a[3], b[3]);
1012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
1022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
1032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
1042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**
1052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Do bilinear interpolation of colors.
1062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */
1079520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void
108de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paullerp_rgba_2d(GLfloat result[4], GLfloat a, GLfloat b,
109de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul             const GLfloat t00[4], const GLfloat t10[4],
110de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul             const GLfloat t01[4], const GLfloat t11[4])
1112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
1122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   result[0] = lerp_2d(a, b, t00[0], t10[0], t01[0], t11[0]);
1132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   result[1] = lerp_2d(a, b, t00[1], t10[1], t01[1], t11[1]);
1142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   result[2] = lerp_2d(a, b, t00[2], t10[2], t01[2], t11[2]);
1152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   result[3] = lerp_2d(a, b, t00[3], t10[3], t01[3], t11[3]);
1162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
1172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
1182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
1192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**
1200f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul * Do trilinear interpolation of colors.
1210f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul */
1229520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void
123de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paullerp_rgba_3d(GLfloat result[4], GLfloat a, GLfloat b, GLfloat c,
124de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul             const GLfloat t000[4], const GLfloat t100[4],
125de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul             const GLfloat t010[4], const GLfloat t110[4],
126de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul             const GLfloat t001[4], const GLfloat t101[4],
127de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul             const GLfloat t011[4], const GLfloat t111[4])
1280f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul{
1290f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   GLuint k;
1300f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   /* compiler should unroll these short loops */
1310f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   for (k = 0; k < 4; k++) {
1320f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul      result[k] = lerp_3d(a, b, c, t000[k], t100[k], t010[k], t110[k],
1330f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul                                   t001[k], t101[k], t011[k], t111[k]);
1340f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   }
1350f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul}
1360f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul
1370f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul
1380f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul/**
1395ba62cd4139e95c752453a1591eb3e47b6b18238Brian Paul * Used for GL_REPEAT wrap mode.  Using A % B doesn't produce the
1405ba62cd4139e95c752453a1591eb3e47b6b18238Brian Paul * right results for A<0.  Casting to A to be unsigned only works if B
1415ba62cd4139e95c752453a1591eb3e47b6b18238Brian Paul * is a power of two.  Adding a bias to A (which is a multiple of B)
1425ba62cd4139e95c752453a1591eb3e47b6b18238Brian Paul * avoids the problems with A < 0 (for reasonable A) without using a
1435ba62cd4139e95c752453a1591eb3e47b6b18238Brian Paul * conditional.
1442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */
145ed7f4b42307bff4633689d6781cd3643f10041e5Brian Paul#define REMAINDER(A, B) (((A) + (B) * 1024) % (B))
1462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
1472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
1482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**
1492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Used to compute texel locations for linear sampling.
1502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Input:
1512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *    wrapMode = GL_REPEAT, GL_CLAMP, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER
152249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *    s = texcoord in [0,1]
153249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *    size = width (or height or depth) of texture
1542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Output:
155249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *    i0, i1 = returns two nearest texel indexes
156249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *    weight = returns blend factor between texels
1572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */
1589520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void
159249e1e4d30759cd3c55cef0dba75f531cc7c6269Brianlinear_texel_locations(GLenum wrapMode,
160249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian                       const struct gl_texture_image *img,
161249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian                       GLint size, GLfloat s,
162249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian                       GLint *i0, GLint *i1, GLfloat *weight)
163249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian{
164eaf376ba354db11f7729452060570b48a029c9a0Brian Paul   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
165249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   GLfloat u;
166249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   switch (wrapMode) {
167249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   case GL_REPEAT:
168249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      u = s * size - 0.5F;
169eaf376ba354db11f7729452060570b48a029c9a0Brian Paul      if (swImg->_IsPowerOfTwo) {
170249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         *i0 = IFLOOR(u) & (size - 1);
171249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         *i1 = (*i0 + 1) & (size - 1);
172249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      }
173249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      else {
174249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         *i0 = REMAINDER(IFLOOR(u), size);
175249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         *i1 = REMAINDER(*i0 + 1, size);
176249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      }
177249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      break;
178249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   case GL_CLAMP_TO_EDGE:
179249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      if (s <= 0.0F)
180249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         u = 0.0F;
181249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      else if (s >= 1.0F)
182249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         u = (GLfloat) size;
183249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      else
184249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         u = s * size;
185249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      u -= 0.5F;
186249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      *i0 = IFLOOR(u);
187249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      *i1 = *i0 + 1;
188249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      if (*i0 < 0)
189249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         *i0 = 0;
190249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      if (*i1 >= (GLint) size)
191249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         *i1 = size - 1;
192249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      break;
193249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   case GL_CLAMP_TO_BORDER:
194249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      {
195249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         const GLfloat min = -1.0F / (2.0F * size);
196249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         const GLfloat max = 1.0F - min;
197249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         if (s <= min)
198249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            u = min * size;
199249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         else if (s >= max)
200249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            u = max * size;
201249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         else
202249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            u = s * size;
203249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         u -= 0.5F;
204249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         *i0 = IFLOOR(u);
205249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         *i1 = *i0 + 1;
206249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      }
207249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      break;
208249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   case GL_MIRRORED_REPEAT:
209249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      {
210249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         const GLint flr = IFLOOR(s);
211249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         if (flr & 1)
212249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            u = 1.0F - (s - (GLfloat) flr);
213249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         else
214249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            u = s - (GLfloat) flr;
215249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         u = (u * size) - 0.5F;
216249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         *i0 = IFLOOR(u);
217249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         *i1 = *i0 + 1;
218249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         if (*i0 < 0)
219249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            *i0 = 0;
220249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         if (*i1 >= (GLint) size)
221249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            *i1 = size - 1;
222249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      }
223249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      break;
224249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   case GL_MIRROR_CLAMP_EXT:
225249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      u = FABSF(s);
226249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      if (u >= 1.0F)
227249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         u = (GLfloat) size;
228249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      else
229249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         u *= size;
230249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      u -= 0.5F;
231249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      *i0 = IFLOOR(u);
232249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      *i1 = *i0 + 1;
233249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      break;
234249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   case GL_MIRROR_CLAMP_TO_EDGE_EXT:
235249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      u = FABSF(s);
236249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      if (u >= 1.0F)
237249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         u = (GLfloat) size;
238249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      else
239249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         u *= size;
240249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      u -= 0.5F;
241249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      *i0 = IFLOOR(u);
242249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      *i1 = *i0 + 1;
243249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      if (*i0 < 0)
244249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         *i0 = 0;
245249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      if (*i1 >= (GLint) size)
246249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         *i1 = size - 1;
247249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      break;
248249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   case GL_MIRROR_CLAMP_TO_BORDER_EXT:
249249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      {
250249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         const GLfloat min = -1.0F / (2.0F * size);
251249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         const GLfloat max = 1.0F - min;
252249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         u = FABSF(s);
253249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         if (u <= min)
254249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            u = min * size;
255249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         else if (u >= max)
256249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            u = max * size;
257249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         else
258249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            u *= size;
259249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         u -= 0.5F;
260249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         *i0 = IFLOOR(u);
261249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         *i1 = *i0 + 1;
262249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      }
263249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      break;
264249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   case GL_CLAMP:
265249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      if (s <= 0.0F)
266249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         u = 0.0F;
267249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      else if (s >= 1.0F)
268249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         u = (GLfloat) size;
269249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      else
270249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         u = s * size;
271249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      u -= 0.5F;
272249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      *i0 = IFLOOR(u);
273249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      *i1 = *i0 + 1;
274249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      break;
275249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   default:
276249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      _mesa_problem(NULL, "Bad wrap mode");
277249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      u = 0.0F;
27803bbcd447cbaa28b52465ae1045013f1aff420c2Chad Versace      break;
279249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   }
280249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   *weight = FRAC(u);
2812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
2822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
2832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
2842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**
2852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Used to compute texel location for nearest sampling.
2862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */
2879520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLint
288249e1e4d30759cd3c55cef0dba75f531cc7c6269Briannearest_texel_location(GLenum wrapMode,
289249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian                       const struct gl_texture_image *img,
290249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian                       GLint size, GLfloat s)
291249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian{
292eaf376ba354db11f7729452060570b48a029c9a0Brian Paul   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
293249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   GLint i;
294249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian
295249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   switch (wrapMode) {
296249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   case GL_REPEAT:
297249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      /* s limited to [0,1) */
298249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      /* i limited to [0,size-1] */
299249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      i = IFLOOR(s * size);
300eaf376ba354db11f7729452060570b48a029c9a0Brian Paul      if (swImg->_IsPowerOfTwo)
301249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         i &= (size - 1);
302249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      else
303249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         i = REMAINDER(i, size);
304249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      return i;
305249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   case GL_CLAMP_TO_EDGE:
306249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      {
307249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         /* s limited to [min,max] */
308249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         /* i limited to [0, size-1] */
309249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         const GLfloat min = 1.0F / (2.0F * size);
310249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         const GLfloat max = 1.0F - min;
311249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         if (s < min)
312249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            i = 0;
313249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         else if (s > max)
314249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            i = size - 1;
315249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         else
316249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            i = IFLOOR(s * size);
317249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      }
318249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      return i;
319249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   case GL_CLAMP_TO_BORDER:
320249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      {
321249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         /* s limited to [min,max] */
322249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         /* i limited to [-1, size] */
323249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         const GLfloat min = -1.0F / (2.0F * size);
324249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         const GLfloat max = 1.0F - min;
325249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         if (s <= min)
326249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            i = -1;
327249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         else if (s >= max)
328249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            i = size;
329249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         else
330249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            i = IFLOOR(s * size);
331249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      }
332249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      return i;
333249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   case GL_MIRRORED_REPEAT:
334249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      {
335249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         const GLfloat min = 1.0F / (2.0F * size);
336249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         const GLfloat max = 1.0F - min;
337249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         const GLint flr = IFLOOR(s);
338249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         GLfloat u;
339249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         if (flr & 1)
340249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            u = 1.0F - (s - (GLfloat) flr);
341249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         else
342249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            u = s - (GLfloat) flr;
343249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         if (u < min)
344249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            i = 0;
345249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         else if (u > max)
346249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            i = size - 1;
347249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         else
348249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            i = IFLOOR(u * size);
349249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      }
350249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      return i;
351249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   case GL_MIRROR_CLAMP_EXT:
352249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      {
353249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         /* s limited to [0,1] */
354249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         /* i limited to [0,size-1] */
355249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         const GLfloat u = FABSF(s);
356249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         if (u <= 0.0F)
357249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            i = 0;
358249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         else if (u >= 1.0F)
359249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            i = size - 1;
360249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         else
361249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            i = IFLOOR(u * size);
362249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      }
363249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      return i;
364249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   case GL_MIRROR_CLAMP_TO_EDGE_EXT:
365249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      {
366249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         /* s limited to [min,max] */
367249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         /* i limited to [0, size-1] */
368249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         const GLfloat min = 1.0F / (2.0F * size);
369249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         const GLfloat max = 1.0F - min;
370249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         const GLfloat u = FABSF(s);
371249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         if (u < min)
372249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            i = 0;
373249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         else if (u > max)
374249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            i = size - 1;
375249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         else
376249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            i = IFLOOR(u * size);
377249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      }
378249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      return i;
379249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   case GL_MIRROR_CLAMP_TO_BORDER_EXT:
380249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      {
381249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         /* s limited to [min,max] */
382249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         /* i limited to [0, size-1] */
383249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         const GLfloat min = -1.0F / (2.0F * size);
384249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         const GLfloat max = 1.0F - min;
385249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         const GLfloat u = FABSF(s);
386249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         if (u < min)
387249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            i = -1;
388249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         else if (u > max)
389249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            i = size;
390249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         else
391249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian            i = IFLOOR(u * size);
392249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      }
393249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      return i;
394249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   case GL_CLAMP:
395249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      /* s limited to [0,1] */
396249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      /* i limited to [0,size-1] */
397249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      if (s <= 0.0F)
398249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         i = 0;
399249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      else if (s >= 1.0F)
400249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         i = size - 1;
401249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      else
402249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian         i = IFLOOR(s * size);
403249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      return i;
404249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   default:
405249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      _mesa_problem(NULL, "Bad wrap mode");
406249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian      return 0;
407249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   }
4082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
4092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
4102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
4112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/* Power of two image sizes only */
4129520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void
413249e1e4d30759cd3c55cef0dba75f531cc7c6269Brianlinear_repeat_texel_location(GLuint size, GLfloat s,
414249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian                             GLint *i0, GLint *i1, GLfloat *weight)
415249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian{
416249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   GLfloat u = s * size - 0.5F;
417249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   *i0 = IFLOOR(u) & (size - 1);
418249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   *i1 = (*i0 + 1) & (size - 1);
419249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   *weight = FRAC(u);
4202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
4212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
4222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
423792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul/**
424a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul * Do clamp/wrap for a texture rectangle coord, GL_NEAREST filter mode.
425a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul */
4269520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLint
427a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paulclamp_rect_coord_nearest(GLenum wrapMode, GLfloat coord, GLint max)
428a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul{
429a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   switch (wrapMode) {
430a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   case GL_CLAMP:
431a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      return IFLOOR( CLAMP(coord, 0.0F, max - 1) );
432a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   case GL_CLAMP_TO_EDGE:
433a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      return IFLOOR( CLAMP(coord, 0.5F, max - 0.5F) );
434a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   case GL_CLAMP_TO_BORDER:
435a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      return IFLOOR( CLAMP(coord, -0.5F, max + 0.5F) );
436a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   default:
437a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      _mesa_problem(NULL, "bad wrapMode in clamp_rect_coord_nearest");
438a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      return 0;
439a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   }
440a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul}
441a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul
442a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul
443a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul/**
444a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul * As above, but GL_LINEAR filtering.
445a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul */
4469520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void
447a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paulclamp_rect_coord_linear(GLenum wrapMode, GLfloat coord, GLint max,
448a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul                        GLint *i0out, GLint *i1out, GLfloat *weight)
449a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul{
450a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   GLfloat fcol;
451a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   GLint i0, i1;
452a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   switch (wrapMode) {
453a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   case GL_CLAMP:
454a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      /* Not exactly what the spec says, but it matches NVIDIA output */
455880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul      fcol = CLAMP(coord - 0.5F, 0.0F, max - 1);
456a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      i0 = IFLOOR(fcol);
457a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      i1 = i0 + 1;
458a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      break;
459a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   case GL_CLAMP_TO_EDGE:
460a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      fcol = CLAMP(coord, 0.5F, max - 0.5F);
461a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      fcol -= 0.5F;
462a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      i0 = IFLOOR(fcol);
463a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      i1 = i0 + 1;
464a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      if (i1 > max - 1)
465a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul         i1 = max - 1;
466a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      break;
467a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   case GL_CLAMP_TO_BORDER:
468a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      fcol = CLAMP(coord, -0.5F, max + 0.5F);
469a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      fcol -= 0.5F;
470a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      i0 = IFLOOR(fcol);
471a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      i1 = i0 + 1;
472dcf571aff9de1a4298c4d2c4148d84cdc4daf02eBrian Paul      break;
473a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   default:
474a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      _mesa_problem(NULL, "bad wrapMode in clamp_rect_coord_linear");
475a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      i0 = i1 = 0;
476a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      fcol = 0.0F;
47703bbcd447cbaa28b52465ae1045013f1aff420c2Chad Versace      break;
478a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   }
479a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   *i0out = i0;
480a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   *i1out = i1;
481a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   *weight = FRAC(fcol);
482a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul}
483a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul
484a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul
485a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul/**
48658ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul * Compute slice/image to use for 1D or 2D array texture.
48758ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul */
4889520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLint
48958ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paultex_array_slice(GLfloat coord, GLsizei size)
49058ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul{
491bdbb5f8170f48713b741ad68c26464231a01ca7aBrian Paul   GLint slice = IFLOOR(coord + 0.5f);
49258ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul   slice = CLAMP(slice, 0, size - 1);
49358ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul   return slice;
49458ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul}
49558ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul
49658ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul
49758ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul/**
498a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul * Compute nearest integer texcoords for given texobj and coordinate.
4992b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul * NOTE: only used for depth texture sampling.
500a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul */
5019520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void
502cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminennearest_texcoord(const struct gl_sampler_object *samp,
503cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                 const struct gl_texture_object *texObj,
5042b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul                 GLuint level,
505a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul                 const GLfloat texcoord[4],
506a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul                 GLint *i, GLint *j, GLint *k)
507a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul{
5082b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul   const struct gl_texture_image *img = texObj->Image[0][level];
509a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   const GLint width = img->Width;
510a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   const GLint height = img->Height;
511a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   const GLint depth = img->Depth;
512a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul
513a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   switch (texObj->Target) {
514a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   case GL_TEXTURE_RECTANGLE_ARB:
515cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      *i = clamp_rect_coord_nearest(samp->WrapS, texcoord[0], width);
516cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      *j = clamp_rect_coord_nearest(samp->WrapT, texcoord[1], height);
517a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      *k = 0;
518a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      break;
519a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   case GL_TEXTURE_1D:
520cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      *i = nearest_texel_location(samp->WrapS, img, width, texcoord[0]);
521a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      *j = 0;
522a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      *k = 0;
523a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      break;
524a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   case GL_TEXTURE_2D:
525cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      *i = nearest_texel_location(samp->WrapS, img, width, texcoord[0]);
526cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      *j = nearest_texel_location(samp->WrapT, img, height, texcoord[1]);
527a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      *k = 0;
528a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      break;
529a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   case GL_TEXTURE_1D_ARRAY_EXT:
530cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      *i = nearest_texel_location(samp->WrapS, img, width, texcoord[0]);
53158ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul      *j = tex_array_slice(texcoord[1], height);
532a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      *k = 0;
533a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      break;
534a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   case GL_TEXTURE_2D_ARRAY_EXT:
535cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      *i = nearest_texel_location(samp->WrapS, img, width, texcoord[0]);
536cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      *j = nearest_texel_location(samp->WrapT, img, height, texcoord[1]);
53758ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul      *k = tex_array_slice(texcoord[2], depth);
538a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      break;
539a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   default:
540a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      *i = *j = *k = 0;
54103bbcd447cbaa28b52465ae1045013f1aff420c2Chad Versace      break;
542a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   }
543a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul}
544a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul
545a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul
546a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul/**
547a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul * Compute linear integer texcoords for given texobj and coordinate.
5482b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul * NOTE: only used for depth texture sampling.
549a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul */
5509520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void
551cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminenlinear_texcoord(const struct gl_sampler_object *samp,
552cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                const struct gl_texture_object *texObj,
5532b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul                GLuint level,
554a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul                const GLfloat texcoord[4],
555a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul                GLint *i0, GLint *i1, GLint *j0, GLint *j1, GLint *slice,
556a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul                GLfloat *wi, GLfloat *wj)
557a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul{
5582b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul   const struct gl_texture_image *img = texObj->Image[0][level];
559a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   const GLint width = img->Width;
560a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   const GLint height = img->Height;
561a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   const GLint depth = img->Depth;
562a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul
563a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   switch (texObj->Target) {
564a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   case GL_TEXTURE_RECTANGLE_ARB:
565cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      clamp_rect_coord_linear(samp->WrapS, texcoord[0],
566a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul                              width, i0, i1, wi);
567cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      clamp_rect_coord_linear(samp->WrapT, texcoord[1],
568a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul                              height, j0, j1, wj);
569a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      *slice = 0;
570a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      break;
571a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul
572a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   case GL_TEXTURE_1D:
573a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   case GL_TEXTURE_2D:
574cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      linear_texel_locations(samp->WrapS, img, width,
575a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul                             texcoord[0], i0, i1, wi);
576cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      linear_texel_locations(samp->WrapT, img, height,
577a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul                             texcoord[1], j0, j1, wj);
578a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      *slice = 0;
579a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      break;
580a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul
581a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   case GL_TEXTURE_1D_ARRAY_EXT:
582cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      linear_texel_locations(samp->WrapS, img, width,
583a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul                             texcoord[0], i0, i1, wi);
58458ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul      *j0 = tex_array_slice(texcoord[1], height);
585a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      *j1 = *j0;
586a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      *slice = 0;
587a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      break;
588a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul
589a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   case GL_TEXTURE_2D_ARRAY_EXT:
590cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      linear_texel_locations(samp->WrapS, img, width,
591a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul                             texcoord[0], i0, i1, wi);
592cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      linear_texel_locations(samp->WrapT, img, height,
593a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul                             texcoord[1], j0, j1, wj);
59458ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul      *slice = tex_array_slice(texcoord[2], depth);
595a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      break;
596a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul
597a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   default:
598a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      *slice = 0;
59903bbcd447cbaa28b52465ae1045013f1aff420c2Chad Versace      break;
600a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   }
601a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul}
602a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul
603a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul
604a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul
605a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul/**
606792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul * For linear interpolation between mipmap levels N and N+1, this function
607792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul * computes N.
6082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */
6099520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLint
610792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paullinear_mipmap_level(const struct gl_texture_object *tObj, GLfloat lambda)
611792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul{
612792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul   if (lambda < 0.0F)
613792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul      return tObj->BaseLevel;
614792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul   else if (lambda > tObj->_MaxLambda)
615792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul      return (GLint) (tObj->BaseLevel + tObj->_MaxLambda);
616792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul   else
617792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul      return (GLint) (tObj->BaseLevel + lambda);
6182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
6192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
6202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
621792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul/**
622792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul * Compute the nearest mipmap level to take texels from.
6232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */
6249520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLint
625792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paulnearest_mipmap_level(const struct gl_texture_object *tObj, GLfloat lambda)
626792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul{
627792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul   GLfloat l;
628792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul   GLint level;
629792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul   if (lambda <= 0.5F)
630792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul      l = 0.0F;
631792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul   else if (lambda > tObj->_MaxLambda + 0.4999F)
632792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul      l = tObj->_MaxLambda + 0.4999F;
633792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul   else
634792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul      l = lambda;
635792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul   level = (GLint) (tObj->BaseLevel + l + 0.5F);
636792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul   if (level > tObj->_MaxLevel)
637792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul      level = tObj->_MaxLevel;
638792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul   return level;
6392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
6402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
6412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
6422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
6432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/*
6442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Bitflags for texture border color sampling.
6452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */
6462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#define I0BIT   1
6472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#define I1BIT   2
6482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#define J0BIT   4
6492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#define J1BIT   8
6502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#define K0BIT  16
6512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#define K1BIT  32
6522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
6532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
6542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
6556e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/**
6562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * The lambda[] array values are always monotonic.  Either the whole span
6572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * will be minified, magnified, or split between the two.  This function
6582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * determines the subranges in [0, n-1] that are to be minified or magnified.
6592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */
6609520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void
661cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminencompute_min_mag_ranges(const struct gl_sampler_object *samp,
662aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul                       GLuint n, const GLfloat lambda[],
663aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul                       GLuint *minStart, GLuint *minEnd,
664aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul                       GLuint *magStart, GLuint *magEnd)
6652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
666aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul   GLfloat minMagThresh;
667aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul
668aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul   /* we shouldn't be here if minfilter == magfilter */
669cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   ASSERT(samp->MinFilter != samp->MagFilter);
670aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul
671aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul   /* This bit comes from the OpenGL spec: */
672cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   if (samp->MagFilter == GL_LINEAR
673cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen       && (samp->MinFilter == GL_NEAREST_MIPMAP_NEAREST ||
674cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen           samp->MinFilter == GL_NEAREST_MIPMAP_LINEAR)) {
675aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul      minMagThresh = 0.5F;
676aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul   }
677aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul   else {
678aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul      minMagThresh = 0.0F;
679aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul   }
680792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul
6812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#if 0
682792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul   /* DEBUG CODE: Verify that lambda[] is monotonic.
6832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul    * We can't really use this because the inaccuracy in the LOG2 function
6842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul    * causes this test to fail, yet the resulting texturing is correct.
6852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul    */
6862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   if (n > 1) {
6872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      GLuint i;
6882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      printf("lambda delta = %g\n", lambda[0] - lambda[n-1]);
6892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (lambda[0] >= lambda[n-1]) { /* decreasing */
6902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         for (i = 0; i < n - 1; i++) {
6912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            ASSERT((GLint) (lambda[i] * 10) >= (GLint) (lambda[i+1] * 10));
6922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
6932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
6942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      else { /* increasing */
6952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         for (i = 0; i < n - 1; i++) {
6962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            ASSERT((GLint) (lambda[i] * 10) <= (GLint) (lambda[i+1] * 10));
6972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
6982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
6992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
7002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#endif /* DEBUG */
7012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
702876b41bc03c9a92263b824378fc2191f85e0a403Brian Paul   if (lambda[0] <= minMagThresh && (n <= 1 || lambda[n-1] <= minMagThresh)) {
7032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      /* magnification for whole span */
7042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      *magStart = 0;
7052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      *magEnd = n;
7062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      *minStart = *minEnd = 0;
7072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
708876b41bc03c9a92263b824378fc2191f85e0a403Brian Paul   else if (lambda[0] > minMagThresh && (n <=1 || lambda[n-1] > minMagThresh)) {
7092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      /* minification for whole span */
7102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      *minStart = 0;
7112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      *minEnd = n;
7122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      *magStart = *magEnd = 0;
7132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
7142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   else {
7152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      /* a mix of minification and magnification */
7162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      GLuint i;
7172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (lambda[0] > minMagThresh) {
7182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         /* start with minification */
7192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         for (i = 1; i < n; i++) {
7202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            if (lambda[i] <= minMagThresh)
7212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul               break;
7222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
7232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         *minStart = 0;
7242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         *minEnd = i;
7252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         *magStart = i;
7262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         *magEnd = n;
7272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
7282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      else {
7292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         /* start with magnification */
7302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         for (i = 1; i < n; i++) {
7312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            if (lambda[i] > minMagThresh)
7322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul               break;
7332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
7342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         *magStart = 0;
7352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         *magEnd = i;
7362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         *minStart = i;
7372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         *minEnd = n;
7382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
7392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
7402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
7412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#if 0
7422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   /* Verify the min/mag Start/End values
7432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul    * We don't use this either (see above)
7442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul    */
7452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   {
7462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      GLint i;
7472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      for (i = 0; i < n; i++) {
7482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         if (lambda[i] > minMagThresh) {
7492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            /* minification */
7502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            ASSERT(i >= *minStart);
7512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            ASSERT(i < *minEnd);
7522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
7532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         else {
7542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            /* magnification */
7552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            ASSERT(i >= *magStart);
7562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            ASSERT(i < *magEnd);
7572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
7582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
7592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
7602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#endif
7612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
7622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
7632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
764b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul/**
765b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul * When we sample the border color, it must be interpreted according to
766b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul * the base texture format.  Ex: if the texture base format it GL_ALPHA,
767b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul * we return (0,0,0,BorderAlpha).
768b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul */
7699520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void
770cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminenget_border_color(const struct gl_sampler_object *samp,
771b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul                 const struct gl_texture_image *img,
772b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul                 GLfloat rgba[4])
773b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul{
7741f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul   switch (img->_BaseFormat) {
775b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul   case GL_RGB:
776cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      rgba[0] = samp->BorderColor.f[0];
777cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      rgba[1] = samp->BorderColor.f[1];
778cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      rgba[2] = samp->BorderColor.f[2];
779b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul      rgba[3] = 1.0F;
780b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul      break;
781b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul   case GL_ALPHA:
782b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul      rgba[0] = rgba[1] = rgba[2] = 0.0;
783cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      rgba[3] = samp->BorderColor.f[3];
784b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul      break;
785b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul   case GL_LUMINANCE:
786cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      rgba[0] = rgba[1] = rgba[2] = samp->BorderColor.f[0];
787b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul      rgba[3] = 1.0;
788b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul      break;
789b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul   case GL_LUMINANCE_ALPHA:
790cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      rgba[0] = rgba[1] = rgba[2] = samp->BorderColor.f[0];
791cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      rgba[3] = samp->BorderColor.f[3];
792b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul      break;
793b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul   case GL_INTENSITY:
794cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      rgba[0] = rgba[1] = rgba[2] = rgba[3] = samp->BorderColor.f[0];
795b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul      break;
796b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul   default:
797cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      COPY_4V(rgba, samp->BorderColor.f);
79803bbcd447cbaa28b52465ae1045013f1aff420c2Chad Versace      break;
799b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul   }
800b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul}
801b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul
802b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul
8039282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul/**
8049282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul * Put z into texel according to GL_DEPTH_MODE.
8059282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul */
8069282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paulstatic INLINE void
8079282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paulapply_depth_mode(GLenum depthMode, GLfloat z, GLfloat texel[4])
8089282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul{
8099282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul   switch (depthMode) {
8109282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul   case GL_LUMINANCE:
8119282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul      ASSIGN_4V(texel, z, z, z, 1.0F);
8129282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul      break;
8139282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul   case GL_INTENSITY:
8149282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul      ASSIGN_4V(texel, z, z, z, z);
8159282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul      break;
8169282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul   case GL_ALPHA:
8179282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul      ASSIGN_4V(texel, 0.0F, 0.0F, 0.0F, z);
8189282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul      break;
8199282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul   case GL_RED:
8209282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul      ASSIGN_4V(texel, z, 0.0F, 0.0F, 1.0F);
8219282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul      break;
8229282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul   default:
8239282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul      _mesa_problem(NULL, "Bad depth texture mode");
8249282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul   }
8259282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul}
8269282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul
8279282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul
8289282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul/**
8299282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul * Is the given texture a depth (or depth/stencil) texture?
8309282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul */
8319282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paulstatic GLboolean
8329282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paulis_depth_texture(const struct gl_texture_object *tObj)
8339282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul{
8349282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul   GLenum format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat;
8359282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul   return format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT;
8369282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul}
8379282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul
8389282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul
8392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/
8402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/*                    1-D Texture Sampling Functions                  */
8412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/
8422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
8436e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/**
8442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Return the texture sample for coordinate (s) using GL_NEAREST filter.
8452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */
8469520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void
847f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_nearest(struct gl_context *ctx,
848cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                  const struct gl_sampler_object *samp,
8492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                  const struct gl_texture_image *img,
850de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                  const GLfloat texcoord[4], GLfloat rgba[4])
8512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
852a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
8532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLint width = img->Width2;  /* without border, power of two */
8542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLint i;
855cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   i = nearest_texel_location(samp->WrapS, img, width, texcoord[0]);
8562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   /* skip over the border, if any */
8572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   i += img->Border;
8582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   if (i < 0 || i >= (GLint) img->Width) {
8592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      /* Need this test for GL_CLAMP_TO_BORDER mode */
860cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      get_border_color(samp, img, rgba);
8612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
8622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   else {
8635ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul      swImg->FetchTexel(swImg, i, 0, 0, rgba);
8642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
8652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
8662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
8672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
8686e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/**
8692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Return the texture sample for coordinate (s) using GL_LINEAR filter.
8702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */
8719520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void
872f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_linear(struct gl_context *ctx,
873cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                 const struct gl_sampler_object *samp,
8742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                 const struct gl_texture_image *img,
875de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                 const GLfloat texcoord[4], GLfloat rgba[4])
8762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
877a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
8782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLint width = img->Width2;
8792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLint i0, i1;
8800f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   GLbitfield useBorderColor = 0x0;
8810f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   GLfloat a;
882de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul   GLfloat t0[4], t1[4];  /* texels */
8832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
884cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   linear_texel_locations(samp->WrapS, img, width, texcoord[0], &i0, &i1, &a);
8852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
8862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   if (img->Border) {
8872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      i0 += img->Border;
8882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      i1 += img->Border;
8892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
8902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   else {
8912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (i0 < 0 || i0 >= width)   useBorderColor |= I0BIT;
8922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (i1 < 0 || i1 >= width)   useBorderColor |= I1BIT;
8932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
8942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
8950f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   /* fetch texel colors */
8960f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   if (useBorderColor & I0BIT) {
897cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      get_border_color(samp, img, t0);
8982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
8990f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   else {
9005ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul      swImg->FetchTexel(swImg, i0, 0, 0, t0);
9010f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   }
9020f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   if (useBorderColor & I1BIT) {
903cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      get_border_color(samp, img, t1);
9040f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   }
9050f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   else {
9065ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul      swImg->FetchTexel(swImg, i1, 0, 0, t1);
9070f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   }
9080f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul
9090f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   lerp_rgba(rgba, a, t0, t1);
9102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
9112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
9122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
9132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
914f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_nearest_mipmap_nearest(struct gl_context *ctx,
915cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                                 const struct gl_sampler_object *samp,
9162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                 const struct gl_texture_object *tObj,
9172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                 GLuint n, const GLfloat texcoord[][4],
918de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                                 const GLfloat lambda[], GLfloat rgba[][4])
9192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
9202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
9212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   ASSERT(lambda != NULL);
9222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   for (i = 0; i < n; i++) {
923792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul      GLint level = nearest_mipmap_level(tObj, lambda[i]);
924cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      sample_1d_nearest(ctx, samp, tObj->Image[0][level], texcoord[i], rgba[i]);
9252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
9262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
9272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
9282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
9292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
930f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_linear_mipmap_nearest(struct gl_context *ctx,
931cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                                const struct gl_sampler_object *samp,
9322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                const struct gl_texture_object *tObj,
9332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                GLuint n, const GLfloat texcoord[][4],
934de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                                const GLfloat lambda[], GLfloat rgba[][4])
9352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
9362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
9372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   ASSERT(lambda != NULL);
9382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   for (i = 0; i < n; i++) {
939792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul      GLint level = nearest_mipmap_level(tObj, lambda[i]);
940cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      sample_1d_linear(ctx, samp, tObj->Image[0][level], texcoord[i], rgba[i]);
9412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
9422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
9432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
9442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
9452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
946f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_nearest_mipmap_linear(struct gl_context *ctx,
947cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                                const struct gl_sampler_object *samp,
9482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                const struct gl_texture_object *tObj,
9492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                GLuint n, const GLfloat texcoord[][4],
950de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                                const GLfloat lambda[], GLfloat rgba[][4])
9512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
9522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
9532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   ASSERT(lambda != NULL);
9542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   for (i = 0; i < n; i++) {
955792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul      GLint level = linear_mipmap_level(tObj, lambda[i]);
9562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (level >= tObj->_MaxLevel) {
957cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_1d_nearest(ctx, samp, tObj->Image[0][tObj->_MaxLevel],
9582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                           texcoord[i], rgba[i]);
9592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
9602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      else {
961de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul         GLfloat t0[4], t1[4];
9622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         const GLfloat f = FRAC(lambda[i]);
963cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_1d_nearest(ctx, samp, tObj->Image[0][level  ], texcoord[i], t0);
964cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_1d_nearest(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1);
9652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         lerp_rgba(rgba[i], f, t0, t1);
9662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
9672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
9682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
9692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
9702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
9712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
972f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_linear_mipmap_linear(struct gl_context *ctx,
973cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                               const struct gl_sampler_object *samp,
9742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                               const struct gl_texture_object *tObj,
9752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                               GLuint n, const GLfloat texcoord[][4],
976de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                               const GLfloat lambda[], GLfloat rgba[][4])
9772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
9782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
9792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   ASSERT(lambda != NULL);
9802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   for (i = 0; i < n; i++) {
981792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul      GLint level = linear_mipmap_level(tObj, lambda[i]);
9822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (level >= tObj->_MaxLevel) {
983cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_1d_linear(ctx, samp, tObj->Image[0][tObj->_MaxLevel],
9842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                          texcoord[i], rgba[i]);
9852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
9862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      else {
987de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul         GLfloat t0[4], t1[4];
9882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         const GLfloat f = FRAC(lambda[i]);
989cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_1d_linear(ctx, samp, tObj->Image[0][level  ], texcoord[i], t0);
990cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_1d_linear(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1);
9912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         lerp_rgba(rgba[i], f, t0, t1);
9922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
9932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
9942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
9952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
9962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
9976e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 1D texture, nearest filtering for both min/magnification */
9982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
999f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_nearest_1d( struct gl_context *ctx,
1000cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                   const struct gl_sampler_object *samp,
10012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                   const struct gl_texture_object *tObj, GLuint n,
10022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                   const GLfloat texcoords[][4], const GLfloat lambda[],
1003de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                   GLfloat rgba[][4] )
10042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
10052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
10062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
10072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   (void) lambda;
10086e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian   for (i = 0; i < n; i++) {
1009cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      sample_1d_nearest(ctx, samp, image, texcoords[i], rgba[i]);
10102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
10112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
10122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
10132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
10146e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 1D texture, linear filtering for both min/magnification */
10152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
1016f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_linear_1d( struct gl_context *ctx,
1017cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                  const struct gl_sampler_object *samp,
10182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                  const struct gl_texture_object *tObj, GLuint n,
10192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                  const GLfloat texcoords[][4], const GLfloat lambda[],
1020de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                  GLfloat rgba[][4] )
10212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
10222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
10232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
10242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   (void) lambda;
10256e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian   for (i = 0; i < n; i++) {
1026cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      sample_1d_linear(ctx, samp, image, texcoords[i], rgba[i]);
10272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
10282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
10292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
10302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
10316e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 1D texture, using lambda to choose between min/magnification */
10322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
1033f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_lambda_1d( struct gl_context *ctx,
1034cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                  const struct gl_sampler_object *samp,
10352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                  const struct gl_texture_object *tObj, GLuint n,
10362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                  const GLfloat texcoords[][4],
1037de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                  const GLfloat lambda[], GLfloat rgba[][4] )
10382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
10392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint minStart, minEnd;  /* texels with minification */
10402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint magStart, magEnd;  /* texels with magnification */
10412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
10422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
10432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   ASSERT(lambda != NULL);
1044cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   compute_min_mag_ranges(samp, n, lambda,
1045aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul                          &minStart, &minEnd, &magStart, &magEnd);
10462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
10472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   if (minStart < minEnd) {
10482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      /* do the minified texels */
10492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      const GLuint m = minEnd - minStart;
1050cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      switch (samp->MinFilter) {
10512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_NEAREST:
10522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         for (i = minStart; i < minEnd; i++)
1053cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            sample_1d_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel],
10542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                              texcoords[i], rgba[i]);
10552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
10562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_LINEAR:
10572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         for (i = minStart; i < minEnd; i++)
1058cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            sample_1d_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel],
10592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                             texcoords[i], rgba[i]);
10602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
10612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_NEAREST_MIPMAP_NEAREST:
1062cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_1d_nearest_mipmap_nearest(ctx, samp, tObj, m, texcoords + minStart,
10632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                          lambda + minStart, rgba + minStart);
10642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
10652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_LINEAR_MIPMAP_NEAREST:
1066cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_1d_linear_mipmap_nearest(ctx, samp, tObj, m, texcoords + minStart,
10672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                         lambda + minStart, rgba + minStart);
10682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
10692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_NEAREST_MIPMAP_LINEAR:
1070cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_1d_nearest_mipmap_linear(ctx, samp, tObj, m, texcoords + minStart,
10712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                         lambda + minStart, rgba + minStart);
10722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
10732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_LINEAR_MIPMAP_LINEAR:
1074cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_1d_linear_mipmap_linear(ctx, samp, tObj, m, texcoords + minStart,
10752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                        lambda + minStart, rgba + minStart);
10762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
10772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      default:
10782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         _mesa_problem(ctx, "Bad min filter in sample_1d_texture");
10792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         return;
10802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
10812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
10822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
10832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   if (magStart < magEnd) {
10842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      /* do the magnified texels */
1085cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      switch (samp->MagFilter) {
10862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_NEAREST:
10872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         for (i = magStart; i < magEnd; i++)
1088cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            sample_1d_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel],
10892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                              texcoords[i], rgba[i]);
10902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
10912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_LINEAR:
10922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         for (i = magStart; i < magEnd; i++)
1093cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            sample_1d_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel],
10942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                             texcoords[i], rgba[i]);
10952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
10962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      default:
10972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         _mesa_problem(ctx, "Bad mag filter in sample_1d_texture");
10982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         return;
10992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
11002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
11012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
11022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
11032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
11042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/
11052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/*                    2-D Texture Sampling Functions                  */
11062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/
11072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
11082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
11096e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/**
11102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Return the texture sample for coordinate (s,t) using GL_NEAREST filter.
11112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */
11129520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void
1113f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_nearest(struct gl_context *ctx,
1114cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                  const struct gl_sampler_object *samp,
11152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                  const struct gl_texture_image *img,
11162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                  const GLfloat texcoord[4],
1117de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                  GLfloat rgba[])
11182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
1119a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
11202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLint width = img->Width2;    /* without border, power of two */
11212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLint height = img->Height2;  /* without border, power of two */
11222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLint i, j;
11232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   (void) ctx;
11242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
1125cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   i = nearest_texel_location(samp->WrapS, img, width, texcoord[0]);
1126cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   j = nearest_texel_location(samp->WrapT, img, height, texcoord[1]);
11272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
11282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   /* skip over the border, if any */
11292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   i += img->Border;
11302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   j += img->Border;
11312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
11322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   if (i < 0 || i >= (GLint) img->Width || j < 0 || j >= (GLint) img->Height) {
11332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      /* Need this test for GL_CLAMP_TO_BORDER mode */
1134cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      get_border_color(samp, img, rgba);
11352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
11362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   else {
11375ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul      swImg->FetchTexel(swImg, i, j, 0, rgba);
11382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
11392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
11402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
11412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
11422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**
11432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Return the texture sample for coordinate (s,t) using GL_LINEAR filter.
11442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * New sampling code contributed by Lynn Quam <quam@ai.sri.com>.
11452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */
11469520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void
1147f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_linear(struct gl_context *ctx,
1148cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                 const struct gl_sampler_object *samp,
11492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                 const struct gl_texture_image *img,
11502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                 const GLfloat texcoord[4],
1151de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                 GLfloat rgba[])
11522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
1153a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
11542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLint width = img->Width2;
11552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLint height = img->Height2;
11562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLint i0, j0, i1, j1;
11570f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   GLbitfield useBorderColor = 0x0;
11580f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   GLfloat a, b;
1159de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul   GLfloat t00[4], t10[4], t01[4], t11[4]; /* sampled texel colors */
11602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
1161cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   linear_texel_locations(samp->WrapS, img, width, texcoord[0],  &i0, &i1, &a);
1162cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   linear_texel_locations(samp->WrapT, img, height, texcoord[1], &j0, &j1, &b);
11632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
11642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   if (img->Border) {
11652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      i0 += img->Border;
11662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      i1 += img->Border;
11672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      j0 += img->Border;
11682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      j1 += img->Border;
11692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
11702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   else {
11712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (i0 < 0 || i0 >= width)   useBorderColor |= I0BIT;
11722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (i1 < 0 || i1 >= width)   useBorderColor |= I1BIT;
11732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (j0 < 0 || j0 >= height)  useBorderColor |= J0BIT;
11742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (j1 < 0 || j1 >= height)  useBorderColor |= J1BIT;
11752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
11762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
11770f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   /* fetch four texel colors */
11780f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   if (useBorderColor & (I0BIT | J0BIT)) {
1179cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      get_border_color(samp, img, t00);
11800f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   }
11810f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   else {
11825ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul      swImg->FetchTexel(swImg, i0, j0, 0, t00);
11830f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   }
11840f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   if (useBorderColor & (I1BIT | J0BIT)) {
1185cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      get_border_color(samp, img, t10);
11860f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   }
11870f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   else {
11885ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul      swImg->FetchTexel(swImg, i1, j0, 0, t10);
11890f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   }
11900f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   if (useBorderColor & (I0BIT | J1BIT)) {
1191cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      get_border_color(samp, img, t01);
11920f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   }
11930f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   else {
11945ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul      swImg->FetchTexel(swImg, i0, j1, 0, t01);
11950f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   }
11960f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   if (useBorderColor & (I1BIT | J1BIT)) {
1197cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      get_border_color(samp, img, t11);
11980f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   }
11990f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   else {
12005ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul      swImg->FetchTexel(swImg, i1, j1, 0, t11);
12012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
12020f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul
12030f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   lerp_rgba_2d(rgba, a, b, t00, t10, t01, t11);
12042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
12052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
12062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
12076e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/**
12082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * As above, but we know WRAP_S == REPEAT and WRAP_T == REPEAT.
12092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * We don't have to worry about the texture border.
12102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */
12119520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void
1212f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_linear_repeat(struct gl_context *ctx,
1213cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                        const struct gl_sampler_object *samp,
12142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                        const struct gl_texture_image *img,
12152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                        const GLfloat texcoord[4],
1216de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                        GLfloat rgba[])
12172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
1218a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
12192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLint width = img->Width2;
12202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLint height = img->Height2;
12212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLint i0, j0, i1, j1;
1222249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   GLfloat wi, wj;
1223de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul   GLfloat t00[4], t10[4], t01[4], t11[4]; /* sampled texel colors */
12240f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul
12259ebe3b6d369c946e41b5f6a684a4ac4e3509b67cBrian Paul   (void) ctx;
12269ebe3b6d369c946e41b5f6a684a4ac4e3509b67cBrian Paul
1227cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   ASSERT(samp->WrapS == GL_REPEAT);
1228cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   ASSERT(samp->WrapT == GL_REPEAT);
12292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   ASSERT(img->Border == 0);
1230eaf376ba354db11f7729452060570b48a029c9a0Brian Paul   ASSERT(swImg->_IsPowerOfTwo);
12312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
1232249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   linear_repeat_texel_location(width,  texcoord[0], &i0, &i1, &wi);
1233249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   linear_repeat_texel_location(height, texcoord[1], &j0, &j1, &wj);
12342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
12355ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul   swImg->FetchTexel(swImg, i0, j0, 0, t00);
12365ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul   swImg->FetchTexel(swImg, i1, j0, 0, t10);
12375ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul   swImg->FetchTexel(swImg, i0, j1, 0, t01);
12385ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul   swImg->FetchTexel(swImg, i1, j1, 0, t11);
12392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
1240249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian   lerp_rgba_2d(rgba, wi, wj, t00, t10, t01, t11);
12412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
12422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
12432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
12442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
1245f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_nearest_mipmap_nearest(struct gl_context *ctx,
1246cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                                 const struct gl_sampler_object *samp,
12472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                 const struct gl_texture_object *tObj,
12482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                 GLuint n, const GLfloat texcoord[][4],
1249de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                                 const GLfloat lambda[], GLfloat rgba[][4])
12502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
12512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
12522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   for (i = 0; i < n; i++) {
1253792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul      GLint level = nearest_mipmap_level(tObj, lambda[i]);
1254cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      sample_2d_nearest(ctx, samp, tObj->Image[0][level], texcoord[i], rgba[i]);
12552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
12562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
12572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
12582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
12592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
1260f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_linear_mipmap_nearest(struct gl_context *ctx,
1261cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                                const struct gl_sampler_object *samp,
12622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                const struct gl_texture_object *tObj,
12632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                GLuint n, const GLfloat texcoord[][4],
1264de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                                const GLfloat lambda[], GLfloat rgba[][4])
12652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
12662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
12672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   ASSERT(lambda != NULL);
12682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   for (i = 0; i < n; i++) {
1269792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul      GLint level = nearest_mipmap_level(tObj, lambda[i]);
1270cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      sample_2d_linear(ctx, samp, tObj->Image[0][level], texcoord[i], rgba[i]);
12712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
12722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
12732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
12742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
12752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
1276f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_nearest_mipmap_linear(struct gl_context *ctx,
1277cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                                const struct gl_sampler_object *samp,
12782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                const struct gl_texture_object *tObj,
12792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                GLuint n, const GLfloat texcoord[][4],
1280de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                                const GLfloat lambda[], GLfloat rgba[][4])
12812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
12822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
12832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   ASSERT(lambda != NULL);
12842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   for (i = 0; i < n; i++) {
1285792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul      GLint level = linear_mipmap_level(tObj, lambda[i]);
12862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (level >= tObj->_MaxLevel) {
1287cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_nearest(ctx, samp, tObj->Image[0][tObj->_MaxLevel],
12882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                           texcoord[i], rgba[i]);
12892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
12902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      else {
1291de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul         GLfloat t0[4], t1[4];  /* texels */
12922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         const GLfloat f = FRAC(lambda[i]);
1293cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_nearest(ctx, samp, tObj->Image[0][level  ], texcoord[i], t0);
1294cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_nearest(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1);
12952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         lerp_rgba(rgba[i], f, t0, t1);
12962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
12972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
12982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
12992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
13002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
13012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
1302f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_linear_mipmap_linear( struct gl_context *ctx,
1303cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                                const struct gl_sampler_object *samp,
13042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                const struct gl_texture_object *tObj,
13052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                GLuint n, const GLfloat texcoord[][4],
1306de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                                const GLfloat lambda[], GLfloat rgba[][4] )
13072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
13082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
13092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   ASSERT(lambda != NULL);
13102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   for (i = 0; i < n; i++) {
1311792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul      GLint level = linear_mipmap_level(tObj, lambda[i]);
13122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (level >= tObj->_MaxLevel) {
1313cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_linear(ctx, samp, tObj->Image[0][tObj->_MaxLevel],
13142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                          texcoord[i], rgba[i]);
13152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
13162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      else {
1317de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul         GLfloat t0[4], t1[4];  /* texels */
13182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         const GLfloat f = FRAC(lambda[i]);
1319cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_linear(ctx, samp, tObj->Image[0][level  ], texcoord[i], t0);
1320cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_linear(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1);
13212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         lerp_rgba(rgba[i], f, t0, t1);
13222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
13232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
13242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
13252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
13262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
13272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
1328f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_linear_mipmap_linear_repeat(struct gl_context *ctx,
1329cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                                      const struct gl_sampler_object *samp,
13306e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                                      const struct gl_texture_object *tObj,
13316e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                                      GLuint n, const GLfloat texcoord[][4],
1332de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                                      const GLfloat lambda[], GLfloat rgba[][4])
13332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
13342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
13352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   ASSERT(lambda != NULL);
1336cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   ASSERT(samp->WrapS == GL_REPEAT);
1337cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   ASSERT(samp->WrapT == GL_REPEAT);
13382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   for (i = 0; i < n; i++) {
1339792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul      GLint level = linear_mipmap_level(tObj, lambda[i]);
13402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (level >= tObj->_MaxLevel) {
1341cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_linear_repeat(ctx, samp, tObj->Image[0][tObj->_MaxLevel],
13422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                 texcoord[i], rgba[i]);
13432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
13442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      else {
1345de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul         GLfloat t0[4], t1[4];  /* texels */
13462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         const GLfloat f = FRAC(lambda[i]);
1347cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_linear_repeat(ctx, samp, tObj->Image[0][level  ],
13486e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                                 texcoord[i], t0);
1349cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_linear_repeat(ctx, samp, tObj->Image[0][level+1],
13506e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                                 texcoord[i], t1);
13512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         lerp_rgba(rgba[i], f, t0, t1);
13522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
13532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
13542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
13552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
13562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
13576e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 2D texture, nearest filtering for both min/magnification */
13582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
1359f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_nearest_2d(struct gl_context *ctx,
1360cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                  const struct gl_sampler_object *samp,
13616e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                  const struct gl_texture_object *tObj, GLuint n,
13626e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                  const GLfloat texcoords[][4],
1363de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                  const GLfloat lambda[], GLfloat rgba[][4])
13642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
13652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
13662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
13672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   (void) lambda;
13686e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian   for (i = 0; i < n; i++) {
1369cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      sample_2d_nearest(ctx, samp, image, texcoords[i], rgba[i]);
13702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
13712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
13722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
13732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
13746e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 2D texture, linear filtering for both min/magnification */
13752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
1376f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_linear_2d(struct gl_context *ctx,
1377cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                 const struct gl_sampler_object *samp,
13786e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                 const struct gl_texture_object *tObj, GLuint n,
13796e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                 const GLfloat texcoords[][4],
1380de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                 const GLfloat lambda[], GLfloat rgba[][4])
13812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
13822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
13832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
1384eaf376ba354db11f7729452060570b48a029c9a0Brian Paul   const struct swrast_texture_image *swImg = swrast_texture_image_const(image);
13852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   (void) lambda;
1386cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   if (samp->WrapS == GL_REPEAT &&
1387cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen       samp->WrapT == GL_REPEAT &&
1388eaf376ba354db11f7729452060570b48a029c9a0Brian Paul       swImg->_IsPowerOfTwo &&
1389c14d969a69d7b9a060c6701d3f18c51eabc56635Brian       image->Border == 0) {
13906e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian      for (i = 0; i < n; i++) {
1391cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_linear_repeat(ctx, samp, image, texcoords[i], rgba[i]);
13922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
13932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
13942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   else {
13956e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian      for (i = 0; i < n; i++) {
1396cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_linear(ctx, samp, image, texcoords[i], rgba[i]);
13972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
13982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
13992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
14002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
14012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
14026e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/**
14032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Optimized 2-D texture sampling:
14042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *    S and T wrap mode == GL_REPEAT
14052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *    GL_NEAREST min/mag filter
14062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *    No border,
14072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *    RowStride == Width,
14082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *    Format = GL_RGB
14092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */
14102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
1411f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergopt_sample_rgb_2d(struct gl_context *ctx,
1412cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                  const struct gl_sampler_object *samp,
14136e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                  const struct gl_texture_object *tObj,
14146e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                  GLuint n, const GLfloat texcoords[][4],
14156d63dec41f5399dbe5561175c1652d2ac5ffd4bbBrian Paul                  const GLfloat lambda[], GLfloat rgba[][4])
14162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
14172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const struct gl_texture_image *img = tObj->Image[0][tObj->BaseLevel];
1418eaf376ba354db11f7729452060570b48a029c9a0Brian Paul   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
14192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLfloat width = (GLfloat) img->Width;
14202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLfloat height = (GLfloat) img->Height;
14212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLint colMask = img->Width - 1;
14222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLint rowMask = img->Height - 1;
14232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLint shift = img->WidthLog2;
14242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint k;
14252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   (void) ctx;
14262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   (void) lambda;
1427cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   ASSERT(samp->WrapS==GL_REPEAT);
1428cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   ASSERT(samp->WrapT==GL_REPEAT);
14292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   ASSERT(img->Border==0);
14303fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul   ASSERT(img->TexFormat == MESA_FORMAT_RGB888);
1431eaf376ba354db11f7729452060570b48a029c9a0Brian Paul   ASSERT(swImg->_IsPowerOfTwo);
143226b8dfc8cadf0f1a8604fc77b226cc7de005f9caBrian Paul   (void) swImg;
14332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
14342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   for (k=0; k<n; k++) {
14352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      GLint i = IFLOOR(texcoords[k][0] * width) & colMask;
14362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      GLint j = IFLOOR(texcoords[k][1] * height) & rowMask;
14372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      GLint pos = (j << shift) | i;
1438bd3c10c0f0c60ab3421c2da2eab814edc2296cb0Brian Paul      GLubyte *texel = swImg->Map + 3 * pos;
14398c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul      rgba[k][RCOMP] = UBYTE_TO_FLOAT(texel[2]);
14403fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul      rgba[k][GCOMP] = UBYTE_TO_FLOAT(texel[1]);
14418c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul      rgba[k][BCOMP] = UBYTE_TO_FLOAT(texel[0]);
14426a0255122a7d7c0aa09bceacda90a5cea67d5ee2Brian Paul      rgba[k][ACOMP] = 1.0F;
14432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
14442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
14452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
14462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
14476e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/**
14482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Optimized 2-D texture sampling:
14492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *    S and T wrap mode == GL_REPEAT
14502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *    GL_NEAREST min/mag filter
14512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *    No border
14522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *    RowStride == Width,
14532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *    Format = GL_RGBA
14542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */
14552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
1456f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergopt_sample_rgba_2d(struct gl_context *ctx,
1457cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                   const struct gl_sampler_object *samp,
14586e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                   const struct gl_texture_object *tObj,
14596e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                   GLuint n, const GLfloat texcoords[][4],
14606d63dec41f5399dbe5561175c1652d2ac5ffd4bbBrian Paul                   const GLfloat lambda[], GLfloat rgba[][4])
14612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
14622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const struct gl_texture_image *img = tObj->Image[0][tObj->BaseLevel];
1463eaf376ba354db11f7729452060570b48a029c9a0Brian Paul   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
14642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLfloat width = (GLfloat) img->Width;
14652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLfloat height = (GLfloat) img->Height;
14662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLint colMask = img->Width - 1;
14672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLint rowMask = img->Height - 1;
14682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLint shift = img->WidthLog2;
14692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
14702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   (void) ctx;
14712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   (void) lambda;
1472cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   ASSERT(samp->WrapS==GL_REPEAT);
1473cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   ASSERT(samp->WrapT==GL_REPEAT);
14742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   ASSERT(img->Border==0);
14753fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul   ASSERT(img->TexFormat == MESA_FORMAT_RGBA8888);
1476eaf376ba354db11f7729452060570b48a029c9a0Brian Paul   ASSERT(swImg->_IsPowerOfTwo);
147726b8dfc8cadf0f1a8604fc77b226cc7de005f9caBrian Paul   (void) swImg;
14782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
14792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   for (i = 0; i < n; i++) {
14802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      const GLint col = IFLOOR(texcoords[i][0] * width) & colMask;
14812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      const GLint row = IFLOOR(texcoords[i][1] * height) & rowMask;
14822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      const GLint pos = (row << shift) | col;
1483bd3c10c0f0c60ab3421c2da2eab814edc2296cb0Brian Paul      const GLuint texel = *((GLuint *) swImg->Map + pos);
14841e7517f059b1f3601502a199b05453eabfe56cdbBrian Paul      rgba[i][RCOMP] = UBYTE_TO_FLOAT( (texel >> 24)        );
14851e7517f059b1f3601502a199b05453eabfe56cdbBrian Paul      rgba[i][GCOMP] = UBYTE_TO_FLOAT( (texel >> 16) & 0xff );
14861e7517f059b1f3601502a199b05453eabfe56cdbBrian Paul      rgba[i][BCOMP] = UBYTE_TO_FLOAT( (texel >>  8) & 0xff );
14871e7517f059b1f3601502a199b05453eabfe56cdbBrian Paul      rgba[i][ACOMP] = UBYTE_TO_FLOAT( (texel      ) & 0xff );
14882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
14892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
14902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
14912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
14926e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 2D texture, using lambda to choose between min/magnification */
14932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
1494f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_lambda_2d(struct gl_context *ctx,
1495cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                 const struct gl_sampler_object *samp,
14966e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                 const struct gl_texture_object *tObj,
14976e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                 GLuint n, const GLfloat texcoords[][4],
1498de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                 const GLfloat lambda[], GLfloat rgba[][4])
14992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
15002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const struct gl_texture_image *tImg = tObj->Image[0][tObj->BaseLevel];
1501eaf376ba354db11f7729452060570b48a029c9a0Brian Paul   const struct swrast_texture_image *swImg = swrast_texture_image_const(tImg);
15022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint minStart, minEnd;  /* texels with minification */
15032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint magStart, magEnd;  /* texels with magnification */
15042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
1505cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   const GLboolean repeatNoBorderPOT = (samp->WrapS == GL_REPEAT)
1506cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      && (samp->WrapT == GL_REPEAT)
15076e0f9001fe3fb191c2928bd09aa9e9d05ddf4ea9Brian Paul      && (tImg->Border == 0 && (tImg->Width == swImg->RowStride))
1508eaf376ba354db11f7729452060570b48a029c9a0Brian Paul      && swImg->_IsPowerOfTwo;
15092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
15102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   ASSERT(lambda != NULL);
1511cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   compute_min_mag_ranges(samp, n, lambda,
1512aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul                          &minStart, &minEnd, &magStart, &magEnd);
15132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
15142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   if (minStart < minEnd) {
15152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      /* do the minified texels */
15162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      const GLuint m = minEnd - minStart;
1517cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      switch (samp->MinFilter) {
15182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_NEAREST:
15192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         if (repeatNoBorderPOT) {
15201f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul            switch (tImg->TexFormat) {
15213fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul            case MESA_FORMAT_RGB888:
1522cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen               opt_sample_rgb_2d(ctx, samp, tObj, m, texcoords + minStart,
15232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                 NULL, rgba + minStart);
15242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul               break;
15253fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul            case MESA_FORMAT_RGBA8888:
1526cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen	       opt_sample_rgba_2d(ctx, samp, tObj, m, texcoords + minStart,
15272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                  NULL, rgba + minStart);
15282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul               break;
15292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            default:
1530cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen               sample_nearest_2d(ctx, samp, tObj, m, texcoords + minStart,
15312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                 NULL, rgba + minStart );
15322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            }
15332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
15342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         else {
1535cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            sample_nearest_2d(ctx, samp, tObj, m, texcoords + minStart,
15362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                              NULL, rgba + minStart);
15372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
15382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
15392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_LINEAR:
1540cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen	 sample_linear_2d(ctx, samp, tObj, m, texcoords + minStart,
15412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul			  NULL, rgba + minStart);
15422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
15432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_NEAREST_MIPMAP_NEAREST:
1544cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_nearest_mipmap_nearest(ctx, samp, tObj, m,
15452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                          texcoords + minStart,
15462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                          lambda + minStart, rgba + minStart);
15472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
15482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_LINEAR_MIPMAP_NEAREST:
1549cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_linear_mipmap_nearest(ctx, samp, tObj, m, texcoords + minStart,
15502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                         lambda + minStart, rgba + minStart);
15512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
15522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_NEAREST_MIPMAP_LINEAR:
1553cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_nearest_mipmap_linear(ctx, samp, tObj, m, texcoords + minStart,
15542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                         lambda + minStart, rgba + minStart);
15552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
15562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_LINEAR_MIPMAP_LINEAR:
15572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         if (repeatNoBorderPOT)
1558cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            sample_2d_linear_mipmap_linear_repeat(ctx, samp, tObj, m,
15592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                  texcoords + minStart, lambda + minStart, rgba + minStart);
15602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         else
1561cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            sample_2d_linear_mipmap_linear(ctx, samp, tObj, m, texcoords + minStart,
15622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                        lambda + minStart, rgba + minStart);
15632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
15642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      default:
15652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         _mesa_problem(ctx, "Bad min filter in sample_2d_texture");
15662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         return;
15672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
15682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
15692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
15702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   if (magStart < magEnd) {
15712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      /* do the magnified texels */
15722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      const GLuint m = magEnd - magStart;
15732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
1574cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      switch (samp->MagFilter) {
15752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_NEAREST:
15762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         if (repeatNoBorderPOT) {
15771f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul            switch (tImg->TexFormat) {
15783fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul            case MESA_FORMAT_RGB888:
1579cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen               opt_sample_rgb_2d(ctx, samp, tObj, m, texcoords + magStart,
15802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                 NULL, rgba + magStart);
15812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul               break;
15823fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul            case MESA_FORMAT_RGBA8888:
1583cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen	       opt_sample_rgba_2d(ctx, samp, tObj, m, texcoords + magStart,
15842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                  NULL, rgba + magStart);
15852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul               break;
15862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            default:
1587cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen               sample_nearest_2d(ctx, samp, tObj, m, texcoords + magStart,
15882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                 NULL, rgba + magStart );
15892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            }
15902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
15912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         else {
1592cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            sample_nearest_2d(ctx, samp, tObj, m, texcoords + magStart,
15932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                              NULL, rgba + magStart);
15942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
15952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
15962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_LINEAR:
1597cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen	 sample_linear_2d(ctx, samp, tObj, m, texcoords + magStart,
15982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul			  NULL, rgba + magStart);
15992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
16002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      default:
16012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         _mesa_problem(ctx, "Bad mag filter in sample_lambda_2d");
160203bbcd447cbaa28b52465ae1045013f1aff420c2Chad Versace         break;
16032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
16042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
16052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
16062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
16072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
16088a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger/* For anisotropic filtering */
16098a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger#define WEIGHT_LUT_SIZE 1024
16108a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
16118a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengerstatic GLfloat *weightLut = NULL;
16128a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
16138a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger/**
16148a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * Creates the look-up table used to speed-up EWA sampling
16158a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */
16168a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengerstatic void
16178a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengercreate_filter_table(void)
16188a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger{
16198a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLuint i;
16208a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   if (!weightLut) {
16218a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      weightLut = (GLfloat *) malloc(WEIGHT_LUT_SIZE * sizeof(GLfloat));
16228a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
16238a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      for (i = 0; i < WEIGHT_LUT_SIZE; ++i) {
16248a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger         GLfloat alpha = 2;
16258a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger         GLfloat r2 = (GLfloat) i / (GLfloat) (WEIGHT_LUT_SIZE - 1);
16268a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger         GLfloat weight = (GLfloat) exp(-alpha * r2);
16278a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger         weightLut[i] = weight;
16288a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      }
16298a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   }
16308a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger}
16318a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
16328a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
16338a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger/**
16348a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * Elliptical weighted average (EWA) filter for producing high quality
16358a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * anisotropic filtered results.
16368a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * Based on the Higher Quality Elliptical Weighted Avarage Filter
16378a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * published by Paul S. Heckbert in his Master's Thesis
16388a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * "Fundamentals of Texture Mapping and Image Warping" (1989)
16398a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */
16408a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengerstatic void
16418a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengersample_2d_ewa(struct gl_context *ctx,
1642cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen              const struct gl_sampler_object *samp,
16438a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger              const struct gl_texture_object *tObj,
16448a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger              const GLfloat texcoord[4],
16458a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger              const GLfloat dudx, const GLfloat dvdx,
16468a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger              const GLfloat dudy, const GLfloat dvdy, const GLint lod,
16478a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger              GLfloat rgba[])
16488a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger{
16498a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLint level = lod > 0 ? lod : 0;
16508a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat scaling = 1.0 / (1 << level);
16518a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   const struct gl_texture_image *img =	tObj->Image[0][level];
16528a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   const struct gl_texture_image *mostDetailedImage =
16538a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      tObj->Image[0][tObj->BaseLevel];
1654980f6f1b37ca88529b3e000235156eab93254facBrian Paul   const struct swrast_texture_image *swImg =
1655980f6f1b37ca88529b3e000235156eab93254facBrian Paul      swrast_texture_image_const(mostDetailedImage);
1656980f6f1b37ca88529b3e000235156eab93254facBrian Paul   GLfloat tex_u=-0.5 + texcoord[0] * swImg->WidthScale * scaling;
1657980f6f1b37ca88529b3e000235156eab93254facBrian Paul   GLfloat tex_v=-0.5 + texcoord[1] * swImg->HeightScale * scaling;
16588a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
16598a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat ux = dudx * scaling;
16608a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat vx = dvdx * scaling;
16618a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat uy = dudy * scaling;
16628a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat vy = dvdy * scaling;
16638a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
16648a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   /* compute ellipse coefficients to bound the region:
16658a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger    * A*x*x + B*x*y + C*y*y = F.
16668a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger    */
16678a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat A = vx*vx+vy*vy+1;
16688a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat B = -2*(ux*vx+uy*vy);
16698a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat C = ux*ux+uy*uy+1;
16708a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat F = A*C-B*B/4.0;
16718a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
16728a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   /* check if it is an ellipse */
16738a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   /* ASSERT(F > 0.0); */
16748a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
16758a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   /* Compute the ellipse's (u,v) bounding box in texture space */
16768a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat d = -B*B+4.0*C*A;
16778a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat box_u = 2.0 / d * sqrt(d*C*F); /* box_u -> half of bbox with   */
16788a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat box_v = 2.0 / d * sqrt(A*d*F); /* box_v -> half of bbox height */
16798a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
16808a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLint u0 = floor(tex_u - box_u);
16818a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLint u1 = ceil (tex_u + box_u);
16828a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLint v0 = floor(tex_v - box_v);
16838a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLint v1 = ceil (tex_v + box_v);
16848a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
16858a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat num[4] = {0.0F, 0.0F, 0.0F, 0.0F};
16868a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat newCoord[2];
16878a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat den = 0.0F;
16888a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat ddq;
16898a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat U = u0 - tex_u;
16908a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLint v;
16918a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
16928a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   /* Scale ellipse formula to directly index the Filter Lookup Table.
16938a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger    * i.e. scale so that F = WEIGHT_LUT_SIZE-1
16948a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger    */
16958a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   double formScale = (double) (WEIGHT_LUT_SIZE - 1) / F;
16968a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   A *= formScale;
16978a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   B *= formScale;
16988a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   C *= formScale;
16998a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   /* F *= formScale; */ /* no need to scale F as we don't use it below here */
17008a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
17018a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   /* Heckbert MS thesis, p. 59; scan over the bounding box of the ellipse
17028a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger    * and incrementally update the value of Ax^2+Bxy*Cy^2; when this
17038a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger    * value, q, is less than F, we're inside the ellipse
17048a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger    */
17058a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   ddq = 2 * A;
17068a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   for (v = v0; v <= v1; ++v) {
17078a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      GLfloat V = v - tex_v;
17088a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      GLfloat dq = A * (2 * U + 1) + B * V;
17098a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      GLfloat q = (C * V + B * U) * V + A * U * U;
17108a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
17118a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      GLint u;
17128a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      for (u = u0; u <= u1; ++u) {
17138a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger         /* Note that the ellipse has been pre-scaled so F = WEIGHT_LUT_SIZE - 1 */
17148a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger         if (q < WEIGHT_LUT_SIZE) {
17158a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger            /* as a LUT is used, q must never be negative;
17168a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger             * should not happen, though
17178a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger             */
17188a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger            const GLint qClamped = q >= 0.0F ? q : 0;
17198a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger            GLfloat weight = weightLut[qClamped];
17208a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
17218a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger            newCoord[0] = u / ((GLfloat) img->Width2);
17228a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger            newCoord[1] = v / ((GLfloat) img->Height2);
17238a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
1724cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            sample_2d_nearest(ctx, samp, img, newCoord, rgba);
17258a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger            num[0] += weight * rgba[0];
17268a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger            num[1] += weight * rgba[1];
17278a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger            num[2] += weight * rgba[2];
17288a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger            num[3] += weight * rgba[3];
17298a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
17308a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger            den += weight;
17318a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger         }
17328a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger         q += dq;
17338a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger         dq += ddq;
17348a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      }
17358a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   }
17368a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
17378a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   if (den <= 0.0F) {
17388a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      /* Reaching this place would mean
17398a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger       * that no pixels intersected the ellipse.
17408a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger       * This should never happen because
17418a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger       * the filter we use always
17428a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger       * intersects at least one pixel.
17438a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger       */
17448a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
17458a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      /*rgba[0]=0;
17468a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      rgba[1]=0;
17478a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      rgba[2]=0;
17488a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      rgba[3]=0;*/
17498a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      /* not enough pixels in resampling, resort to direct interpolation */
1750cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      sample_2d_linear(ctx, samp, img, texcoord, rgba);
17518a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      return;
17528a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   }
17538a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
17548a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   rgba[0] = num[0] / den;
17558a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   rgba[1] = num[1] / den;
17568a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   rgba[2] = num[2] / den;
17578a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   rgba[3] = num[3] / den;
17588a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger}
17598a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
17608a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
17618a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger/**
17628a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * Anisotropic filtering using footprint assembly as outlined in the
17638a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * EXT_texture_filter_anisotropic spec:
17648a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * http://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt
17658a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * Faster than EWA but has less quality (more aliasing effects)
17668a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */
17678a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengerstatic void
17688a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengersample_2d_footprint(struct gl_context *ctx,
1769cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                 const struct gl_sampler_object *samp,
17708a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger                 const struct gl_texture_object *tObj,
17718a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger                 const GLfloat texcoord[4],
17728a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger                 const GLfloat dudx, const GLfloat dvdx,
17738a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger                 const GLfloat dudy, const GLfloat dvdy, const GLint lod,
17748a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger                 GLfloat rgba[])
17758a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger{
17768a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLint level = lod > 0 ? lod : 0;
17778a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat scaling = 1.0F / (1 << level);
17788a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   const struct gl_texture_image *img = tObj->Image[0][level];
17798a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
17808a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat ux = dudx * scaling;
17818a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat vx = dvdx * scaling;
17828a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat uy = dudy * scaling;
17838a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat vy = dvdy * scaling;
17848a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
17858a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat Px2 = ux * ux + vx * vx; /* squared length of dx */
17868a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat Py2 = uy * uy + vy * vy; /* squared length of dy */
17878a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
17888a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLint numSamples;
17898a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat ds;
17908a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat dt;
17918a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
17928a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat num[4] = {0.0F, 0.0F, 0.0F, 0.0F};
17938a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat newCoord[2];
17948a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLint s;
17958a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
17968a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   /*  Calculate the per anisotropic sample offsets in s,t space. */
17978a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   if (Px2 > Py2) {
17988a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      numSamples = ceil(SQRTF(Px2));
17998a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      ds = ux / ((GLfloat) img->Width2);
18008a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      dt = vx / ((GLfloat) img->Height2);
18018a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   }
18028a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   else {
18038a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      numSamples = ceil(SQRTF(Py2));
18048a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      ds = uy / ((GLfloat) img->Width2);
18058a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      dt = vy / ((GLfloat) img->Height2);
18068a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   }
18078a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
18088a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   for (s = 0; s<numSamples; s++) {
18098a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      newCoord[0] = texcoord[0] + ds * ((GLfloat)(s+1) / (numSamples+1) -0.5);
18108a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      newCoord[1] = texcoord[1] + dt * ((GLfloat)(s+1) / (numSamples+1) -0.5);
18118a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
1812cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      sample_2d_linear(ctx, samp, img, newCoord, rgba);
18138a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      num[0] += rgba[0];
18148a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      num[1] += rgba[1];
18158a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      num[2] += rgba[2];
18168a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      num[3] += rgba[3];
18178a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   }
18188a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
18198a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   rgba[0] = num[0] / numSamples;
18208a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   rgba[1] = num[1] / numSamples;
18218a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   rgba[2] = num[2] / numSamples;
18228a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   rgba[3] = num[3] / numSamples;
18238a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger}
18248a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
18258a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
18268a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger/**
18278a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * Returns the index of the specified texture object in the
18288a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * gl_context texture unit array.
18298a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */
18309520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLuint
18318a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengertexture_unit_index(const struct gl_context *ctx,
18328a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger                   const struct gl_texture_object *tObj)
18338a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger{
18348a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   const GLuint maxUnit
18358a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      = (ctx->Texture._EnabledCoordUnits > 1) ? ctx->Const.MaxTextureUnits : 1;
18368a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLuint u;
18378a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
18388a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   /* XXX CoordUnits vs. ImageUnits */
18398a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   for (u = 0; u < maxUnit; u++) {
18408a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      if (ctx->Texture.Unit[u]._Current == tObj)
18418a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger         break; /* found */
18428a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   }
18438a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   if (u >= maxUnit)
18448a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      u = 0; /* not found, use 1st one; should never happen */
18458a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
18468a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   return u;
18478a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger}
18488a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
18498a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
18508a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger/**
18518a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * Sample 2D texture using an anisotropic filter.
18528a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * NOTE: the const GLfloat lambda_iso[] parameter does *NOT* contain
18538a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * the lambda float array but a "hidden" SWspan struct which is required
18548a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * by this function but is not available in the texture_sample_func signature.
18558a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * See _swrast_texture_span( struct gl_context *ctx, SWspan *span ) on how
18568a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * this function is called.
18578a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */
18588a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengerstatic void
18598a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengersample_lambda_2d_aniso(struct gl_context *ctx,
1860cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                       const struct gl_sampler_object *samp,
18618a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger                       const struct gl_texture_object *tObj,
18628a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger                       GLuint n, const GLfloat texcoords[][4],
18638a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger                       const GLfloat lambda_iso[], GLfloat rgba[][4])
18648a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger{
18658a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   const struct gl_texture_image *tImg = tObj->Image[0][tObj->BaseLevel];
1866980f6f1b37ca88529b3e000235156eab93254facBrian Paul   const struct swrast_texture_image *swImg = swrast_texture_image_const(tImg);
18678a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   const GLfloat maxEccentricity =
1868cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      samp->MaxAnisotropy * samp->MaxAnisotropy;
18698a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
18708a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   /* re-calculate the lambda values so that they are usable with anisotropic
18718a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger    * filtering
18728a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger    */
18738a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   SWspan *span = (SWspan *)lambda_iso; /* access the "hidden" SWspan struct */
18748a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
18758a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   /* based on interpolate_texcoords(struct gl_context *ctx, SWspan *span)
18768a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger    * in swrast/s_span.c
18778a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger    */
18788a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
18798a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   /* find the texture unit index by looking up the current texture object
18808a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger    * from the context list of available texture objects.
18818a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger    */
18828a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   const GLuint u = texture_unit_index(ctx, tObj);
18838a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   const GLuint attr = FRAG_ATTRIB_TEX0 + u;
18848a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat texW, texH;
18858a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
18868a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   const GLfloat dsdx = span->attrStepX[attr][0];
18878a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   const GLfloat dsdy = span->attrStepY[attr][0];
18888a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   const GLfloat dtdx = span->attrStepX[attr][1];
18898a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   const GLfloat dtdy = span->attrStepY[attr][1];
18908a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   const GLfloat dqdx = span->attrStepX[attr][3];
18918a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   const GLfloat dqdy = span->attrStepY[attr][3];
18928a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat s = span->attrStart[attr][0] + span->leftClip * dsdx;
18938a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat t = span->attrStart[attr][1] + span->leftClip * dtdx;
18948a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLfloat q = span->attrStart[attr][3] + span->leftClip * dqdx;
18958a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
18968a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   /* from swrast/s_texcombine.c _swrast_texture_span */
18978a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u];
18988a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   const GLboolean adjustLOD =
1899cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      (texUnit->LodBias + samp->LodBias != 0.0F)
1900cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      || (samp->MinLod != -1000.0 || samp->MaxLod != 1000.0);
19018a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
19028a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   GLuint i;
19038a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
19048a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   /* on first access create the lookup table containing the filter weights. */
19058a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   if (!weightLut) {
19068a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      create_filter_table();
19078a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   }
19088a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
1909980f6f1b37ca88529b3e000235156eab93254facBrian Paul   texW = swImg->WidthScale;
1910980f6f1b37ca88529b3e000235156eab93254facBrian Paul   texH = swImg->HeightScale;
19118a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
19128a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   for (i = 0; i < n; i++) {
19138a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
19148a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
19158a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      GLfloat dudx = texW * ((s + dsdx) / (q + dqdx) - s * invQ);
19168a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      GLfloat dvdx = texH * ((t + dtdx) / (q + dqdx) - t * invQ);
19178a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      GLfloat dudy = texW * ((s + dsdy) / (q + dqdy) - s * invQ);
19188a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      GLfloat dvdy = texH * ((t + dtdy) / (q + dqdy) - t * invQ);
19198a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
19208a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      /* note: instead of working with Px and Py, we will use the
19218a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger       * squared length instead, to avoid sqrt.
19228a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger       */
19238a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      GLfloat Px2 = dudx * dudx + dvdx * dvdx;
19248a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      GLfloat Py2 = dudy * dudy + dvdy * dvdy;
19258a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
19268a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      GLfloat Pmax2;
19278a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      GLfloat Pmin2;
19288a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      GLfloat e;
19298a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      GLfloat lod;
19308a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
19318a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      s += dsdx;
19328a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      t += dtdx;
19338a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      q += dqdx;
19348a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
19358a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      if (Px2 < Py2) {
19368a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger         Pmax2 = Py2;
19378a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger         Pmin2 = Px2;
19388a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      }
19398a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      else {
19408a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger         Pmax2 = Px2;
19418a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger         Pmin2 = Py2;
19428a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      }
19438a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
19448a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      /* if the eccentricity of the ellipse is too big, scale up the shorter
19458a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger       * of the two vectors to limit the maximum amount of work per pixel
19468a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger       */
19478a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      e = Pmax2 / Pmin2;
19488a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      if (e > maxEccentricity) {
19498a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger         /* GLfloat s=e / maxEccentricity;
19508a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger            minor[0] *= s;
19518a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger            minor[1] *= s;
19528a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger            Pmin2 *= s; */
19538a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger         Pmin2 = Pmax2 / maxEccentricity;
19548a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      }
19558a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
19568a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      /* note: we need to have Pmin=sqrt(Pmin2) here, but we can avoid
19578a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger       * this since 0.5*log(x) = log(sqrt(x))
19588a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger       */
19598a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      lod = 0.5 * LOG2(Pmin2);
19608a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
19618a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      if (adjustLOD) {
19628a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger         /* from swrast/s_texcombine.c _swrast_texture_span */
1963cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         if (texUnit->LodBias + samp->LodBias != 0.0F) {
19648a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger            /* apply LOD bias, but don't clamp yet */
19658a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger            const GLfloat bias =
1966cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen               CLAMP(texUnit->LodBias + samp->LodBias,
19678a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger                     -ctx->Const.MaxTextureLodBias,
19688a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger                     ctx->Const.MaxTextureLodBias);
19698a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger            lod += bias;
19708a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
1971cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            if (samp->MinLod != -1000.0 ||
1972cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                samp->MaxLod != 1000.0) {
19738a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger               /* apply LOD clamping to lambda */
1974cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen               lod = CLAMP(lod, samp->MinLod, samp->MaxLod);
19758a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger            }
19768a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger         }
19778a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      }
19788a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
19798a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      /* If the ellipse covers the whole image, we can
19808a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger       * simply return the average of the whole image.
19818a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger       */
19828a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      if (lod >= tObj->_MaxLevel) {
1983cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_linear(ctx, samp, tObj->Image[0][tObj->_MaxLevel],
19848a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger                          texcoords[i], rgba[i]);
19858a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      }
19868a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      else {
19878a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger         /* don't bother interpolating between multiple LODs; it doesn't
19888a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger          * seem to be worth the extra running time.
19898a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger          */
1990cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_ewa(ctx, samp, tObj, texcoords[i],
19918a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger                       dudx, dvdx, dudy, dvdy, floor(lod), rgba[i]);
19928a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
19938a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger         /* unused: */
19948a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger         (void) sample_2d_footprint;
19958a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger         /*
19968a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger         sample_2d_footprint(ctx, tObj, texcoords[i],
19978a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger                             dudx, dvdx, dudy, dvdy, floor(lod), rgba[i]);
19988a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger         */
19998a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger      }
20008a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger   }
20018a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger}
20028a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
20038a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger
20042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
20052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/
20062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/*                    3-D Texture Sampling Functions                  */
20072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/
20082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
20096e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/**
20102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter.
20112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */
20129520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void
2013f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_3d_nearest(struct gl_context *ctx,
2014cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                  const struct gl_sampler_object *samp,
20152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                  const struct gl_texture_image *img,
20162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                  const GLfloat texcoord[4],
2017de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                  GLfloat rgba[4])
20182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
2019a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
20202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLint width = img->Width2;     /* without border, power of two */
20212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLint height = img->Height2;   /* without border, power of two */
20222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLint depth = img->Depth2;     /* without border, power of two */
20232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLint i, j, k;
20242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   (void) ctx;
20252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
2026cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   i = nearest_texel_location(samp->WrapS, img, width, texcoord[0]);
2027cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   j = nearest_texel_location(samp->WrapT, img, height, texcoord[1]);
2028cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   k = nearest_texel_location(samp->WrapR, img, depth, texcoord[2]);
20292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
20302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   if (i < 0 || i >= (GLint) img->Width ||
20312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul       j < 0 || j >= (GLint) img->Height ||
20322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul       k < 0 || k >= (GLint) img->Depth) {
20332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      /* Need this test for GL_CLAMP_TO_BORDER mode */
2034cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      get_border_color(samp, img, rgba);
20352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
20362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   else {
20375ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul      swImg->FetchTexel(swImg, i, j, k, rgba);
20382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
20392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
20402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
20412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
20426e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/**
20432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter.
20442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */
20452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
2046f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_3d_linear(struct gl_context *ctx,
2047cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                 const struct gl_sampler_object *samp,
20482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                 const struct gl_texture_image *img,
20492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                 const GLfloat texcoord[4],
2050de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                 GLfloat rgba[4])
20512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
2052a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
20532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLint width = img->Width2;
20542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLint height = img->Height2;
20552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLint depth = img->Depth2;
20562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLint i0, j0, k0, i1, j1, k1;
20570f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   GLbitfield useBorderColor = 0x0;
20580f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   GLfloat a, b, c;
2059de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul   GLfloat t000[4], t010[4], t001[4], t011[4];
2060de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul   GLfloat t100[4], t110[4], t101[4], t111[4];
20612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
2062cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   linear_texel_locations(samp->WrapS, img, width, texcoord[0],  &i0, &i1, &a);
2063cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   linear_texel_locations(samp->WrapT, img, height, texcoord[1], &j0, &j1, &b);
2064cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   linear_texel_locations(samp->WrapR, img, depth, texcoord[2],  &k0, &k1, &c);
20652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
20662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   if (img->Border) {
20672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      i0 += img->Border;
20682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      i1 += img->Border;
20692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      j0 += img->Border;
20702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      j1 += img->Border;
20712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      k0 += img->Border;
20722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      k1 += img->Border;
20732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
20742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   else {
20752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      /* check if sampling texture border color */
20762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (i0 < 0 || i0 >= width)   useBorderColor |= I0BIT;
20772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (i1 < 0 || i1 >= width)   useBorderColor |= I1BIT;
20782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (j0 < 0 || j0 >= height)  useBorderColor |= J0BIT;
20792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (j1 < 0 || j1 >= height)  useBorderColor |= J1BIT;
20802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (k0 < 0 || k0 >= depth)   useBorderColor |= K0BIT;
20812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (k1 < 0 || k1 >= depth)   useBorderColor |= K1BIT;
20822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
20832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
20840f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   /* Fetch texels */
20850f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   if (useBorderColor & (I0BIT | J0BIT | K0BIT)) {
2086cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      get_border_color(samp, img, t000);
20870f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   }
20880f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   else {
20895ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul      swImg->FetchTexel(swImg, i0, j0, k0, t000);
20900f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   }
20910f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   if (useBorderColor & (I1BIT | J0BIT | K0BIT)) {
2092cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      get_border_color(samp, img, t100);
20930f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   }
20940f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   else {
20955ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul      swImg->FetchTexel(swImg, i1, j0, k0, t100);
20960f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   }
20970f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   if (useBorderColor & (I0BIT | J1BIT | K0BIT)) {
2098cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      get_border_color(samp, img, t010);
20990f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   }
21000f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   else {
21015ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul      swImg->FetchTexel(swImg, i0, j1, k0, t010);
21020f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   }
21030f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   if (useBorderColor & (I1BIT | J1BIT | K0BIT)) {
2104cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      get_border_color(samp, img, t110);
21050f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   }
21060f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   else {
21075ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul      swImg->FetchTexel(swImg, i1, j1, k0, t110);
21080f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   }
21092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
21100f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   if (useBorderColor & (I0BIT | J0BIT | K1BIT)) {
2111cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      get_border_color(samp, img, t001);
21120f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   }
21130f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   else {
21145ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul      swImg->FetchTexel(swImg, i0, j0, k1, t001);
21150f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   }
21160f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   if (useBorderColor & (I1BIT | J0BIT | K1BIT)) {
2117cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      get_border_color(samp, img, t101);
21180f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   }
21190f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   else {
21205ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul      swImg->FetchTexel(swImg, i1, j0, k1, t101);
21210f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   }
21220f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   if (useBorderColor & (I0BIT | J1BIT | K1BIT)) {
2123cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      get_border_color(samp, img, t011);
21240f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   }
21250f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   else {
21265ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul      swImg->FetchTexel(swImg, i0, j1, k1, t011);
21272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
21280f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   if (useBorderColor & (I1BIT | J1BIT | K1BIT)) {
2129cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      get_border_color(samp, img, t111);
21300f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   }
21310f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   else {
21325ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul      swImg->FetchTexel(swImg, i1, j1, k1, t111);
21330f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   }
21340f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul
21350f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   /* trilinear interpolation of samples */
21360f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul   lerp_rgba_3d(rgba, a, b, c, t000, t100, t010, t110, t001, t101, t011, t111);
21372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
21382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
21392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
21402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
2141f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_3d_nearest_mipmap_nearest(struct gl_context *ctx,
2142cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                                 const struct gl_sampler_object *samp,
21432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                 const struct gl_texture_object *tObj,
21442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                 GLuint n, const GLfloat texcoord[][4],
2145de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                                 const GLfloat lambda[], GLfloat rgba[][4] )
21462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
21472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
21482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   for (i = 0; i < n; i++) {
2149792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul      GLint level = nearest_mipmap_level(tObj, lambda[i]);
2150cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      sample_3d_nearest(ctx, samp, tObj->Image[0][level], texcoord[i], rgba[i]);
21512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
21522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
21532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
21542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
21552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
2156f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_3d_linear_mipmap_nearest(struct gl_context *ctx,
2157cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                                const struct gl_sampler_object *samp,
21582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                const struct gl_texture_object *tObj,
21592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                GLuint n, const GLfloat texcoord[][4],
2160de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                                const GLfloat lambda[], GLfloat rgba[][4])
21612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
21622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
21632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   ASSERT(lambda != NULL);
21642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   for (i = 0; i < n; i++) {
2165792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul      GLint level = nearest_mipmap_level(tObj, lambda[i]);
2166cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      sample_3d_linear(ctx, samp, tObj->Image[0][level], texcoord[i], rgba[i]);
21672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
21682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
21692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
21702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
21712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
2172f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_3d_nearest_mipmap_linear(struct gl_context *ctx,
2173cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                                const struct gl_sampler_object *samp,
21742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                const struct gl_texture_object *tObj,
21752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                GLuint n, const GLfloat texcoord[][4],
2176de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                                const GLfloat lambda[], GLfloat rgba[][4])
21772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
21782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
21792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   ASSERT(lambda != NULL);
21802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   for (i = 0; i < n; i++) {
2181792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul      GLint level = linear_mipmap_level(tObj, lambda[i]);
21822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (level >= tObj->_MaxLevel) {
2183cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_3d_nearest(ctx, samp, tObj->Image[0][tObj->_MaxLevel],
21842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                           texcoord[i], rgba[i]);
21852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
21862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      else {
2187de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul         GLfloat t0[4], t1[4];  /* texels */
21882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         const GLfloat f = FRAC(lambda[i]);
2189cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_3d_nearest(ctx, samp, tObj->Image[0][level  ], texcoord[i], t0);
2190cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_3d_nearest(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1);
21912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         lerp_rgba(rgba[i], f, t0, t1);
21922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
21932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
21942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
21952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
21962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
21972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
2198f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_3d_linear_mipmap_linear(struct gl_context *ctx,
2199cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                               const struct gl_sampler_object *samp,
22002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                               const struct gl_texture_object *tObj,
22012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                               GLuint n, const GLfloat texcoord[][4],
2202de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                               const GLfloat lambda[], GLfloat rgba[][4])
22032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
22042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
22052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   ASSERT(lambda != NULL);
22062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   for (i = 0; i < n; i++) {
2207792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul      GLint level = linear_mipmap_level(tObj, lambda[i]);
22082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (level >= tObj->_MaxLevel) {
2209cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_3d_linear(ctx, samp, tObj->Image[0][tObj->_MaxLevel],
22102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                          texcoord[i], rgba[i]);
22112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
22122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      else {
2213de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul         GLfloat t0[4], t1[4];  /* texels */
22142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         const GLfloat f = FRAC(lambda[i]);
2215cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_3d_linear(ctx, samp, tObj->Image[0][level  ], texcoord[i], t0);
2216cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_3d_linear(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1);
22172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         lerp_rgba(rgba[i], f, t0, t1);
22182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
22192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
22202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
22212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
22222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
22236e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 3D texture, nearest filtering for both min/magnification */
22242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
2225f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_nearest_3d(struct gl_context *ctx,
2226cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                  const struct gl_sampler_object *samp,
22272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                  const struct gl_texture_object *tObj, GLuint n,
22282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                  const GLfloat texcoords[][4], const GLfloat lambda[],
2229de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                  GLfloat rgba[][4])
22302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
22312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
22322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
22332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   (void) lambda;
22346e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian   for (i = 0; i < n; i++) {
2235cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      sample_3d_nearest(ctx, samp, image, texcoords[i], rgba[i]);
22362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
22372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
22382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
22392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
22406e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 3D texture, linear filtering for both min/magnification */
22412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
2242f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_linear_3d(struct gl_context *ctx,
2243cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                 const struct gl_sampler_object *samp,
22446e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                 const struct gl_texture_object *tObj, GLuint n,
22456e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                 const GLfloat texcoords[][4],
2246de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul		 const GLfloat lambda[], GLfloat rgba[][4])
22472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
22482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
22492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
22502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   (void) lambda;
22516e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian   for (i = 0; i < n; i++) {
2252cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      sample_3d_linear(ctx, samp, image, texcoords[i], rgba[i]);
22532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
22542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
22552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
22562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
22576e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 3D texture, using lambda to choose between min/magnification */
22582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
2259f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_lambda_3d(struct gl_context *ctx,
2260cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                 const struct gl_sampler_object *samp,
22616e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                 const struct gl_texture_object *tObj, GLuint n,
22626e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                 const GLfloat texcoords[][4], const GLfloat lambda[],
2263de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                 GLfloat rgba[][4])
22642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
22652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint minStart, minEnd;  /* texels with minification */
22662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint magStart, magEnd;  /* texels with magnification */
22672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
22682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
22692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   ASSERT(lambda != NULL);
2270cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   compute_min_mag_ranges(samp, n, lambda,
2271aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul                          &minStart, &minEnd, &magStart, &magEnd);
22722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
22732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   if (minStart < minEnd) {
22742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      /* do the minified texels */
22752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      GLuint m = minEnd - minStart;
2276cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      switch (samp->MinFilter) {
22772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_NEAREST:
22782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         for (i = minStart; i < minEnd; i++)
2279cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            sample_3d_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel],
22802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                              texcoords[i], rgba[i]);
22812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
22822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_LINEAR:
22832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         for (i = minStart; i < minEnd; i++)
2284cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            sample_3d_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel],
22852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                             texcoords[i], rgba[i]);
22862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
22872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_NEAREST_MIPMAP_NEAREST:
2288cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_3d_nearest_mipmap_nearest(ctx, samp, tObj, m, texcoords + minStart,
22892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                          lambda + minStart, rgba + minStart);
22902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
22912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_LINEAR_MIPMAP_NEAREST:
2292cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_3d_linear_mipmap_nearest(ctx, samp, tObj, m, texcoords + minStart,
22932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                         lambda + minStart, rgba + minStart);
22942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
22952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_NEAREST_MIPMAP_LINEAR:
2296cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_3d_nearest_mipmap_linear(ctx, samp, tObj, m, texcoords + minStart,
22972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                         lambda + minStart, rgba + minStart);
22982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
22992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_LINEAR_MIPMAP_LINEAR:
2300cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_3d_linear_mipmap_linear(ctx, samp, tObj, m, texcoords + minStart,
23012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                        lambda + minStart, rgba + minStart);
23022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
23032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      default:
23042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         _mesa_problem(ctx, "Bad min filter in sample_3d_texture");
23052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         return;
23062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
23072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
23082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
23092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   if (magStart < magEnd) {
23102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      /* do the magnified texels */
2311cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      switch (samp->MagFilter) {
23122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_NEAREST:
23132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         for (i = magStart; i < magEnd; i++)
2314cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            sample_3d_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel],
23152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                              texcoords[i], rgba[i]);
23162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
23172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_LINEAR:
23182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         for (i = magStart; i < magEnd; i++)
2319cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            sample_3d_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel],
23202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                             texcoords[i], rgba[i]);
23212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
23222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      default:
23232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         _mesa_problem(ctx, "Bad mag filter in sample_3d_texture");
23242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         return;
23252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
23262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
23272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
23282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
23292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
23302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/
23312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/*                Texture Cube Map Sampling Functions                 */
23322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/
23332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
23342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**
23352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Choose one of six sides of a texture cube map given the texture
23362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * coord (rx,ry,rz).  Return pointer to corresponding array of texture
23372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * images.
23382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */
23392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic const struct gl_texture_image **
23402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulchoose_cube_face(const struct gl_texture_object *texObj,
23412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                 const GLfloat texcoord[4], GLfloat newCoord[4])
23422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
23432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   /*
23442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      major axis
23452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      direction     target                             sc     tc    ma
23462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      ----------    -------------------------------    ---    ---   ---
23472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul       +rx          TEXTURE_CUBE_MAP_POSITIVE_X_EXT    -rz    -ry   rx
23482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul       -rx          TEXTURE_CUBE_MAP_NEGATIVE_X_EXT    +rz    -ry   rx
23492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul       +ry          TEXTURE_CUBE_MAP_POSITIVE_Y_EXT    +rx    +rz   ry
23502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul       -ry          TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT    +rx    -rz   ry
23512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul       +rz          TEXTURE_CUBE_MAP_POSITIVE_Z_EXT    +rx    -ry   rz
23522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul       -rz          TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT    -rx    -ry   rz
23532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   */
23542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLfloat rx = texcoord[0];
23552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLfloat ry = texcoord[1];
23562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLfloat rz = texcoord[2];
23572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const GLfloat arx = FABSF(rx), ary = FABSF(ry), arz = FABSF(rz);
23582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint face;
23592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLfloat sc, tc, ma;
23602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
2361d504a7669d7b71229c2d15503a095d71ee1584e6Brian Paul   if (arx >= ary && arx >= arz) {
23622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (rx >= 0.0F) {
23632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         face = FACE_POS_X;
23642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         sc = -rz;
23652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         tc = -ry;
23662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         ma = arx;
23672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
23682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      else {
23692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         face = FACE_NEG_X;
23702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         sc = rz;
23712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         tc = -ry;
23722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         ma = arx;
23732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
23742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
2375d504a7669d7b71229c2d15503a095d71ee1584e6Brian Paul   else if (ary >= arx && ary >= arz) {
23762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (ry >= 0.0F) {
23772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         face = FACE_POS_Y;
23782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         sc = rx;
23792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         tc = rz;
23802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         ma = ary;
23812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
23822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      else {
23832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         face = FACE_NEG_Y;
23842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         sc = rx;
23852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         tc = -rz;
23862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         ma = ary;
23872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
23882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
23892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   else {
23902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (rz > 0.0F) {
23912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         face = FACE_POS_Z;
23922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         sc = rx;
23932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         tc = -ry;
23942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         ma = arz;
23952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
23962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      else {
23972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         face = FACE_NEG_Z;
23982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         sc = -rx;
23992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         tc = -ry;
24002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         ma = arz;
24012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
24022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
24032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
240467d4a5b15cfd8583c19a5776b0ec1564b60239ebKeith Whitwell   {
240567d4a5b15cfd8583c19a5776b0ec1564b60239ebKeith Whitwell      const float ima = 1.0F / ma;
240667d4a5b15cfd8583c19a5776b0ec1564b60239ebKeith Whitwell      newCoord[0] = ( sc * ima + 1.0F ) * 0.5F;
240767d4a5b15cfd8583c19a5776b0ec1564b60239ebKeith Whitwell      newCoord[1] = ( tc * ima + 1.0F ) * 0.5F;
240867d4a5b15cfd8583c19a5776b0ec1564b60239ebKeith Whitwell   }
240967d4a5b15cfd8583c19a5776b0ec1564b60239ebKeith Whitwell
24102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   return (const struct gl_texture_image **) texObj->Image[face];
24112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
24122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
24132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
24142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
2415f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_nearest_cube(struct gl_context *ctx,
2416cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                    const struct gl_sampler_object *samp,
24172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul		    const struct gl_texture_object *tObj, GLuint n,
24182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                    const GLfloat texcoords[][4], const GLfloat lambda[],
2419de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                    GLfloat rgba[][4])
24202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
24212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
24222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   (void) lambda;
24232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   for (i = 0; i < n; i++) {
24242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      const struct gl_texture_image **images;
24252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      GLfloat newCoord[4];
24262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      images = choose_cube_face(tObj, texcoords[i], newCoord);
2427cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      sample_2d_nearest(ctx, samp, images[tObj->BaseLevel],
24282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                        newCoord, rgba[i]);
24292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
24309282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul   if (is_depth_texture(tObj)) {
24319282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul      for (i = 0; i < n; i++) {
24329282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul         apply_depth_mode(tObj->DepthMode, rgba[i][0], rgba[i]);
24339282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul      }
24349282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul   }
24352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
24362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
24372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
24382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
2439f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_linear_cube(struct gl_context *ctx,
2440cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                   const struct gl_sampler_object *samp,
24412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul		   const struct gl_texture_object *tObj, GLuint n,
24422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                   const GLfloat texcoords[][4],
2443de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul		   const GLfloat lambda[], GLfloat rgba[][4])
24442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
24452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
24462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   (void) lambda;
24472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   for (i = 0; i < n; i++) {
24482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      const struct gl_texture_image **images;
24492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      GLfloat newCoord[4];
24502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      images = choose_cube_face(tObj, texcoords[i], newCoord);
2451cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      sample_2d_linear(ctx, samp, images[tObj->BaseLevel],
24522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                       newCoord, rgba[i]);
24532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
24549282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul   if (is_depth_texture(tObj)) {
24559282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul      for (i = 0; i < n; i++) {
24569282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul         apply_depth_mode(tObj->DepthMode, rgba[i][0], rgba[i]);
24579282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul      }
24589282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul   }
24592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
24602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
24612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
24622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
2463f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_cube_nearest_mipmap_nearest(struct gl_context *ctx,
2464cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                                   const struct gl_sampler_object *samp,
24652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                   const struct gl_texture_object *tObj,
24662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                   GLuint n, const GLfloat texcoord[][4],
2467de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                                   const GLfloat lambda[], GLfloat rgba[][4])
24682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
24692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
24702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   ASSERT(lambda != NULL);
24712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   for (i = 0; i < n; i++) {
24722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      const struct gl_texture_image **images;
24732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      GLfloat newCoord[4];
247421177c8764638e1d4b3b29fed64adec62a14e936Brian Paul      GLint level;
24752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      images = choose_cube_face(tObj, texcoord[i], newCoord);
247621177c8764638e1d4b3b29fed64adec62a14e936Brian Paul
247721177c8764638e1d4b3b29fed64adec62a14e936Brian Paul      /* XXX we actually need to recompute lambda here based on the newCoords.
247821177c8764638e1d4b3b29fed64adec62a14e936Brian Paul       * But we would need the texcoords of adjacent fragments to compute that
247921177c8764638e1d4b3b29fed64adec62a14e936Brian Paul       * properly, and we don't have those here.
248021177c8764638e1d4b3b29fed64adec62a14e936Brian Paul       * For now, do an approximation:  subtracting 1 from the chosen mipmap
248121177c8764638e1d4b3b29fed64adec62a14e936Brian Paul       * level seems to work in some test cases.
248221177c8764638e1d4b3b29fed64adec62a14e936Brian Paul       * The same adjustment is done in the next few functions.
248321177c8764638e1d4b3b29fed64adec62a14e936Brian Paul      */
248421177c8764638e1d4b3b29fed64adec62a14e936Brian Paul      level = nearest_mipmap_level(tObj, lambda[i]);
248521177c8764638e1d4b3b29fed64adec62a14e936Brian Paul      level = MAX2(level - 1, 0);
248621177c8764638e1d4b3b29fed64adec62a14e936Brian Paul
2487cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      sample_2d_nearest(ctx, samp, images[level], newCoord, rgba[i]);
24882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
24899282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul   if (is_depth_texture(tObj)) {
24909282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul      for (i = 0; i < n; i++) {
24919282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul         apply_depth_mode(tObj->DepthMode, rgba[i][0], rgba[i]);
24929282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul      }
24939282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul   }
24942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
24952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
24962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
24972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
2498f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_cube_linear_mipmap_nearest(struct gl_context *ctx,
2499cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                                  const struct gl_sampler_object *samp,
25002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                  const struct gl_texture_object *tObj,
25012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                  GLuint n, const GLfloat texcoord[][4],
2502de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                                  const GLfloat lambda[], GLfloat rgba[][4])
25032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
25042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
25052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   ASSERT(lambda != NULL);
25062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   for (i = 0; i < n; i++) {
25072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      const struct gl_texture_image **images;
25082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      GLfloat newCoord[4];
2509792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul      GLint level = nearest_mipmap_level(tObj, lambda[i]);
251021177c8764638e1d4b3b29fed64adec62a14e936Brian Paul      level = MAX2(level - 1, 0); /* see comment above */
25112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      images = choose_cube_face(tObj, texcoord[i], newCoord);
2512cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      sample_2d_linear(ctx, samp, images[level], newCoord, rgba[i]);
25132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
25149282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul   if (is_depth_texture(tObj)) {
25159282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul      for (i = 0; i < n; i++) {
25169282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul         apply_depth_mode(tObj->DepthMode, rgba[i][0], rgba[i]);
25179282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul      }
25189282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul   }
25192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
25202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
25212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
25222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
2523f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_cube_nearest_mipmap_linear(struct gl_context *ctx,
2524cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                                  const struct gl_sampler_object *samp,
25252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                  const struct gl_texture_object *tObj,
25262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                  GLuint n, const GLfloat texcoord[][4],
2527de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                                  const GLfloat lambda[], GLfloat rgba[][4])
25282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
25292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
25302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   ASSERT(lambda != NULL);
25312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   for (i = 0; i < n; i++) {
25322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      const struct gl_texture_image **images;
25332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      GLfloat newCoord[4];
2534792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul      GLint level = linear_mipmap_level(tObj, lambda[i]);
253521177c8764638e1d4b3b29fed64adec62a14e936Brian Paul      level = MAX2(level - 1, 0); /* see comment above */
25362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      images = choose_cube_face(tObj, texcoord[i], newCoord);
25372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (level >= tObj->_MaxLevel) {
2538cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_nearest(ctx, samp, images[tObj->_MaxLevel],
25392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                           newCoord, rgba[i]);
25402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
25412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      else {
2542de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul         GLfloat t0[4], t1[4];  /* texels */
25432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         const GLfloat f = FRAC(lambda[i]);
2544cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_nearest(ctx, samp, images[level  ], newCoord, t0);
2545cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_nearest(ctx, samp, images[level+1], newCoord, t1);
25462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         lerp_rgba(rgba[i], f, t0, t1);
25472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
25482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
25499282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul   if (is_depth_texture(tObj)) {
25509282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul      for (i = 0; i < n; i++) {
25519282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul         apply_depth_mode(tObj->DepthMode, rgba[i][0], rgba[i]);
25529282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul      }
25539282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul   }
25542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
25552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
25562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
25572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
2558f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_cube_linear_mipmap_linear(struct gl_context *ctx,
2559cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                                 const struct gl_sampler_object *samp,
25602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                 const struct gl_texture_object *tObj,
25612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                 GLuint n, const GLfloat texcoord[][4],
2562de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                                 const GLfloat lambda[], GLfloat rgba[][4])
25632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
25642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
25652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   ASSERT(lambda != NULL);
25662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   for (i = 0; i < n; i++) {
25672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      const struct gl_texture_image **images;
25682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      GLfloat newCoord[4];
2569792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul      GLint level = linear_mipmap_level(tObj, lambda[i]);
257021177c8764638e1d4b3b29fed64adec62a14e936Brian Paul      level = MAX2(level - 1, 0); /* see comment above */
25712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      images = choose_cube_face(tObj, texcoord[i], newCoord);
25722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (level >= tObj->_MaxLevel) {
2573cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_linear(ctx, samp, images[tObj->_MaxLevel],
25742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                          newCoord, rgba[i]);
25752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
25762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      else {
2577de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul         GLfloat t0[4], t1[4];
25782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         const GLfloat f = FRAC(lambda[i]);
2579cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_linear(ctx, samp, images[level  ], newCoord, t0);
2580cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_linear(ctx, samp, images[level+1], newCoord, t1);
25812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         lerp_rgba(rgba[i], f, t0, t1);
25822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
25832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
25849282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul   if (is_depth_texture(tObj)) {
25859282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul      for (i = 0; i < n; i++) {
25869282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul         apply_depth_mode(tObj->DepthMode, rgba[i][0], rgba[i]);
25879282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul      }
25889282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul   }
25892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
25902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
25912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
25926e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample cube texture, using lambda to choose between min/magnification */
25932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
2594f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_lambda_cube(struct gl_context *ctx,
2595cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                   const struct gl_sampler_object *samp,
25966e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian		   const struct gl_texture_object *tObj, GLuint n,
25976e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian		   const GLfloat texcoords[][4], const GLfloat lambda[],
2598de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul		   GLfloat rgba[][4])
25992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
26002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint minStart, minEnd;  /* texels with minification */
26012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint magStart, magEnd;  /* texels with magnification */
26022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
26032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   ASSERT(lambda != NULL);
2604cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   compute_min_mag_ranges(samp, n, lambda,
2605aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul                          &minStart, &minEnd, &magStart, &magEnd);
26062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
26072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   if (minStart < minEnd) {
26082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      /* do the minified texels */
26092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      const GLuint m = minEnd - minStart;
2610cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      switch (samp->MinFilter) {
26112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_NEAREST:
2612cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_nearest_cube(ctx, samp, tObj, m, texcoords + minStart,
26132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                             lambda + minStart, rgba + minStart);
26142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
26152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_LINEAR:
2616cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_linear_cube(ctx, samp, tObj, m, texcoords + minStart,
26172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                            lambda + minStart, rgba + minStart);
26182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
26192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_NEAREST_MIPMAP_NEAREST:
2620cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_cube_nearest_mipmap_nearest(ctx, samp, tObj, m,
26212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                            texcoords + minStart,
26222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                           lambda + minStart, rgba + minStart);
26232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
26242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_LINEAR_MIPMAP_NEAREST:
2625cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_cube_linear_mipmap_nearest(ctx, samp, tObj, m,
26262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                           texcoords + minStart,
26272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                           lambda + minStart, rgba + minStart);
26282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
26292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_NEAREST_MIPMAP_LINEAR:
2630cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_cube_nearest_mipmap_linear(ctx, samp, tObj, m,
26312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                           texcoords + minStart,
26322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                           lambda + minStart, rgba + minStart);
26332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
26342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_LINEAR_MIPMAP_LINEAR:
2635cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_cube_linear_mipmap_linear(ctx, samp, tObj, m,
26362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                          texcoords + minStart,
26372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                                          lambda + minStart, rgba + minStart);
26382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
26392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      default:
26402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         _mesa_problem(ctx, "Bad min filter in sample_lambda_cube");
264103bbcd447cbaa28b52465ae1045013f1aff420c2Chad Versace         break;
26422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
26432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
26442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
26452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   if (magStart < magEnd) {
26462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      /* do the magnified texels */
26472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      const GLuint m = magEnd - magStart;
2648cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      switch (samp->MagFilter) {
26492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_NEAREST:
2650cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_nearest_cube(ctx, samp, tObj, m, texcoords + magStart,
26512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                             lambda + magStart, rgba + magStart);
26522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
26532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_LINEAR:
2654cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_linear_cube(ctx, samp, tObj, m, texcoords + magStart,
26552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                            lambda + magStart, rgba + magStart);
26562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         break;
26572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      default:
26582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         _mesa_problem(ctx, "Bad mag filter in sample_lambda_cube");
265903bbcd447cbaa28b52465ae1045013f1aff420c2Chad Versace         break;
26602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
26612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
26622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
26632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
26642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
26652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/
26662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/*               Texture Rectangle Sampling Functions                 */
26672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/
26682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
2669fde15a2bae2f2ca552763705f12d53e4606feabfBrian
26702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
2671f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_nearest_rect(struct gl_context *ctx,
2672cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                    const struct gl_sampler_object *samp,
26732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul		    const struct gl_texture_object *tObj, GLuint n,
26742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                    const GLfloat texcoords[][4], const GLfloat lambda[],
2675de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                    GLfloat rgba[][4])
26762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
26772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const struct gl_texture_image *img = tObj->Image[0][0];
2678a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
26796e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian   const GLint width = img->Width;
26806e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian   const GLint height = img->Height;
26812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
26822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
26832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   (void) ctx;
26842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   (void) lambda;
26852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
2686cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   ASSERT(samp->WrapS == GL_CLAMP ||
2687cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen          samp->WrapS == GL_CLAMP_TO_EDGE ||
2688cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen          samp->WrapS == GL_CLAMP_TO_BORDER);
2689cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   ASSERT(samp->WrapT == GL_CLAMP ||
2690cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen          samp->WrapT == GL_CLAMP_TO_EDGE ||
2691cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen          samp->WrapT == GL_CLAMP_TO_BORDER);
26922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
26932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   for (i = 0; i < n; i++) {
26942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      GLint row, col;
2695cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      col = clamp_rect_coord_nearest(samp->WrapS, texcoords[i][0], width);
2696cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      row = clamp_rect_coord_nearest(samp->WrapT, texcoords[i][1], height);
26976e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian      if (col < 0 || col >= width || row < 0 || row >= height)
2698cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         get_border_color(samp, img, rgba[i]);
26992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      else
27005ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul         swImg->FetchTexel(swImg, col, row, 0, rgba[i]);
27012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
27022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
27032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
27042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
27052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
2706f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_linear_rect(struct gl_context *ctx,
2707cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                   const struct gl_sampler_object *samp,
27082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul		   const struct gl_texture_object *tObj, GLuint n,
27092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                   const GLfloat texcoords[][4],
2710de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul		   const GLfloat lambda[], GLfloat rgba[][4])
27112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
27122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   const struct gl_texture_image *img = tObj->Image[0][0];
2713a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
27146e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian   const GLint width = img->Width;
27156e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian   const GLint height = img->Height;
27162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
27172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
27182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   (void) ctx;
27192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   (void) lambda;
27202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
2721cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   ASSERT(samp->WrapS == GL_CLAMP ||
2722cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen          samp->WrapS == GL_CLAMP_TO_EDGE ||
2723cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen          samp->WrapS == GL_CLAMP_TO_BORDER);
2724cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   ASSERT(samp->WrapT == GL_CLAMP ||
2725cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen          samp->WrapT == GL_CLAMP_TO_EDGE ||
2726cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen          samp->WrapT == GL_CLAMP_TO_BORDER);
27272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
27282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   for (i = 0; i < n; i++) {
27292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      GLint i0, j0, i1, j1;
2730de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul      GLfloat t00[4], t01[4], t10[4], t11[4];
27312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      GLfloat a, b;
27320f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul      GLbitfield useBorderColor = 0x0;
27332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
2734cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      clamp_rect_coord_linear(samp->WrapS, texcoords[i][0], width,
2735249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian                              &i0, &i1, &a);
2736cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      clamp_rect_coord_linear(samp->WrapT, texcoords[i][1], height,
2737249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian                              &j0, &j1, &b);
27382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
27392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      /* compute integer rows/columns */
27406e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian      if (i0 < 0 || i0 >= width)   useBorderColor |= I0BIT;
27416e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian      if (i1 < 0 || i1 >= width)   useBorderColor |= I1BIT;
27426e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian      if (j0 < 0 || j0 >= height)  useBorderColor |= J0BIT;
27436e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian      if (j1 < 0 || j1 >= height)  useBorderColor |= J1BIT;
27442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
27452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      /* get four texel samples */
27462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (useBorderColor & (I0BIT | J0BIT))
2747cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         get_border_color(samp, img, t00);
27482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      else
27495ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul         swImg->FetchTexel(swImg, i0, j0, 0, t00);
27502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
27512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (useBorderColor & (I1BIT | J0BIT))
2752cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         get_border_color(samp, img, t10);
27532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      else
27545ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul         swImg->FetchTexel(swImg, i1, j0, 0, t10);
27552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
27562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (useBorderColor & (I0BIT | J1BIT))
2757cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         get_border_color(samp, img, t01);
27582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      else
27595ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul         swImg->FetchTexel(swImg, i0, j1, 0, t01);
27602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
27612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      if (useBorderColor & (I1BIT | J1BIT))
2762cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         get_border_color(samp, img, t11);
27632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      else
27645ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul         swImg->FetchTexel(swImg, i1, j1, 0, t11);
27652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
27662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      lerp_rgba_2d(rgba[i], a, b, t00, t10, t01, t11);
27672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
27682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
27692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
27702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
27716e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample Rect texture, using lambda to choose between min/magnification */
27722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
2773f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_lambda_rect(struct gl_context *ctx,
2774cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                   const struct gl_sampler_object *samp,
27756e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian		   const struct gl_texture_object *tObj, GLuint n,
27766e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian		   const GLfloat texcoords[][4], const GLfloat lambda[],
2777de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul		   GLfloat rgba[][4])
27782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
27792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint minStart, minEnd, magStart, magEnd;
27802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
27812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   /* We only need lambda to decide between minification and magnification.
27822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul    * There is no mipmapping with rectangular textures.
27832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul    */
2784cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   compute_min_mag_ranges(samp, n, lambda,
2785aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul                          &minStart, &minEnd, &magStart, &magEnd);
27862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
27872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   if (minStart < minEnd) {
2788cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      if (samp->MinFilter == GL_NEAREST) {
2789cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_nearest_rect(ctx, samp, tObj, minEnd - minStart,
27906e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                             texcoords + minStart, NULL, rgba + minStart);
27912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
27922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      else {
2793cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_linear_rect(ctx, samp, tObj, minEnd - minStart,
27946e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                            texcoords + minStart, NULL, rgba + minStart);
27952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
27962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
27972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   if (magStart < magEnd) {
2798cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      if (samp->MagFilter == GL_NEAREST) {
2799cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_nearest_rect(ctx, samp, tObj, magEnd - magStart,
28006e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                             texcoords + magStart, NULL, rgba + magStart);
28012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
28022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      else {
2803cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_linear_rect(ctx, samp, tObj, magEnd - magStart,
28046e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                            texcoords + magStart, NULL, rgba + magStart);
28052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
28062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
28072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
28082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
28092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
2810bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick/**********************************************************************/
2811bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick/*                2D Texture Array Sampling Functions                 */
2812bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick/**********************************************************************/
2813bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
28146e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/**
2815bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter.
2816bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick */
2817bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void
2818f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_array_nearest(struct gl_context *ctx,
2819cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                        const struct gl_sampler_object *samp,
2820bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                        const struct gl_texture_image *img,
2821bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                        const GLfloat texcoord[4],
2822de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                        GLfloat rgba[4])
2823bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{
2824a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
2825bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   const GLint width = img->Width2;     /* without border, power of two */
2826bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   const GLint height = img->Height2;   /* without border, power of two */
2827bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   const GLint depth = img->Depth;
2828bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLint i, j;
2829bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLint array;
2830bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   (void) ctx;
2831bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
2832cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   i = nearest_texel_location(samp->WrapS, img, width, texcoord[0]);
2833cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   j = nearest_texel_location(samp->WrapT, img, height, texcoord[1]);
283458ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul   array = tex_array_slice(texcoord[2], depth);
2835bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
2836bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   if (i < 0 || i >= (GLint) img->Width ||
2837bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick       j < 0 || j >= (GLint) img->Height ||
2838bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick       array < 0 || array >= (GLint) img->Depth) {
2839bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      /* Need this test for GL_CLAMP_TO_BORDER mode */
2840cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      get_border_color(samp, img, rgba);
2841bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   }
2842bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   else {
28435ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul      swImg->FetchTexel(swImg, i, j, array, rgba);
2844bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   }
2845bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick}
2846bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
2847bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
28486e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/**
2849bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter.
2850bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick */
2851bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void
2852f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_array_linear(struct gl_context *ctx,
2853cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                       const struct gl_sampler_object *samp,
2854bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                       const struct gl_texture_image *img,
2855bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                       const GLfloat texcoord[4],
2856de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                       GLfloat rgba[4])
2857bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{
2858a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
2859bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   const GLint width = img->Width2;
2860bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   const GLint height = img->Height2;
2861bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   const GLint depth = img->Depth;
2862bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLint i0, j0, i1, j1;
2863bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLint array;
2864bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLbitfield useBorderColor = 0x0;
2865bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLfloat a, b;
2866de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul   GLfloat t00[4], t01[4], t10[4], t11[4];
2867bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
2868cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   linear_texel_locations(samp->WrapS, img, width,  texcoord[0], &i0, &i1, &a);
2869cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   linear_texel_locations(samp->WrapT, img, height, texcoord[1], &j0, &j1, &b);
287058ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul   array = tex_array_slice(texcoord[2], depth);
2871bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
2872bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   if (array < 0 || array >= depth) {
2873cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      COPY_4V(rgba, samp->BorderColor.f);
2874bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   }
2875bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   else {
2876bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      if (img->Border) {
2877bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick	 i0 += img->Border;
2878bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick	 i1 += img->Border;
2879bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick	 j0 += img->Border;
2880bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick	 j1 += img->Border;
2881bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      }
2882bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      else {
2883bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick	 /* check if sampling texture border color */
2884bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick	 if (i0 < 0 || i0 >= width)   useBorderColor |= I0BIT;
2885bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick	 if (i1 < 0 || i1 >= width)   useBorderColor |= I1BIT;
2886bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick	 if (j0 < 0 || j0 >= height)  useBorderColor |= J0BIT;
2887bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick	 if (j1 < 0 || j1 >= height)  useBorderColor |= J1BIT;
2888bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      }
2889bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
2890bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      /* Fetch texels */
2891bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      if (useBorderColor & (I0BIT | J0BIT)) {
2892cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         get_border_color(samp, img, t00);
2893bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      }
2894bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      else {
28955ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul	 swImg->FetchTexel(swImg, i0, j0, array, t00);
2896bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      }
2897bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      if (useBorderColor & (I1BIT | J0BIT)) {
2898cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         get_border_color(samp, img, t10);
2899bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      }
2900bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      else {
29015ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul	 swImg->FetchTexel(swImg, i1, j0, array, t10);
2902bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      }
2903bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      if (useBorderColor & (I0BIT | J1BIT)) {
2904cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         get_border_color(samp, img, t01);
2905bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      }
2906bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      else {
29075ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul	 swImg->FetchTexel(swImg, i0, j1, array, t01);
2908bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      }
2909bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      if (useBorderColor & (I1BIT | J1BIT)) {
2910cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         get_border_color(samp, img, t11);
2911bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      }
2912bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      else {
29135ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul	 swImg->FetchTexel(swImg, i1, j1, array, t11);
2914bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      }
2915bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
2916bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      /* trilinear interpolation of samples */
2917bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      lerp_rgba_2d(rgba, a, b, t00, t10, t01, t11);
2918bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   }
2919bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick}
2920bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
2921bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
2922bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void
2923f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_array_nearest_mipmap_nearest(struct gl_context *ctx,
2924cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                                       const struct gl_sampler_object *samp,
2925bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                       const struct gl_texture_object *tObj,
2926bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                       GLuint n, const GLfloat texcoord[][4],
2927de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                                       const GLfloat lambda[], GLfloat rgba[][4])
2928bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{
2929bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLuint i;
2930bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   for (i = 0; i < n; i++) {
2931bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      GLint level = nearest_mipmap_level(tObj, lambda[i]);
2932cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      sample_2d_array_nearest(ctx, samp, tObj->Image[0][level], texcoord[i],
2933bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                              rgba[i]);
2934bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   }
2935bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick}
2936bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
2937bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
2938bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void
2939f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_array_linear_mipmap_nearest(struct gl_context *ctx,
2940cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                                      const struct gl_sampler_object *samp,
2941bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                      const struct gl_texture_object *tObj,
2942bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                      GLuint n, const GLfloat texcoord[][4],
2943de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                                      const GLfloat lambda[], GLfloat rgba[][4])
2944bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{
2945bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLuint i;
2946bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   ASSERT(lambda != NULL);
2947bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   for (i = 0; i < n; i++) {
2948bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      GLint level = nearest_mipmap_level(tObj, lambda[i]);
2949cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      sample_2d_array_linear(ctx, samp, tObj->Image[0][level],
2950bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                             texcoord[i], rgba[i]);
2951bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   }
2952bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick}
2953bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
2954bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
2955bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void
2956f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_array_nearest_mipmap_linear(struct gl_context *ctx,
2957cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                                      const struct gl_sampler_object *samp,
2958bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                      const struct gl_texture_object *tObj,
2959bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                      GLuint n, const GLfloat texcoord[][4],
2960de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                                      const GLfloat lambda[], GLfloat rgba[][4])
2961bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{
2962bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLuint i;
2963bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   ASSERT(lambda != NULL);
2964bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   for (i = 0; i < n; i++) {
2965bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      GLint level = linear_mipmap_level(tObj, lambda[i]);
2966bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      if (level >= tObj->_MaxLevel) {
2967cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_array_nearest(ctx, samp, tObj->Image[0][tObj->_MaxLevel],
2968bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                 texcoord[i], rgba[i]);
2969bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      }
2970bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      else {
2971de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul         GLfloat t0[4], t1[4];  /* texels */
2972bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         const GLfloat f = FRAC(lambda[i]);
2973cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_array_nearest(ctx, samp, tObj->Image[0][level  ],
29746e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                                 texcoord[i], t0);
2975cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_array_nearest(ctx, samp, tObj->Image[0][level+1],
29766e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                                 texcoord[i], t1);
2977bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         lerp_rgba(rgba[i], f, t0, t1);
2978bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      }
2979bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   }
2980bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick}
2981bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
2982bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
2983bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void
2984f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_array_linear_mipmap_linear(struct gl_context *ctx,
2985cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                                     const struct gl_sampler_object *samp,
29866e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                                     const struct gl_texture_object *tObj,
29876e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                                     GLuint n, const GLfloat texcoord[][4],
2988de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                                     const GLfloat lambda[], GLfloat rgba[][4])
2989bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{
2990bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLuint i;
2991bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   ASSERT(lambda != NULL);
2992bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   for (i = 0; i < n; i++) {
2993bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      GLint level = linear_mipmap_level(tObj, lambda[i]);
2994bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      if (level >= tObj->_MaxLevel) {
2995cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_array_linear(ctx, samp, tObj->Image[0][tObj->_MaxLevel],
2996bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                          texcoord[i], rgba[i]);
2997bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      }
2998bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      else {
2999de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul         GLfloat t0[4], t1[4];  /* texels */
3000bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         const GLfloat f = FRAC(lambda[i]);
3001cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_array_linear(ctx, samp, tObj->Image[0][level  ],
30026e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                                texcoord[i], t0);
3003cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_array_linear(ctx, samp, tObj->Image[0][level+1],
30046e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                                texcoord[i], t1);
3005bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         lerp_rgba(rgba[i], f, t0, t1);
3006bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      }
3007bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   }
3008bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick}
3009bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3010bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
30116e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 2D Array texture, nearest filtering for both min/magnification */
3012bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void
3013f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_nearest_2d_array(struct gl_context *ctx,
3014cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                        const struct gl_sampler_object *samp,
30156e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                        const struct gl_texture_object *tObj, GLuint n,
30166e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                        const GLfloat texcoords[][4], const GLfloat lambda[],
3017de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                        GLfloat rgba[][4])
3018bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{
3019bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLuint i;
3020bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
3021bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   (void) lambda;
30226e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian   for (i = 0; i < n; i++) {
3023cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      sample_2d_array_nearest(ctx, samp, image, texcoords[i], rgba[i]);
3024bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   }
3025bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick}
3026bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3027bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3028bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
30296e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 2D Array texture, linear filtering for both min/magnification */
3030bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void
3031f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_linear_2d_array(struct gl_context *ctx,
3032cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                       const struct gl_sampler_object *samp,
3033bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                       const struct gl_texture_object *tObj, GLuint n,
3034bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                       const GLfloat texcoords[][4],
3035de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                       const GLfloat lambda[], GLfloat rgba[][4])
3036bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{
3037bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLuint i;
3038bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
3039bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   (void) lambda;
30406e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian   for (i = 0; i < n; i++) {
3041cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      sample_2d_array_linear(ctx, samp, image, texcoords[i], rgba[i]);
3042bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   }
3043bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick}
3044bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3045bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
30466e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 2D Array texture, using lambda to choose between min/magnification */
3047bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void
3048f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_lambda_2d_array(struct gl_context *ctx,
3049cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                       const struct gl_sampler_object *samp,
3050bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                       const struct gl_texture_object *tObj, GLuint n,
3051bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                       const GLfloat texcoords[][4], const GLfloat lambda[],
3052de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                       GLfloat rgba[][4])
3053bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{
3054bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLuint minStart, minEnd;  /* texels with minification */
3055bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLuint magStart, magEnd;  /* texels with magnification */
3056bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLuint i;
3057bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3058bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   ASSERT(lambda != NULL);
3059cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   compute_min_mag_ranges(samp, n, lambda,
3060bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                          &minStart, &minEnd, &magStart, &magEnd);
3061bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3062bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   if (minStart < minEnd) {
3063bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      /* do the minified texels */
3064bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      GLuint m = minEnd - minStart;
3065cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      switch (samp->MinFilter) {
3066bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      case GL_NEAREST:
3067bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         for (i = minStart; i < minEnd; i++)
3068cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            sample_2d_array_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel],
3069bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                    texcoords[i], rgba[i]);
3070bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         break;
3071bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      case GL_LINEAR:
3072bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         for (i = minStart; i < minEnd; i++)
3073cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            sample_2d_array_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel],
3074bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                   texcoords[i], rgba[i]);
3075bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         break;
3076bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      case GL_NEAREST_MIPMAP_NEAREST:
3077cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_array_nearest_mipmap_nearest(ctx, samp, tObj, m,
30786e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                                                texcoords + minStart,
30796e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                                                lambda + minStart,
30806e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                                                rgba + minStart);
3081bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         break;
3082bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      case GL_LINEAR_MIPMAP_NEAREST:
3083cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_array_linear_mipmap_nearest(ctx, samp, tObj, m,
3084bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                               texcoords + minStart,
3085bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                               lambda + minStart,
3086bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                               rgba + minStart);
3087bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         break;
3088bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      case GL_NEAREST_MIPMAP_LINEAR:
3089cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_array_nearest_mipmap_linear(ctx, samp, tObj, m,
30906e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                                               texcoords + minStart,
30916e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                                               lambda + minStart,
30926e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                                               rgba + minStart);
3093bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         break;
3094bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      case GL_LINEAR_MIPMAP_LINEAR:
3095cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_2d_array_linear_mipmap_linear(ctx, samp, tObj, m,
3096bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                              texcoords + minStart,
3097bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                              lambda + minStart,
3098bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                              rgba + minStart);
3099bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         break;
3100bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      default:
3101bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         _mesa_problem(ctx, "Bad min filter in sample_2d_array_texture");
3102bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         return;
3103bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      }
3104bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   }
3105bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3106bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   if (magStart < magEnd) {
3107bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      /* do the magnified texels */
3108cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      switch (samp->MagFilter) {
3109bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      case GL_NEAREST:
3110bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         for (i = magStart; i < magEnd; i++)
3111cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            sample_2d_array_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel],
3112bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                              texcoords[i], rgba[i]);
3113bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         break;
3114bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      case GL_LINEAR:
3115bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         for (i = magStart; i < magEnd; i++)
3116cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            sample_2d_array_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel],
3117bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                   texcoords[i], rgba[i]);
3118bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         break;
3119bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      default:
3120bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         _mesa_problem(ctx, "Bad mag filter in sample_2d_array_texture");
3121bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         return;
3122bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      }
3123bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   }
3124bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick}
3125bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3126bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3127bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3128bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3129bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick/**********************************************************************/
3130bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick/*                1D Texture Array Sampling Functions                 */
3131bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick/**********************************************************************/
3132bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
31336e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/**
3134bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter.
3135bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick */
3136bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void
3137f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_array_nearest(struct gl_context *ctx,
3138cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                        const struct gl_sampler_object *samp,
3139bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                        const struct gl_texture_image *img,
3140bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                        const GLfloat texcoord[4],
3141de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                        GLfloat rgba[4])
3142bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{
3143a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
3144bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   const GLint width = img->Width2;     /* without border, power of two */
3145bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   const GLint height = img->Height;
3146bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLint i;
3147bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLint array;
3148bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   (void) ctx;
3149bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3150cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   i = nearest_texel_location(samp->WrapS, img, width, texcoord[0]);
315158ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul   array = tex_array_slice(texcoord[1], height);
3152bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3153bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   if (i < 0 || i >= (GLint) img->Width ||
3154bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick       array < 0 || array >= (GLint) img->Height) {
3155bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      /* Need this test for GL_CLAMP_TO_BORDER mode */
3156cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      get_border_color(samp, img, rgba);
3157bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   }
3158bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   else {
31595ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul      swImg->FetchTexel(swImg, i, array, 0, rgba);
3160bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   }
3161bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick}
3162bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3163bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
31646e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/**
3165bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter.
3166bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick */
3167bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void
3168f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_array_linear(struct gl_context *ctx,
3169cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                       const struct gl_sampler_object *samp,
3170bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                       const struct gl_texture_image *img,
3171bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                       const GLfloat texcoord[4],
3172de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                       GLfloat rgba[4])
3173bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{
3174a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
3175bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   const GLint width = img->Width2;
3176bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   const GLint height = img->Height;
3177bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLint i0, i1;
3178bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLint array;
3179bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLbitfield useBorderColor = 0x0;
3180bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLfloat a;
3181de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul   GLfloat t0[4], t1[4];
3182bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3183cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   linear_texel_locations(samp->WrapS, img, width, texcoord[0], &i0, &i1, &a);
318458ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul   array = tex_array_slice(texcoord[1], height);
3185bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3186bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   if (img->Border) {
3187bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      i0 += img->Border;
3188bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      i1 += img->Border;
3189bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   }
3190bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   else {
3191bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      /* check if sampling texture border color */
3192bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      if (i0 < 0 || i0 >= width)   useBorderColor |= I0BIT;
3193bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      if (i1 < 0 || i1 >= width)   useBorderColor |= I1BIT;
3194bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   }
3195bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3196bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   if (array < 0 || array >= height)   useBorderColor |= K0BIT;
3197bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3198bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   /* Fetch texels */
3199bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   if (useBorderColor & (I0BIT | K0BIT)) {
3200cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      get_border_color(samp, img, t0);
3201bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   }
3202bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   else {
32035ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul      swImg->FetchTexel(swImg, i0, array, 0, t0);
3204bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   }
3205bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   if (useBorderColor & (I1BIT | K0BIT)) {
3206cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      get_border_color(samp, img, t1);
3207bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   }
3208bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   else {
32095ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul      swImg->FetchTexel(swImg, i1, array, 0, t1);
3210bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   }
3211bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3212bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   /* bilinear interpolation of samples */
3213bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   lerp_rgba(rgba, a, t0, t1);
3214bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick}
3215bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3216bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3217bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void
3218f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_array_nearest_mipmap_nearest(struct gl_context *ctx,
3219cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                                       const struct gl_sampler_object *samp,
3220bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                       const struct gl_texture_object *tObj,
3221bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                       GLuint n, const GLfloat texcoord[][4],
3222de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                                       const GLfloat lambda[], GLfloat rgba[][4])
3223bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{
3224bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLuint i;
3225bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   for (i = 0; i < n; i++) {
3226bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      GLint level = nearest_mipmap_level(tObj, lambda[i]);
3227cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      sample_1d_array_nearest(ctx, samp, tObj->Image[0][level], texcoord[i],
3228bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                              rgba[i]);
3229bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   }
3230bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick}
3231bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3232bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3233bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void
3234f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_array_linear_mipmap_nearest(struct gl_context *ctx,
3235cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                                      const struct gl_sampler_object *samp,
3236bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                      const struct gl_texture_object *tObj,
3237bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                      GLuint n, const GLfloat texcoord[][4],
3238de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                                      const GLfloat lambda[], GLfloat rgba[][4])
3239bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{
3240bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLuint i;
3241bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   ASSERT(lambda != NULL);
3242bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   for (i = 0; i < n; i++) {
3243bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      GLint level = nearest_mipmap_level(tObj, lambda[i]);
3244cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      sample_1d_array_linear(ctx, samp, tObj->Image[0][level],
3245bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                             texcoord[i], rgba[i]);
3246bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   }
3247bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick}
3248bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3249bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3250bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void
3251f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_array_nearest_mipmap_linear(struct gl_context *ctx,
3252cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                                      const struct gl_sampler_object *samp,
3253bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                      const struct gl_texture_object *tObj,
3254bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                      GLuint n, const GLfloat texcoord[][4],
3255de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                                      const GLfloat lambda[], GLfloat rgba[][4])
3256bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{
3257bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLuint i;
3258bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   ASSERT(lambda != NULL);
3259bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   for (i = 0; i < n; i++) {
3260bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      GLint level = linear_mipmap_level(tObj, lambda[i]);
3261bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      if (level >= tObj->_MaxLevel) {
3262cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_1d_array_nearest(ctx, samp, tObj->Image[0][tObj->_MaxLevel],
3263bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                 texcoord[i], rgba[i]);
3264bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      }
3265bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      else {
3266de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul         GLfloat t0[4], t1[4];  /* texels */
3267bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         const GLfloat f = FRAC(lambda[i]);
3268cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_1d_array_nearest(ctx, samp, tObj->Image[0][level  ], texcoord[i], t0);
3269cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_1d_array_nearest(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1);
3270bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         lerp_rgba(rgba[i], f, t0, t1);
3271bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      }
3272bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   }
3273bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick}
3274bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3275bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3276bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void
3277f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_array_linear_mipmap_linear(struct gl_context *ctx,
3278cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                                     const struct gl_sampler_object *samp,
32796e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                                     const struct gl_texture_object *tObj,
32806e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                                     GLuint n, const GLfloat texcoord[][4],
3281de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                                     const GLfloat lambda[], GLfloat rgba[][4])
3282bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{
3283bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLuint i;
3284bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   ASSERT(lambda != NULL);
3285bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   for (i = 0; i < n; i++) {
3286bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      GLint level = linear_mipmap_level(tObj, lambda[i]);
3287bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      if (level >= tObj->_MaxLevel) {
3288cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_1d_array_linear(ctx, samp, tObj->Image[0][tObj->_MaxLevel],
3289bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                          texcoord[i], rgba[i]);
3290bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      }
3291bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      else {
3292de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul         GLfloat t0[4], t1[4];  /* texels */
3293bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         const GLfloat f = FRAC(lambda[i]);
3294cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_1d_array_linear(ctx, samp, tObj->Image[0][level  ], texcoord[i], t0);
3295cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_1d_array_linear(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1);
3296bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         lerp_rgba(rgba[i], f, t0, t1);
3297bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      }
3298bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   }
3299bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick}
3300bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3301bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
33026e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 1D Array texture, nearest filtering for both min/magnification */
3303bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void
3304f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_nearest_1d_array(struct gl_context *ctx,
3305cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                        const struct gl_sampler_object *samp,
33066e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                        const struct gl_texture_object *tObj, GLuint n,
33076e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian                        const GLfloat texcoords[][4], const GLfloat lambda[],
3308de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                        GLfloat rgba[][4])
3309bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{
3310bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLuint i;
3311bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
3312bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   (void) lambda;
33136e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian   for (i = 0; i < n; i++) {
3314cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      sample_1d_array_nearest(ctx, samp, image, texcoords[i], rgba[i]);
3315bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   }
3316bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick}
3317bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3318bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
33196e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 1D Array texture, linear filtering for both min/magnification */
3320bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void
3321f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_linear_1d_array(struct gl_context *ctx,
3322cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                       const struct gl_sampler_object *samp,
3323bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                       const struct gl_texture_object *tObj, GLuint n,
3324bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                       const GLfloat texcoords[][4],
3325de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                       const GLfloat lambda[], GLfloat rgba[][4])
3326bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{
3327bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLuint i;
3328bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
3329bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   (void) lambda;
33306e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian   for (i = 0; i < n; i++) {
3331cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      sample_1d_array_linear(ctx, samp, image, texcoords[i], rgba[i]);
3332bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   }
3333bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick}
3334bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3335bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
33366e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 1D Array texture, using lambda to choose between min/magnification */
3337bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void
3338f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_lambda_1d_array(struct gl_context *ctx,
3339cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                       const struct gl_sampler_object *samp,
3340bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                       const struct gl_texture_object *tObj, GLuint n,
3341bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                       const GLfloat texcoords[][4], const GLfloat lambda[],
3342de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                       GLfloat rgba[][4])
3343bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{
3344bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLuint minStart, minEnd;  /* texels with minification */
3345bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLuint magStart, magEnd;  /* texels with magnification */
3346bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   GLuint i;
3347bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3348bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   ASSERT(lambda != NULL);
3349cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   compute_min_mag_ranges(samp, n, lambda,
3350bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                          &minStart, &minEnd, &magStart, &magEnd);
3351bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3352bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   if (minStart < minEnd) {
3353bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      /* do the minified texels */
3354bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      GLuint m = minEnd - minStart;
3355cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      switch (samp->MinFilter) {
3356bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      case GL_NEAREST:
3357bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         for (i = minStart; i < minEnd; i++)
3358cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            sample_1d_array_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel],
3359bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                    texcoords[i], rgba[i]);
3360bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         break;
3361bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      case GL_LINEAR:
3362bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         for (i = minStart; i < minEnd; i++)
3363cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            sample_1d_array_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel],
3364bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                   texcoords[i], rgba[i]);
3365bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         break;
3366bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      case GL_NEAREST_MIPMAP_NEAREST:
3367cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_1d_array_nearest_mipmap_nearest(ctx, samp, tObj, m, texcoords + minStart,
3368bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                                lambda + minStart, rgba + minStart);
3369bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         break;
3370bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      case GL_LINEAR_MIPMAP_NEAREST:
3371cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_1d_array_linear_mipmap_nearest(ctx, samp, tObj, m,
3372bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                               texcoords + minStart,
3373bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                               lambda + minStart,
3374bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                               rgba + minStart);
3375bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         break;
3376bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      case GL_NEAREST_MIPMAP_LINEAR:
3377cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_1d_array_nearest_mipmap_linear(ctx, samp, tObj, m, texcoords + minStart,
3378bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                               lambda + minStart, rgba + minStart);
3379bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         break;
3380bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      case GL_LINEAR_MIPMAP_LINEAR:
3381cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         sample_1d_array_linear_mipmap_linear(ctx, samp, tObj, m,
3382bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                              texcoords + minStart,
3383bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                              lambda + minStart,
3384bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                              rgba + minStart);
3385bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         break;
3386bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      default:
3387bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         _mesa_problem(ctx, "Bad min filter in sample_1d_array_texture");
3388bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         return;
3389bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      }
3390bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   }
3391bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3392bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   if (magStart < magEnd) {
3393bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      /* do the magnified texels */
3394cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      switch (samp->MagFilter) {
3395bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      case GL_NEAREST:
3396bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         for (i = magStart; i < magEnd; i++)
3397cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            sample_1d_array_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel],
3398bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                              texcoords[i], rgba[i]);
3399bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         break;
3400bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      case GL_LINEAR:
3401bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         for (i = magStart; i < magEnd; i++)
3402cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            sample_1d_array_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel],
3403bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick                                   texcoords[i], rgba[i]);
3404bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         break;
3405bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      default:
3406bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         _mesa_problem(ctx, "Bad mag filter in sample_1d_array_texture");
3407bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         return;
3408bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      }
3409bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   }
3410bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick}
3411bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3412bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
34136e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/**
3414707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick * Compare texcoord against depth sample.  Return 1.0 or 0.0 value.
3415a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul */
34169520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLfloat
3417707f0679157f83ac45127e41647b96ed924d45c9Ian Romanickshadow_compare(GLenum function, GLfloat coord, GLfloat depthSample)
3418a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul{
3419a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   switch (function) {
3420a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   case GL_LEQUAL:
3421707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick      return (coord <= depthSample) ? 1.0F : 0.0F;
3422a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   case GL_GEQUAL:
3423707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick      return (coord >= depthSample) ? 1.0F : 0.0F;
3424a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   case GL_LESS:
3425707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick      return (coord < depthSample) ? 1.0F : 0.0F;
3426a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   case GL_GREATER:
3427707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick      return (coord > depthSample) ? 1.0F : 0.0F;
3428a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   case GL_EQUAL:
3429707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick      return (coord == depthSample) ? 1.0F : 0.0F;
3430a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   case GL_NOTEQUAL:
3431707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick      return (coord != depthSample) ? 1.0F : 0.0F;
3432a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   case GL_ALWAYS:
3433a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      return 1.0F;
3434a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   case GL_NEVER:
3435707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick      return 0.0F;
3436a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   case GL_NONE:
3437a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      return depthSample;
3438a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   default:
3439a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      _mesa_problem(NULL, "Bad compare func in shadow_compare");
3440707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick      return 0.0F;
3441a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   }
3442a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul}
3443a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul
3444a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul
3445a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul/**
3446a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul * Compare texcoord against four depth samples.
3447a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul */
34489520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLfloat
3449a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paulshadow_compare4(GLenum function, GLfloat coord,
3450a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul                GLfloat depth00, GLfloat depth01,
3451a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul                GLfloat depth10, GLfloat depth11,
3452707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick                GLfloat wi, GLfloat wj)
3453a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul{
3454707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick   const GLfloat d = 0.25F;
3455a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   GLfloat luminance = 1.0F;
3456a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul
3457a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   switch (function) {
3458a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   case GL_LEQUAL:
34594a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul      if (coord > depth00)  luminance -= d;
34604a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul      if (coord > depth01)  luminance -= d;
34614a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul      if (coord > depth10)  luminance -= d;
34624a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul      if (coord > depth11)  luminance -= d;
3463a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      return luminance;
3464d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor   case GL_GEQUAL:
34654a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul      if (coord < depth00)  luminance -= d;
34664a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul      if (coord < depth01)  luminance -= d;
34674a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul      if (coord < depth10)  luminance -= d;
34684a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul      if (coord < depth11)  luminance -= d;
3469a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      return luminance;
3470d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor   case GL_LESS:
34714a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul      if (coord >= depth00)  luminance -= d;
34724a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul      if (coord >= depth01)  luminance -= d;
34734a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul      if (coord >= depth10)  luminance -= d;
34744a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul      if (coord >= depth11)  luminance -= d;
3475a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      return luminance;
3476d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor   case GL_GREATER:
34774a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul      if (coord <= depth00)  luminance -= d;
34784a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul      if (coord <= depth01)  luminance -= d;
34794a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul      if (coord <= depth10)  luminance -= d;
34804a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul      if (coord <= depth11)  luminance -= d;
3481d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor      return luminance;
3482d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor   case GL_EQUAL:
34834a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul      if (coord != depth00)  luminance -= d;
34844a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul      if (coord != depth01)  luminance -= d;
34854a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul      if (coord != depth10)  luminance -= d;
34864a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul      if (coord != depth11)  luminance -= d;
3487a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      return luminance;
3488d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor   case GL_NOTEQUAL:
34894a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul      if (coord == depth00)  luminance -= d;
34904a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul      if (coord == depth01)  luminance -= d;
34914a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul      if (coord == depth10)  luminance -= d;
34924a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul      if (coord == depth11)  luminance -= d;
3493d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor      return luminance;
3494a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   case GL_ALWAYS:
3495d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor      return 1.0F;
3496a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   case GL_NEVER:
3497707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick      return 0.0F;
3498a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   case GL_NONE:
3499a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      /* ordinary bilinear filtering */
3500a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul      return lerp_2d(wi, wj, depth00, depth10, depth01, depth11);
3501a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   default:
3502d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor      _mesa_problem(NULL, "Bad compare func in sample_compare4");
3503707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick      return 0.0F;
3504a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul   }
3505a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul}
3506a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul
3507a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul
3508a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul/**
35092b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul * Choose the mipmap level to use when sampling from a depth texture.
35102b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul */
35112b5de09b3ea8754fb004d4f216bca29303f99490Brian Paulstatic int
3512cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminenchoose_depth_texture_level(const struct gl_sampler_object *samp,
3513cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                           const struct gl_texture_object *tObj, GLfloat lambda)
35142b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul{
35152b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul   GLint level;
35162b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul
3517cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   if (samp->MinFilter == GL_NEAREST || samp->MinFilter == GL_LINEAR) {
3518fb5e6f88fc426e53af26e98d1c336222a8952cc5Brian Paul      /* no mipmapping - use base level */
3519fb5e6f88fc426e53af26e98d1c336222a8952cc5Brian Paul      level = tObj->BaseLevel;
3520fb5e6f88fc426e53af26e98d1c336222a8952cc5Brian Paul   }
3521fb5e6f88fc426e53af26e98d1c336222a8952cc5Brian Paul   else {
3522fb5e6f88fc426e53af26e98d1c336222a8952cc5Brian Paul      /* choose mipmap level */
3523cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      lambda = CLAMP(lambda, samp->MinLod, samp->MaxLod);
3524fb5e6f88fc426e53af26e98d1c336222a8952cc5Brian Paul      level = (GLint) lambda;
3525fb5e6f88fc426e53af26e98d1c336222a8952cc5Brian Paul      level = CLAMP(level, tObj->BaseLevel, tObj->_MaxLevel);
3526fb5e6f88fc426e53af26e98d1c336222a8952cc5Brian Paul   }
35272b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul
35282b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul   return level;
35292b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul}
35302b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul
35312b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul
35322b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul/**
35332b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul * Sample a shadow/depth texture.  This function is incomplete.  It doesn't
35342b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul * check for minification vs. magnification, etc.
35352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */
35362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
3537f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_depth_texture( struct gl_context *ctx,
3538cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                      const struct gl_sampler_object *samp,
35392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                      const struct gl_texture_object *tObj, GLuint n,
35402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                      const GLfloat texcoords[][4], const GLfloat lambda[],
3541de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul                      GLfloat texel[][4] )
35422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
3543cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   const GLint level = choose_depth_texture_level(samp, tObj, lambda[0]);
35442b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul   const struct gl_texture_image *img = tObj->Image[0][level];
3545a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
35469ebe3b6d369c946e41b5f6a684a4ac4e3509b67cBrian Paul   const GLint width = img->Width;
35479ebe3b6d369c946e41b5f6a684a4ac4e3509b67cBrian Paul   const GLint height = img->Height;
3548bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   const GLint depth = img->Depth;
3549bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick   const GLuint compare_coord = (tObj->Target == GL_TEXTURE_2D_ARRAY_EXT)
3550bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick       ? 3 : 2;
35512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLenum function;
3552de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul   GLfloat result;
35532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
35541f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul   ASSERT(img->_BaseFormat == GL_DEPTH_COMPONENT ||
35551f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul          img->_BaseFormat == GL_DEPTH_STENCIL_EXT);
3556b0a0ca8bd9edc13e495a39709cc28953dd3fbd9cBrian Paul
35572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   ASSERT(tObj->Target == GL_TEXTURE_1D ||
35582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul          tObj->Target == GL_TEXTURE_2D ||
3559bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick          tObj->Target == GL_TEXTURE_RECTANGLE_NV ||
3560bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick          tObj->Target == GL_TEXTURE_1D_ARRAY_EXT ||
3561c3aae7745a648d5d8f8386e09cd6d965f919c7d9Anuj Phogat          tObj->Target == GL_TEXTURE_2D_ARRAY_EXT ||
3562c3aae7745a648d5d8f8386e09cd6d965f919c7d9Anuj Phogat          tObj->Target == GL_TEXTURE_CUBE_MAP);
35632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
3564cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   /* XXXX if samp->MinFilter != samp->MagFilter, we're ignoring lambda */
35652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
3566cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   function = (samp->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) ?
3567cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      samp->CompareFunc : GL_NONE;
3568590f6fe05030cb274067a9e58af9d8306d97d0b9Brian Paul
3569cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   if (samp->MagFilter == GL_NEAREST) {
35702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      GLuint i;
35712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      for (i = 0; i < n; i++) {
3572d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor         GLfloat depthSample, depthRef;
3573bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         GLint col, row, slice;
3574fde15a2bae2f2ca552763705f12d53e4606feabfBrian
3575cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         nearest_texcoord(samp, tObj, level, texcoords[i], &col, &row, &slice);
3576bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3577bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         if (col >= 0 && row >= 0 && col < width && row < height &&
3578bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick             slice >= 0 && slice < depth) {
35795ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul            swImg->FetchTexel(swImg, col, row, slice, &depthSample);
35809ebe3b6d369c946e41b5f6a684a4ac4e3509b67cBrian Paul         }
35819ebe3b6d369c946e41b5f6a684a4ac4e3509b67cBrian Paul         else {
3582cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            depthSample = samp->BorderColor.f[0];
35839ebe3b6d369c946e41b5f6a684a4ac4e3509b67cBrian Paul         }
35842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
3585d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor         depthRef = CLAMP(texcoords[i][compare_coord], 0.0F, 1.0F);
3586d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor
3587707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick         result = shadow_compare(function, depthRef, depthSample);
35882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
35899282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul         apply_depth_mode(tObj->DepthMode, result, texel[i]);
35902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
35912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
35922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   else {
35932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      GLuint i;
3594cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen      ASSERT(samp->MagFilter == GL_LINEAR);
35952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      for (i = 0; i < n; i++) {
3596d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor         GLfloat depth00, depth01, depth10, depth11, depthRef;
35972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         GLint i0, i1, j0, j1;
3598bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         GLint slice;
3599a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul         GLfloat wi, wj;
36002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         GLuint useBorderTexel;
36012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
3602cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         linear_texcoord(samp, tObj, level, texcoords[i], &i0, &i1, &j0, &j1, &slice,
3603a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul                         &wi, &wj);
36042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
36052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         useBorderTexel = 0;
360606f606ce5761e673fca3f6b1f7dd40dace8a9906Brian Paul         if (img->Border) {
360706f606ce5761e673fca3f6b1f7dd40dace8a9906Brian Paul            i0 += img->Border;
360806f606ce5761e673fca3f6b1f7dd40dace8a9906Brian Paul            i1 += img->Border;
3609bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick            if (tObj->Target != GL_TEXTURE_1D_ARRAY_EXT) {
3610bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick               j0 += img->Border;
3611bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick               j1 += img->Border;
3612bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick            }
36132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
36142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         else {
36152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            if (i0 < 0 || i0 >= (GLint) width)   useBorderTexel |= I0BIT;
36162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            if (i1 < 0 || i1 >= (GLint) width)   useBorderTexel |= I1BIT;
36172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            if (j0 < 0 || j0 >= (GLint) height)  useBorderTexel |= J0BIT;
36182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            if (j1 < 0 || j1 >= (GLint) height)  useBorderTexel |= J1BIT;
36192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
36202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
3621bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         if (slice < 0 || slice >= (GLint) depth) {
3622cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            depth00 = samp->BorderColor.f[0];
3623cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            depth01 = samp->BorderColor.f[0];
3624cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            depth10 = samp->BorderColor.f[0];
3625cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            depth11 = samp->BorderColor.f[0];
36262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
36272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         else {
3628bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick            /* get four depth samples from the texture */
3629bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick            if (useBorderTexel & (I0BIT | J0BIT)) {
3630cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen               depth00 = samp->BorderColor.f[0];
3631bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick            }
3632bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick            else {
36335ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul               swImg->FetchTexel(swImg, i0, j0, slice, &depth00);
3634bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick            }
3635bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick            if (useBorderTexel & (I1BIT | J0BIT)) {
3636cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen               depth10 = samp->BorderColor.f[0];
3637bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick            }
3638bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick            else {
36395ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul               swImg->FetchTexel(swImg, i1, j0, slice, &depth10);
3640bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick            }
3641bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
3642bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick            if (tObj->Target != GL_TEXTURE_1D_ARRAY_EXT) {
3643bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick               if (useBorderTexel & (I0BIT | J1BIT)) {
3644cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                  depth01 = samp->BorderColor.f[0];
3645bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick               }
3646bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick               else {
36475ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul                  swImg->FetchTexel(swImg, i0, j1, slice, &depth01);
3648bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick               }
3649bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick               if (useBorderTexel & (I1BIT | J1BIT)) {
3650cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                  depth11 = samp->BorderColor.f[0];
3651bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick               }
3652bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick               else {
36535ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul                  swImg->FetchTexel(swImg, i1, j1, slice, &depth11);
3654bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick               }
3655bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick            }
3656bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick            else {
3657bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick               depth01 = depth00;
3658bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick               depth11 = depth10;
3659bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick            }
36602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
36612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
3662d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor         depthRef = CLAMP(texcoords[i][compare_coord], 0.0F, 1.0F);
3663d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor
3664d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor         result = shadow_compare4(function, depthRef,
3665a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul                                  depth00, depth01, depth10, depth11,
3666707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick                                  wi, wj);
36672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
36689282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul         apply_depth_mode(tObj->DepthMode, result, texel[i]);
36692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }  /* for */
36702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }  /* if filter */
36712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
36722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
36732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
36742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**
36752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * We use this function when a texture object is in an "incomplete" state.
36762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * When a fragment program attempts to sample an incomplete texture we
36772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * return black (see issue 23 in GL_ARB_fragment_program spec).
36785bfb9356d6df4c8b1e177ebda01631d99355ba25Brian Paul * Note: fragment programs don't observe the texture enable/disable flags.
36792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */
36802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void
3681f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnull_sample_func( struct gl_context *ctx,
3682cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                  const struct gl_sampler_object *samp,
36832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul		  const struct gl_texture_object *tObj, GLuint n,
36842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul		  const GLfloat texcoords[][4], const GLfloat lambda[],
3685de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul		  GLfloat rgba[][4])
36862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
36872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   GLuint i;
36882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   (void) ctx;
36892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   (void) tObj;
36902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   (void) texcoords;
36912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   (void) lambda;
3692cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen   (void) samp;
36932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   for (i = 0; i < n; i++) {
36942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      rgba[i][RCOMP] = 0;
36952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      rgba[i][GCOMP] = 0;
36962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      rgba[i][BCOMP] = 0;
36973fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul      rgba[i][ACOMP] = 1.0;
36982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
36992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
37002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
37012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
37022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**
37032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Choose the texture sampling function for the given texture object.
37042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */
37052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paultexture_sample_func
3706f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_choose_texture_sample_func( struct gl_context *ctx,
3707f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul				    const struct gl_texture_object *t,
3708f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul                                    const struct gl_sampler_object *sampler)
37092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{
3710f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul   if (!t || !_mesa_is_texture_complete(t, sampler)) {
37112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      return &null_sample_func;
37122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
37132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   else {
3714ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul      const GLboolean needLambda =
3715cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         (GLboolean) (sampler->MinFilter != sampler->MagFilter);
37162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul
37172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      switch (t->Target) {
37182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_TEXTURE_1D:
37199282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul         if (is_depth_texture(t)) {
37202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            return &sample_depth_texture;
37212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
37222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         else if (needLambda) {
37232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            return &sample_lambda_1d;
37242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
3725cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         else if (sampler->MinFilter == GL_LINEAR) {
37262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            return &sample_linear_1d;
37272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
37282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         else {
3729cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            ASSERT(sampler->MinFilter == GL_NEAREST);
37302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            return &sample_nearest_1d;
37312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
37322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_TEXTURE_2D:
37339282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul         if (is_depth_texture(t)) {
37342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            return &sample_depth_texture;
37352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
37362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         else if (needLambda) {
37378a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger            /* Anisotropic filtering extension. Activated only if mipmaps are used */
3738cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            if (sampler->MaxAnisotropy > 1.0 &&
3739cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                sampler->MinFilter == GL_LINEAR_MIPMAP_LINEAR) {
37408a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger               return &sample_lambda_2d_aniso;
37418a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger            }
37422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            return &sample_lambda_2d;
37432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
3744cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         else if (sampler->MinFilter == GL_LINEAR) {
37452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            return &sample_linear_2d;
37462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
37472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         else {
374806f606ce5761e673fca3f6b1f7dd40dace8a9906Brian Paul            /* check for a few optimized cases */
374906f606ce5761e673fca3f6b1f7dd40dace8a9906Brian Paul            const struct gl_texture_image *img = t->Image[0][t->BaseLevel];
3750eaf376ba354db11f7729452060570b48a029c9a0Brian Paul            const struct swrast_texture_image *swImg =
3751eaf376ba354db11f7729452060570b48a029c9a0Brian Paul               swrast_texture_image_const(img);
37529f7b6a39f6ebc070ff5020578cea2d299b21d476Yuanhan Liu            texture_sample_func func;
3753eaf376ba354db11f7729452060570b48a029c9a0Brian Paul
3754cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            ASSERT(sampler->MinFilter == GL_NEAREST);
37559f7b6a39f6ebc070ff5020578cea2d299b21d476Yuanhan Liu            func = &sample_nearest_2d;
3756cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            if (sampler->WrapS == GL_REPEAT &&
3757cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen                sampler->WrapT == GL_REPEAT &&
3758eaf376ba354db11f7729452060570b48a029c9a0Brian Paul                swImg->_IsPowerOfTwo &&
37599f7b6a39f6ebc070ff5020578cea2d299b21d476Yuanhan Liu                img->Border == 0) {
37609f7b6a39f6ebc070ff5020578cea2d299b21d476Yuanhan Liu               if (img->TexFormat == MESA_FORMAT_RGB888)
37619f7b6a39f6ebc070ff5020578cea2d299b21d476Yuanhan Liu                  func = &opt_sample_rgb_2d;
37629f7b6a39f6ebc070ff5020578cea2d299b21d476Yuanhan Liu               else if (img->TexFormat == MESA_FORMAT_RGBA8888)
37639f7b6a39f6ebc070ff5020578cea2d299b21d476Yuanhan Liu                  func = &opt_sample_rgba_2d;
37642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            }
37659f7b6a39f6ebc070ff5020578cea2d299b21d476Yuanhan Liu
37669f7b6a39f6ebc070ff5020578cea2d299b21d476Yuanhan Liu            return func;
37672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
37682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_TEXTURE_3D:
37692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         if (needLambda) {
37702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            return &sample_lambda_3d;
37712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
3772cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         else if (sampler->MinFilter == GL_LINEAR) {
37732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            return &sample_linear_3d;
37742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
37752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         else {
3776cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            ASSERT(sampler->MinFilter == GL_NEAREST);
37772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            return &sample_nearest_3d;
37782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
37792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_TEXTURE_CUBE_MAP:
37809282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul         if (needLambda) {
37812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            return &sample_lambda_cube;
37822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
3783cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         else if (sampler->MinFilter == GL_LINEAR) {
37842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            return &sample_linear_cube;
37852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
37862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         else {
3787cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            ASSERT(sampler->MinFilter == GL_NEAREST);
37882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            return &sample_nearest_cube;
37892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
37902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      case GL_TEXTURE_RECTANGLE_NV:
37919282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul         if (is_depth_texture(t)) {
3792fde15a2bae2f2ca552763705f12d53e4606feabfBrian            return &sample_depth_texture;
3793fde15a2bae2f2ca552763705f12d53e4606feabfBrian         }
3794fde15a2bae2f2ca552763705f12d53e4606feabfBrian         else if (needLambda) {
37952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            return &sample_lambda_rect;
37962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
3797cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         else if (sampler->MinFilter == GL_LINEAR) {
37982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            return &sample_linear_rect;
37992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
38002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         else {
3801cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            ASSERT(sampler->MinFilter == GL_NEAREST);
38022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul            return &sample_nearest_rect;
38032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         }
3804bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      case GL_TEXTURE_1D_ARRAY_EXT:
38059282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul         if (is_depth_texture(t)) {
3806c3aae7745a648d5d8f8386e09cd6d965f919c7d9Anuj Phogat            return &sample_depth_texture;
3807c3aae7745a648d5d8f8386e09cd6d965f919c7d9Anuj Phogat         }
3808c3aae7745a648d5d8f8386e09cd6d965f919c7d9Anuj Phogat	 else if (needLambda) {
3809bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick            return &sample_lambda_1d_array;
3810bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         }
3811cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         else if (sampler->MinFilter == GL_LINEAR) {
3812bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick            return &sample_linear_1d_array;
3813bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         }
3814bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         else {
3815cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            ASSERT(sampler->MinFilter == GL_NEAREST);
3816bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick            return &sample_nearest_1d_array;
3817bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         }
3818bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      case GL_TEXTURE_2D_ARRAY_EXT:
38199282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul         if (is_depth_texture(t)) {
3820c3aae7745a648d5d8f8386e09cd6d965f919c7d9Anuj Phogat            return &sample_depth_texture;
3821c3aae7745a648d5d8f8386e09cd6d965f919c7d9Anuj Phogat         }
3822c3aae7745a648d5d8f8386e09cd6d965f919c7d9Anuj Phogat	 else if (needLambda) {
3823bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick            return &sample_lambda_2d_array;
3824bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         }
3825cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen         else if (sampler->MinFilter == GL_LINEAR) {
3826bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick            return &sample_linear_2d_array;
3827bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         }
3828bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         else {
3829cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen            ASSERT(sampler->MinFilter == GL_NEAREST);
3830bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick            return &sample_nearest_2d_array;
3831bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick         }
38322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      default:
38332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         _mesa_problem(ctx,
38342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul                       "invalid target in _swrast_choose_texture_sample_func");
38352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul         return &null_sample_func;
38362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul      }
38372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul   }
38382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul}
3839