1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Mesa 3-D graphics library
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Version:  7.3
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"),
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions:
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice shall be included
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * in all copies or substantial portions of the Software.
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/glheader.h"
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/context.h"
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/colormac.h"
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/imports.h"
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/texobj.h"
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/samplerobj.h"
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "s_context.h"
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "s_texfilter.h"
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Note, the FRAC macro has to work perfectly.  Otherwise you'll sometimes
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * see 1-pixel bands of improperly weighted linear-filtered textures.
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The tests/texwrap.c demo is a good test.
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0.
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x).
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define FRAC(f)  ((f) - IFLOOR(f))
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Linear interpolation macro
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define LERP(T, A, B)  ( (A) + (T) * ((B) - (A)) )
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Do 2D/biliner interpolation of float values.
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * v00, v10, v01 and v11 are typically four texture samples in a square/box.
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * a and b are the horizontal and vertical interpolants.
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * It's important that this function is inlined when compiled with
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * optimization!  If we find that's not true on some systems, convert
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to a macro.
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline GLfloat
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglerp_2d(GLfloat a, GLfloat b,
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        GLfloat v00, GLfloat v10, GLfloat v01, GLfloat v11)
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat temp0 = LERP(a, v00, v10);
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat temp1 = LERP(a, v01, v11);
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return LERP(b, temp0, temp1);
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Do 3D/trilinear interpolation of float values.
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \sa lerp_2d
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline GLfloat
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglerp_3d(GLfloat a, GLfloat b, GLfloat c,
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        GLfloat v000, GLfloat v100, GLfloat v010, GLfloat v110,
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        GLfloat v001, GLfloat v101, GLfloat v011, GLfloat v111)
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat temp00 = LERP(a, v000, v100);
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat temp10 = LERP(a, v010, v110);
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat temp01 = LERP(a, v001, v101);
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat temp11 = LERP(a, v011, v111);
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat temp0 = LERP(b, temp00, temp10);
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat temp1 = LERP(b, temp01, temp11);
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return LERP(c, temp0, temp1);
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Do linear interpolation of colors.
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline void
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglerp_rgba(GLfloat result[4], GLfloat t, const GLfloat a[4], const GLfloat b[4])
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   result[0] = LERP(t, a[0], b[0]);
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   result[1] = LERP(t, a[1], b[1]);
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   result[2] = LERP(t, a[2], b[2]);
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   result[3] = LERP(t, a[3], b[3]);
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Do bilinear interpolation of colors.
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline void
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglerp_rgba_2d(GLfloat result[4], GLfloat a, GLfloat b,
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             const GLfloat t00[4], const GLfloat t10[4],
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             const GLfloat t01[4], const GLfloat t11[4])
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   result[0] = lerp_2d(a, b, t00[0], t10[0], t01[0], t11[0]);
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   result[1] = lerp_2d(a, b, t00[1], t10[1], t01[1], t11[1]);
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   result[2] = lerp_2d(a, b, t00[2], t10[2], t01[2], t11[2]);
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   result[3] = lerp_2d(a, b, t00[3], t10[3], t01[3], t11[3]);
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Do trilinear interpolation of colors.
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline void
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglerp_rgba_3d(GLfloat result[4], GLfloat a, GLfloat b, GLfloat c,
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             const GLfloat t000[4], const GLfloat t100[4],
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             const GLfloat t010[4], const GLfloat t110[4],
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             const GLfloat t001[4], const GLfloat t101[4],
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             const GLfloat t011[4], const GLfloat t111[4])
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint k;
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* compiler should unroll these short loops */
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (k = 0; k < 4; k++) {
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result[k] = lerp_3d(a, b, c, t000[k], t100[k], t010[k], t110[k],
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   t001[k], t101[k], t011[k], t111[k]);
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Used for GL_REPEAT wrap mode.  Using A % B doesn't produce the
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * right results for A<0.  Casting to A to be unsigned only works if B
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is a power of two.  Adding a bias to A (which is a multiple of B)
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * avoids the problems with A < 0 (for reasonable A) without using a
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * conditional.
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define REMAINDER(A, B) (((A) + (B) * 1024) % (B))
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Used to compute texel locations for linear sampling.
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Input:
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    wrapMode = GL_REPEAT, GL_CLAMP, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    s = texcoord in [0,1]
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    size = width (or height or depth) of texture
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Output:
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    i0, i1 = returns two nearest texel indexes
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    weight = returns blend factor between texels
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline void
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglinear_texel_locations(GLenum wrapMode,
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const struct gl_texture_image *img,
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       GLint size, GLfloat s,
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       GLint *i0, GLint *i1, GLfloat *weight)
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat u;
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (wrapMode) {
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_REPEAT:
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      u = s * size - 0.5F;
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (swImg->_IsPowerOfTwo) {
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *i0 = IFLOOR(u) & (size - 1);
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *i1 = (*i0 + 1) & (size - 1);
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *i0 = REMAINDER(IFLOOR(u), size);
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *i1 = REMAINDER(*i0 + 1, size);
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_CLAMP_TO_EDGE:
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (s <= 0.0F)
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         u = 0.0F;
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if (s >= 1.0F)
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         u = (GLfloat) size;
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         u = s * size;
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      u -= 0.5F;
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *i0 = IFLOOR(u);
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *i1 = *i0 + 1;
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (*i0 < 0)
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *i0 = 0;
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (*i1 >= (GLint) size)
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *i1 = size - 1;
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_CLAMP_TO_BORDER:
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      {
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat min = -1.0F / (2.0F * size);
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat max = 1.0F - min;
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (s <= min)
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            u = min * size;
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else if (s >= max)
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            u = max * size;
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            u = s * size;
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         u -= 0.5F;
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *i0 = IFLOOR(u);
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *i1 = *i0 + 1;
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_MIRRORED_REPEAT:
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      {
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLint flr = IFLOOR(s);
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (flr & 1)
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            u = 1.0F - (s - (GLfloat) flr);
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            u = s - (GLfloat) flr;
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         u = (u * size) - 0.5F;
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *i0 = IFLOOR(u);
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *i1 = *i0 + 1;
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (*i0 < 0)
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            *i0 = 0;
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (*i1 >= (GLint) size)
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            *i1 = size - 1;
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_MIRROR_CLAMP_EXT:
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      u = FABSF(s);
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (u >= 1.0F)
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         u = (GLfloat) size;
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         u *= size;
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      u -= 0.5F;
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *i0 = IFLOOR(u);
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *i1 = *i0 + 1;
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_MIRROR_CLAMP_TO_EDGE_EXT:
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      u = FABSF(s);
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (u >= 1.0F)
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         u = (GLfloat) size;
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         u *= size;
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      u -= 0.5F;
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *i0 = IFLOOR(u);
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *i1 = *i0 + 1;
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (*i0 < 0)
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *i0 = 0;
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (*i1 >= (GLint) size)
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *i1 = size - 1;
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_MIRROR_CLAMP_TO_BORDER_EXT:
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      {
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat min = -1.0F / (2.0F * size);
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat max = 1.0F - min;
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         u = FABSF(s);
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (u <= min)
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            u = min * size;
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else if (u >= max)
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            u = max * size;
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            u *= size;
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         u -= 0.5F;
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *i0 = IFLOOR(u);
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *i1 = *i0 + 1;
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_CLAMP:
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (s <= 0.0F)
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         u = 0.0F;
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if (s >= 1.0F)
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         u = (GLfloat) size;
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         u = s * size;
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      u -= 0.5F;
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *i0 = IFLOOR(u);
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *i1 = *i0 + 1;
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_problem(NULL, "Bad wrap mode");
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      u = 0.0F;
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *weight = FRAC(u);
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Used to compute texel location for nearest sampling.
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline GLint
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnearest_texel_location(GLenum wrapMode,
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const struct gl_texture_image *img,
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       GLint size, GLfloat s)
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint i;
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (wrapMode) {
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_REPEAT:
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* s limited to [0,1) */
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* i limited to [0,size-1] */
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      i = IFLOOR(s * size);
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (swImg->_IsPowerOfTwo)
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         i &= (size - 1);
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         i = REMAINDER(i, size);
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return i;
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_CLAMP_TO_EDGE:
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      {
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* s limited to [min,max] */
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* i limited to [0, size-1] */
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat min = 1.0F / (2.0F * size);
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat max = 1.0F - min;
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (s < min)
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            i = 0;
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else if (s > max)
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            i = size - 1;
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            i = IFLOOR(s * size);
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return i;
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_CLAMP_TO_BORDER:
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      {
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* s limited to [min,max] */
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* i limited to [-1, size] */
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat min = -1.0F / (2.0F * size);
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat max = 1.0F - min;
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (s <= min)
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            i = -1;
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else if (s >= max)
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            i = size;
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            i = IFLOOR(s * size);
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return i;
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_MIRRORED_REPEAT:
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      {
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat min = 1.0F / (2.0F * size);
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat max = 1.0F - min;
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLint flr = IFLOOR(s);
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         GLfloat u;
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (flr & 1)
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            u = 1.0F - (s - (GLfloat) flr);
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            u = s - (GLfloat) flr;
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (u < min)
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            i = 0;
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else if (u > max)
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            i = size - 1;
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            i = IFLOOR(u * size);
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return i;
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_MIRROR_CLAMP_EXT:
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      {
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* s limited to [0,1] */
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* i limited to [0,size-1] */
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat u = FABSF(s);
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (u <= 0.0F)
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            i = 0;
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else if (u >= 1.0F)
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            i = size - 1;
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            i = IFLOOR(u * size);
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return i;
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_MIRROR_CLAMP_TO_EDGE_EXT:
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      {
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* s limited to [min,max] */
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* i limited to [0, size-1] */
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat min = 1.0F / (2.0F * size);
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat max = 1.0F - min;
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat u = FABSF(s);
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (u < min)
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            i = 0;
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else if (u > max)
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            i = size - 1;
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            i = IFLOOR(u * size);
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return i;
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_MIRROR_CLAMP_TO_BORDER_EXT:
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      {
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* s limited to [min,max] */
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* i limited to [0, size-1] */
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat min = -1.0F / (2.0F * size);
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat max = 1.0F - min;
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat u = FABSF(s);
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (u < min)
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            i = -1;
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else if (u > max)
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            i = size;
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            i = IFLOOR(u * size);
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return i;
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_CLAMP:
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* s limited to [0,1] */
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* i limited to [0,size-1] */
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (s <= 0.0F)
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         i = 0;
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if (s >= 1.0F)
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         i = size - 1;
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         i = IFLOOR(s * size);
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return i;
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_problem(NULL, "Bad wrap mode");
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 0;
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Power of two image sizes only */
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline void
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglinear_repeat_texel_location(GLuint size, GLfloat s,
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             GLint *i0, GLint *i1, GLfloat *weight)
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat u = s * size - 0.5F;
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *i0 = IFLOOR(u) & (size - 1);
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *i1 = (*i0 + 1) & (size - 1);
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *weight = FRAC(u);
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Do clamp/wrap for a texture rectangle coord, GL_NEAREST filter mode.
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline GLint
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclamp_rect_coord_nearest(GLenum wrapMode, GLfloat coord, GLint max)
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (wrapMode) {
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_CLAMP:
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return IFLOOR( CLAMP(coord, 0.0F, max - 1) );
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_CLAMP_TO_EDGE:
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return IFLOOR( CLAMP(coord, 0.5F, max - 0.5F) );
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_CLAMP_TO_BORDER:
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return IFLOOR( CLAMP(coord, -0.5F, max + 0.5F) );
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_problem(NULL, "bad wrapMode in clamp_rect_coord_nearest");
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 0;
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * As above, but GL_LINEAR filtering.
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline void
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclamp_rect_coord_linear(GLenum wrapMode, GLfloat coord, GLint max,
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        GLint *i0out, GLint *i1out, GLfloat *weight)
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat fcol;
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint i0, i1;
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (wrapMode) {
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_CLAMP:
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Not exactly what the spec says, but it matches NVIDIA output */
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fcol = CLAMP(coord - 0.5F, 0.0F, max - 1);
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      i0 = IFLOOR(fcol);
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      i1 = i0 + 1;
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_CLAMP_TO_EDGE:
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fcol = CLAMP(coord, 0.5F, max - 0.5F);
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fcol -= 0.5F;
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      i0 = IFLOOR(fcol);
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      i1 = i0 + 1;
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (i1 > max - 1)
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         i1 = max - 1;
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_CLAMP_TO_BORDER:
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fcol = CLAMP(coord, -0.5F, max + 0.5F);
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fcol -= 0.5F;
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      i0 = IFLOOR(fcol);
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      i1 = i0 + 1;
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_problem(NULL, "bad wrapMode in clamp_rect_coord_linear");
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      i0 = i1 = 0;
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fcol = 0.0F;
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *i0out = i0;
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *i1out = i1;
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *weight = FRAC(fcol);
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Compute slice/image to use for 1D or 2D array texture.
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline GLint
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtex_array_slice(GLfloat coord, GLsizei size)
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint slice = IFLOOR(coord + 0.5f);
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   slice = CLAMP(slice, 0, size - 1);
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return slice;
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Compute nearest integer texcoords for given texobj and coordinate.
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * NOTE: only used for depth texture sampling.
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline void
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnearest_texcoord(const struct gl_sampler_object *samp,
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const struct gl_texture_object *texObj,
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 GLuint level,
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const GLfloat texcoord[4],
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 GLint *i, GLint *j, GLint *k)
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct gl_texture_image *img = texObj->Image[0][level];
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint width = img->Width;
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint height = img->Height;
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint depth = img->Depth;
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (texObj->Target) {
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_TEXTURE_RECTANGLE_ARB:
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *i = clamp_rect_coord_nearest(samp->WrapS, texcoord[0], width);
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *j = clamp_rect_coord_nearest(samp->WrapT, texcoord[1], height);
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *k = 0;
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_TEXTURE_1D:
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *i = nearest_texel_location(samp->WrapS, img, width, texcoord[0]);
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *j = 0;
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *k = 0;
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_TEXTURE_2D:
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *i = nearest_texel_location(samp->WrapS, img, width, texcoord[0]);
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *j = nearest_texel_location(samp->WrapT, img, height, texcoord[1]);
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *k = 0;
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_TEXTURE_1D_ARRAY_EXT:
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *i = nearest_texel_location(samp->WrapS, img, width, texcoord[0]);
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *j = tex_array_slice(texcoord[1], height);
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *k = 0;
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_TEXTURE_2D_ARRAY_EXT:
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *i = nearest_texel_location(samp->WrapS, img, width, texcoord[0]);
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *j = nearest_texel_location(samp->WrapT, img, height, texcoord[1]);
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *k = tex_array_slice(texcoord[2], depth);
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *i = *j = *k = 0;
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Compute linear integer texcoords for given texobj and coordinate.
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * NOTE: only used for depth texture sampling.
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline void
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglinear_texcoord(const struct gl_sampler_object *samp,
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                const struct gl_texture_object *texObj,
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                GLuint level,
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                const GLfloat texcoord[4],
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                GLint *i0, GLint *i1, GLint *j0, GLint *j1, GLint *slice,
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                GLfloat *wi, GLfloat *wj)
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct gl_texture_image *img = texObj->Image[0][level];
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint width = img->Width;
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint height = img->Height;
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint depth = img->Depth;
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (texObj->Target) {
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_TEXTURE_RECTANGLE_ARB:
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      clamp_rect_coord_linear(samp->WrapS, texcoord[0],
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              width, i0, i1, wi);
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      clamp_rect_coord_linear(samp->WrapT, texcoord[1],
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              height, j0, j1, wj);
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *slice = 0;
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_TEXTURE_1D:
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_TEXTURE_2D:
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      linear_texel_locations(samp->WrapS, img, width,
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             texcoord[0], i0, i1, wi);
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      linear_texel_locations(samp->WrapT, img, height,
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             texcoord[1], j0, j1, wj);
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *slice = 0;
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_TEXTURE_1D_ARRAY_EXT:
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      linear_texel_locations(samp->WrapS, img, width,
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             texcoord[0], i0, i1, wi);
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *j0 = tex_array_slice(texcoord[1], height);
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *j1 = *j0;
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *slice = 0;
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_TEXTURE_2D_ARRAY_EXT:
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      linear_texel_locations(samp->WrapS, img, width,
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             texcoord[0], i0, i1, wi);
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      linear_texel_locations(samp->WrapT, img, height,
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             texcoord[1], j0, j1, wj);
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *slice = tex_array_slice(texcoord[2], depth);
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *slice = 0;
599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * For linear interpolation between mipmap levels N and N+1, this function
607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * computes N.
608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline GLint
610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglinear_mipmap_level(const struct gl_texture_object *tObj, GLfloat lambda)
611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (lambda < 0.0F)
613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return tObj->BaseLevel;
614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (lambda > tObj->_MaxLambda)
615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (GLint) (tObj->BaseLevel + tObj->_MaxLambda);
616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (GLint) (tObj->BaseLevel + lambda);
618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Compute the nearest mipmap level to take texels from.
623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline GLint
625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnearest_mipmap_level(const struct gl_texture_object *tObj, GLfloat lambda)
626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat l;
628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint level;
629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (lambda <= 0.5F)
630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      l = 0.0F;
631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (lambda > tObj->_MaxLambda + 0.4999F)
632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      l = tObj->_MaxLambda + 0.4999F;
633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      l = lambda;
635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   level = (GLint) (tObj->BaseLevel + l + 0.5F);
636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (level > tObj->_MaxLevel)
637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      level = tObj->_MaxLevel;
638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return level;
639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Bitflags for texture border color sampling.
645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define I0BIT   1
647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define I1BIT   2
648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define J0BIT   4
649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define J1BIT   8
650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define K0BIT  16
651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define K1BIT  32
652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The lambda[] array values are always monotonic.  Either the whole span
657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * will be minified, magnified, or split between the two.  This function
658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * determines the subranges in [0, n-1] that are to be minified or magnified.
659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline void
661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcompute_min_mag_ranges(const struct gl_sampler_object *samp,
662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       GLuint n, const GLfloat lambda[],
663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       GLuint *minStart, GLuint *minEnd,
664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       GLuint *magStart, GLuint *magEnd)
665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat minMagThresh;
667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* we shouldn't be here if minfilter == magfilter */
669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(samp->MinFilter != samp->MagFilter);
670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* This bit comes from the OpenGL spec: */
672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (samp->MagFilter == GL_LINEAR
673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       && (samp->MinFilter == GL_NEAREST_MIPMAP_NEAREST ||
674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           samp->MinFilter == GL_NEAREST_MIPMAP_LINEAR)) {
675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      minMagThresh = 0.5F;
676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      minMagThresh = 0.0F;
679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0
682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* DEBUG CODE: Verify that lambda[] is monotonic.
683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * We can't really use this because the inaccuracy in the LOG2 function
684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * causes this test to fail, yet the resulting texturing is correct.
685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (n > 1) {
687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLuint i;
688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("lambda delta = %g\n", lambda[0] - lambda[n-1]);
689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (lambda[0] >= lambda[n-1]) { /* decreasing */
690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 0; i < n - 1; i++) {
691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            ASSERT((GLint) (lambda[i] * 10) >= (GLint) (lambda[i+1] * 10));
692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else { /* increasing */
695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 0; i < n - 1; i++) {
696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            ASSERT((GLint) (lambda[i] * 10) <= (GLint) (lambda[i+1] * 10));
697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* DEBUG */
701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (lambda[0] <= minMagThresh && (n <= 1 || lambda[n-1] <= minMagThresh)) {
703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* magnification for whole span */
704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *magStart = 0;
705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *magEnd = n;
706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *minStart = *minEnd = 0;
707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (lambda[0] > minMagThresh && (n <=1 || lambda[n-1] > minMagThresh)) {
709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* minification for whole span */
710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *minStart = 0;
711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *minEnd = n;
712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *magStart = *magEnd = 0;
713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* a mix of minification and magnification */
716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLuint i;
717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (lambda[0] > minMagThresh) {
718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* start with minification */
719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 1; i < n; i++) {
720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (lambda[i] <= minMagThresh)
721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               break;
722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *minStart = 0;
724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *minEnd = i;
725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *magStart = i;
726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *magEnd = n;
727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* start with magnification */
730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 1; i < n; i++) {
731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (lambda[i] > minMagThresh)
732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               break;
733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *magStart = 0;
735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *magEnd = i;
736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *minStart = i;
737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *minEnd = n;
738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0
742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Verify the min/mag Start/End values
743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * We don't use this either (see above)
744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint i;
747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < n; i++) {
748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (lambda[i] > minMagThresh) {
749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* minification */
750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            ASSERT(i >= *minStart);
751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            ASSERT(i < *minEnd);
752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else {
754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* magnification */
755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            ASSERT(i >= *magStart);
756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            ASSERT(i < *magEnd);
757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * When we sample the border color, it must be interpreted according to
766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the base texture format.  Ex: if the texture base format it GL_ALPHA,
767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * we return (0,0,0,BorderAlpha).
768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline void
770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_border_color(const struct gl_sampler_object *samp,
771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const struct gl_texture_image *img,
772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 GLfloat rgba[4])
773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (img->_BaseFormat) {
775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_RGB:
776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba[0] = samp->BorderColor.f[0];
777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba[1] = samp->BorderColor.f[1];
778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba[2] = samp->BorderColor.f[2];
779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba[3] = 1.0F;
780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_ALPHA:
782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba[0] = rgba[1] = rgba[2] = 0.0;
783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba[3] = samp->BorderColor.f[3];
784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_LUMINANCE:
786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba[0] = rgba[1] = rgba[2] = samp->BorderColor.f[0];
787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba[3] = 1.0;
788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_LUMINANCE_ALPHA:
790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba[0] = rgba[1] = rgba[2] = samp->BorderColor.f[0];
791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba[3] = samp->BorderColor.f[3];
792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_INTENSITY:
794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba[0] = rgba[1] = rgba[2] = rgba[3] = samp->BorderColor.f[0];
795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      COPY_4V(rgba, samp->BorderColor.f);
798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Put z into texel according to GL_DEPTH_MODE.
805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void
807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgapply_depth_mode(GLenum depthMode, GLfloat z, GLfloat texel[4])
808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (depthMode) {
810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_LUMINANCE:
811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ASSIGN_4V(texel, z, z, z, 1.0F);
812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_INTENSITY:
814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ASSIGN_4V(texel, z, z, z, z);
815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_ALPHA:
817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ASSIGN_4V(texel, 0.0F, 0.0F, 0.0F, z);
818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_RED:
820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ASSIGN_4V(texel, z, 0.0F, 0.0F, 1.0F);
821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_problem(NULL, "Bad depth texture mode");
824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Is the given texture a depth (or depth/stencil) texture?
830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLboolean
832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgis_depth_texture(const struct gl_texture_object *tObj)
833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLenum format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat;
835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT;
836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**********************************************************************/
840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*                    1-D Texture Sampling Functions                  */
841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**********************************************************************/
842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return the texture sample for coordinate (s) using GL_NEAREST filter.
845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline void
847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_1d_nearest(struct gl_context *ctx,
848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const struct gl_sampler_object *samp,
849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const struct gl_texture_image *img,
850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const GLfloat texcoord[4], GLfloat rgba[4])
851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint width = img->Width2;  /* without border, power of two */
854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint i;
855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i = nearest_texel_location(samp->WrapS, img, width, texcoord[0]);
856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* skip over the border, if any */
857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i += img->Border;
858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (i < 0 || i >= (GLint) img->Width) {
859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Need this test for GL_CLAMP_TO_BORDER mode */
860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      get_border_color(samp, img, rgba);
861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swImg->FetchTexel(swImg, i, 0, 0, rgba);
864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return the texture sample for coordinate (s) using GL_LINEAR filter.
870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline void
872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_1d_linear(struct gl_context *ctx,
873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const struct gl_sampler_object *samp,
874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const struct gl_texture_image *img,
875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const GLfloat texcoord[4], GLfloat rgba[4])
876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint width = img->Width2;
879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint i0, i1;
880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLbitfield useBorderColor = 0x0;
881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat a;
882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat t0[4], t1[4];  /* texels */
883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   linear_texel_locations(samp->WrapS, img, width, texcoord[0], &i0, &i1, &a);
885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (img->Border) {
887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      i0 += img->Border;
888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      i1 += img->Border;
889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (i0 < 0 || i0 >= width)   useBorderColor |= I0BIT;
892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (i1 < 0 || i1 >= width)   useBorderColor |= I1BIT;
893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* fetch texel colors */
896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (useBorderColor & I0BIT) {
897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      get_border_color(samp, img, t0);
898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swImg->FetchTexel(swImg, i0, 0, 0, t0);
901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (useBorderColor & I1BIT) {
903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      get_border_color(samp, img, t1);
904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swImg->FetchTexel(swImg, i1, 0, 0, t1);
907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lerp_rgba(rgba, a, t0, t1);
910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_1d_nearest_mipmap_nearest(struct gl_context *ctx,
915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 const struct gl_sampler_object *samp,
916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 const struct gl_texture_object *tObj,
917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 GLuint n, const GLfloat texcoord[][4],
918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 const GLfloat lambda[], GLfloat rgba[][4])
919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(lambda != NULL);
922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint level = nearest_mipmap_level(tObj, lambda[i]);
924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sample_1d_nearest(ctx, samp, tObj->Image[0][level], texcoord[i], rgba[i]);
925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_1d_linear_mipmap_nearest(struct gl_context *ctx,
931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                const struct gl_sampler_object *samp,
932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                const struct gl_texture_object *tObj,
933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                GLuint n, const GLfloat texcoord[][4],
934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                const GLfloat lambda[], GLfloat rgba[][4])
935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(lambda != NULL);
938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint level = nearest_mipmap_level(tObj, lambda[i]);
940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sample_1d_linear(ctx, samp, tObj->Image[0][level], texcoord[i], rgba[i]);
941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_1d_nearest_mipmap_linear(struct gl_context *ctx,
947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                const struct gl_sampler_object *samp,
948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                const struct gl_texture_object *tObj,
949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                GLuint n, const GLfloat texcoord[][4],
950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                const GLfloat lambda[], GLfloat rgba[][4])
951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(lambda != NULL);
954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint level = linear_mipmap_level(tObj, lambda[i]);
956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (level >= tObj->_MaxLevel) {
957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_1d_nearest(ctx, samp, tObj->Image[0][tObj->_MaxLevel],
958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           texcoord[i], rgba[i]);
959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         GLfloat t0[4], t1[4];
962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat f = FRAC(lambda[i]);
963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_1d_nearest(ctx, samp, tObj->Image[0][level  ], texcoord[i], t0);
964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_1d_nearest(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1);
965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lerp_rgba(rgba[i], f, t0, t1);
966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_1d_linear_mipmap_linear(struct gl_context *ctx,
973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               const struct gl_sampler_object *samp,
974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               const struct gl_texture_object *tObj,
975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               GLuint n, const GLfloat texcoord[][4],
976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               const GLfloat lambda[], GLfloat rgba[][4])
977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(lambda != NULL);
980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint level = linear_mipmap_level(tObj, lambda[i]);
982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (level >= tObj->_MaxLevel) {
983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_1d_linear(ctx, samp, tObj->Image[0][tObj->_MaxLevel],
984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          texcoord[i], rgba[i]);
985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         GLfloat t0[4], t1[4];
988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat f = FRAC(lambda[i]);
989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_1d_linear(ctx, samp, tObj->Image[0][level  ], texcoord[i], t0);
990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_1d_linear(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1);
991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lerp_rgba(rgba[i], f, t0, t1);
992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Sample 1D texture, nearest filtering for both min/magnification */
998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_nearest_1d( struct gl_context *ctx,
1000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   const struct gl_sampler_object *samp,
1001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   const struct gl_texture_object *tObj, GLuint n,
1002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   const GLfloat texcoords[][4], const GLfloat lambda[],
1003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   GLfloat rgba[][4] )
1004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
1006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
1007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) lambda;
1008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
1009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sample_1d_nearest(ctx, samp, image, texcoords[i], rgba[i]);
1010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Sample 1D texture, linear filtering for both min/magnification */
1015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
1016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_linear_1d( struct gl_context *ctx,
1017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const struct gl_sampler_object *samp,
1018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const struct gl_texture_object *tObj, GLuint n,
1019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const GLfloat texcoords[][4], const GLfloat lambda[],
1020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  GLfloat rgba[][4] )
1021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
1023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
1024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) lambda;
1025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
1026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sample_1d_linear(ctx, samp, image, texcoords[i], rgba[i]);
1027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Sample 1D texture, using lambda to choose between min/magnification */
1032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
1033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_lambda_1d( struct gl_context *ctx,
1034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const struct gl_sampler_object *samp,
1035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const struct gl_texture_object *tObj, GLuint n,
1036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const GLfloat texcoords[][4],
1037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const GLfloat lambda[], GLfloat rgba[][4] )
1038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint minStart, minEnd;  /* texels with minification */
1040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint magStart, magEnd;  /* texels with magnification */
1041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
1042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(lambda != NULL);
1044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   compute_min_mag_ranges(samp, n, lambda,
1045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          &minStart, &minEnd, &magStart, &magEnd);
1046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (minStart < minEnd) {
1048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* do the minified texels */
1049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const GLuint m = minEnd - minStart;
1050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (samp->MinFilter) {
1051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_NEAREST:
1052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = minStart; i < minEnd; i++)
1053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sample_1d_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel],
1054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              texcoords[i], rgba[i]);
1055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_LINEAR:
1057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = minStart; i < minEnd; i++)
1058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sample_1d_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel],
1059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             texcoords[i], rgba[i]);
1060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_NEAREST_MIPMAP_NEAREST:
1062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_1d_nearest_mipmap_nearest(ctx, samp, tObj, m, texcoords + minStart,
1063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          lambda + minStart, rgba + minStart);
1064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_LINEAR_MIPMAP_NEAREST:
1066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_1d_linear_mipmap_nearest(ctx, samp, tObj, m, texcoords + minStart,
1067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         lambda + minStart, rgba + minStart);
1068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_NEAREST_MIPMAP_LINEAR:
1070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_1d_nearest_mipmap_linear(ctx, samp, tObj, m, texcoords + minStart,
1071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         lambda + minStart, rgba + minStart);
1072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_LINEAR_MIPMAP_LINEAR:
1074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_1d_linear_mipmap_linear(ctx, samp, tObj, m, texcoords + minStart,
1075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        lambda + minStart, rgba + minStart);
1076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
1078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_problem(ctx, "Bad min filter in sample_1d_texture");
1079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return;
1080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (magStart < magEnd) {
1084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* do the magnified texels */
1085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (samp->MagFilter) {
1086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_NEAREST:
1087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = magStart; i < magEnd; i++)
1088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sample_1d_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel],
1089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              texcoords[i], rgba[i]);
1090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_LINEAR:
1092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = magStart; i < magEnd; i++)
1093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sample_1d_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel],
1094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             texcoords[i], rgba[i]);
1095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
1097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_problem(ctx, "Bad mag filter in sample_1d_texture");
1098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return;
1099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**********************************************************************/
1105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*                    2-D Texture Sampling Functions                  */
1106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**********************************************************************/
1107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
1110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return the texture sample for coordinate (s,t) using GL_NEAREST filter.
1111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline void
1113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_2d_nearest(struct gl_context *ctx,
1114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const struct gl_sampler_object *samp,
1115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const struct gl_texture_image *img,
1116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const GLfloat texcoord[4],
1117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  GLfloat rgba[])
1118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
1120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint width = img->Width2;    /* without border, power of two */
1121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint height = img->Height2;  /* without border, power of two */
1122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint i, j;
1123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) ctx;
1124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i = nearest_texel_location(samp->WrapS, img, width, texcoord[0]);
1126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   j = nearest_texel_location(samp->WrapT, img, height, texcoord[1]);
1127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* skip over the border, if any */
1129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i += img->Border;
1130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   j += img->Border;
1131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (i < 0 || i >= (GLint) img->Width || j < 0 || j >= (GLint) img->Height) {
1133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Need this test for GL_CLAMP_TO_BORDER mode */
1134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      get_border_color(samp, img, rgba);
1135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
1137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swImg->FetchTexel(swImg, i, j, 0, rgba);
1138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
1143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return the texture sample for coordinate (s,t) using GL_LINEAR filter.
1144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * New sampling code contributed by Lynn Quam <quam@ai.sri.com>.
1145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline void
1147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_2d_linear(struct gl_context *ctx,
1148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const struct gl_sampler_object *samp,
1149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const struct gl_texture_image *img,
1150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const GLfloat texcoord[4],
1151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 GLfloat rgba[])
1152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
1154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint width = img->Width2;
1155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint height = img->Height2;
1156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint i0, j0, i1, j1;
1157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLbitfield useBorderColor = 0x0;
1158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat a, b;
1159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat t00[4], t10[4], t01[4], t11[4]; /* sampled texel colors */
1160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   linear_texel_locations(samp->WrapS, img, width, texcoord[0],  &i0, &i1, &a);
1162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   linear_texel_locations(samp->WrapT, img, height, texcoord[1], &j0, &j1, &b);
1163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (img->Border) {
1165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      i0 += img->Border;
1166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      i1 += img->Border;
1167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      j0 += img->Border;
1168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      j1 += img->Border;
1169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
1171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (i0 < 0 || i0 >= width)   useBorderColor |= I0BIT;
1172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (i1 < 0 || i1 >= width)   useBorderColor |= I1BIT;
1173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (j0 < 0 || j0 >= height)  useBorderColor |= J0BIT;
1174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (j1 < 0 || j1 >= height)  useBorderColor |= J1BIT;
1175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* fetch four texel colors */
1178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (useBorderColor & (I0BIT | J0BIT)) {
1179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      get_border_color(samp, img, t00);
1180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
1182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swImg->FetchTexel(swImg, i0, j0, 0, t00);
1183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (useBorderColor & (I1BIT | J0BIT)) {
1185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      get_border_color(samp, img, t10);
1186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
1188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swImg->FetchTexel(swImg, i1, j0, 0, t10);
1189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (useBorderColor & (I0BIT | J1BIT)) {
1191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      get_border_color(samp, img, t01);
1192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
1194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swImg->FetchTexel(swImg, i0, j1, 0, t01);
1195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (useBorderColor & (I1BIT | J1BIT)) {
1197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      get_border_color(samp, img, t11);
1198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
1200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swImg->FetchTexel(swImg, i1, j1, 0, t11);
1201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lerp_rgba_2d(rgba, a, b, t00, t10, t01, t11);
1204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
1208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * As above, but we know WRAP_S == REPEAT and WRAP_T == REPEAT.
1209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * We don't have to worry about the texture border.
1210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline void
1212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_2d_linear_repeat(struct gl_context *ctx,
1213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct gl_sampler_object *samp,
1214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct gl_texture_image *img,
1215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const GLfloat texcoord[4],
1216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        GLfloat rgba[])
1217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
1219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint width = img->Width2;
1220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint height = img->Height2;
1221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint i0, j0, i1, j1;
1222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat wi, wj;
1223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat t00[4], t10[4], t01[4], t11[4]; /* sampled texel colors */
1224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) ctx;
1226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(samp->WrapS == GL_REPEAT);
1228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(samp->WrapT == GL_REPEAT);
1229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(img->Border == 0);
1230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(swImg->_IsPowerOfTwo);
1231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   linear_repeat_texel_location(width,  texcoord[0], &i0, &i1, &wi);
1233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   linear_repeat_texel_location(height, texcoord[1], &j0, &j1, &wj);
1234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   swImg->FetchTexel(swImg, i0, j0, 0, t00);
1236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   swImg->FetchTexel(swImg, i1, j0, 0, t10);
1237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   swImg->FetchTexel(swImg, i0, j1, 0, t01);
1238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   swImg->FetchTexel(swImg, i1, j1, 0, t11);
1239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lerp_rgba_2d(rgba, wi, wj, t00, t10, t01, t11);
1241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
1245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_2d_nearest_mipmap_nearest(struct gl_context *ctx,
1246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 const struct gl_sampler_object *samp,
1247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 const struct gl_texture_object *tObj,
1248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 GLuint n, const GLfloat texcoord[][4],
1249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 const GLfloat lambda[], GLfloat rgba[][4])
1250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
1252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
1253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint level = nearest_mipmap_level(tObj, lambda[i]);
1254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sample_2d_nearest(ctx, samp, tObj->Image[0][level], texcoord[i], rgba[i]);
1255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
1260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_2d_linear_mipmap_nearest(struct gl_context *ctx,
1261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                const struct gl_sampler_object *samp,
1262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                const struct gl_texture_object *tObj,
1263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                GLuint n, const GLfloat texcoord[][4],
1264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                const GLfloat lambda[], GLfloat rgba[][4])
1265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
1267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(lambda != NULL);
1268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
1269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint level = nearest_mipmap_level(tObj, lambda[i]);
1270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sample_2d_linear(ctx, samp, tObj->Image[0][level], texcoord[i], rgba[i]);
1271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
1276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_2d_nearest_mipmap_linear(struct gl_context *ctx,
1277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                const struct gl_sampler_object *samp,
1278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                const struct gl_texture_object *tObj,
1279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                GLuint n, const GLfloat texcoord[][4],
1280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                const GLfloat lambda[], GLfloat rgba[][4])
1281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
1283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(lambda != NULL);
1284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
1285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint level = linear_mipmap_level(tObj, lambda[i]);
1286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (level >= tObj->_MaxLevel) {
1287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_nearest(ctx, samp, tObj->Image[0][tObj->_MaxLevel],
1288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           texcoord[i], rgba[i]);
1289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
1291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         GLfloat t0[4], t1[4];  /* texels */
1292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat f = FRAC(lambda[i]);
1293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_nearest(ctx, samp, tObj->Image[0][level  ], texcoord[i], t0);
1294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_nearest(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1);
1295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lerp_rgba(rgba[i], f, t0, t1);
1296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
1302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_2d_linear_mipmap_linear( struct gl_context *ctx,
1303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                const struct gl_sampler_object *samp,
1304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                const struct gl_texture_object *tObj,
1305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                GLuint n, const GLfloat texcoord[][4],
1306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                const GLfloat lambda[], GLfloat rgba[][4] )
1307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
1309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(lambda != NULL);
1310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
1311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint level = linear_mipmap_level(tObj, lambda[i]);
1312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (level >= tObj->_MaxLevel) {
1313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_linear(ctx, samp, tObj->Image[0][tObj->_MaxLevel],
1314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          texcoord[i], rgba[i]);
1315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
1317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         GLfloat t0[4], t1[4];  /* texels */
1318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat f = FRAC(lambda[i]);
1319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_linear(ctx, samp, tObj->Image[0][level  ], texcoord[i], t0);
1320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_linear(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1);
1321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lerp_rgba(rgba[i], f, t0, t1);
1322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
1328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_2d_linear_mipmap_linear_repeat(struct gl_context *ctx,
1329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      const struct gl_sampler_object *samp,
1330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      const struct gl_texture_object *tObj,
1331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      GLuint n, const GLfloat texcoord[][4],
1332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      const GLfloat lambda[], GLfloat rgba[][4])
1333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
1335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(lambda != NULL);
1336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(samp->WrapS == GL_REPEAT);
1337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(samp->WrapT == GL_REPEAT);
1338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
1339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint level = linear_mipmap_level(tObj, lambda[i]);
1340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (level >= tObj->_MaxLevel) {
1341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_linear_repeat(ctx, samp, tObj->Image[0][tObj->_MaxLevel],
1342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 texcoord[i], rgba[i]);
1343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
1345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         GLfloat t0[4], t1[4];  /* texels */
1346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat f = FRAC(lambda[i]);
1347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_linear_repeat(ctx, samp, tObj->Image[0][level  ],
1348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 texcoord[i], t0);
1349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_linear_repeat(ctx, samp, tObj->Image[0][level+1],
1350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 texcoord[i], t1);
1351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lerp_rgba(rgba[i], f, t0, t1);
1352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Sample 2D texture, nearest filtering for both min/magnification */
1358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
1359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_nearest_2d(struct gl_context *ctx,
1360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const struct gl_sampler_object *samp,
1361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const struct gl_texture_object *tObj, GLuint n,
1362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const GLfloat texcoords[][4],
1363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const GLfloat lambda[], GLfloat rgba[][4])
1364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
1366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
1367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) lambda;
1368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
1369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sample_2d_nearest(ctx, samp, image, texcoords[i], rgba[i]);
1370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Sample 2D texture, linear filtering for both min/magnification */
1375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
1376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_linear_2d(struct gl_context *ctx,
1377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const struct gl_sampler_object *samp,
1378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const struct gl_texture_object *tObj, GLuint n,
1379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const GLfloat texcoords[][4],
1380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const GLfloat lambda[], GLfloat rgba[][4])
1381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
1383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
1384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct swrast_texture_image *swImg = swrast_texture_image_const(image);
1385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) lambda;
1386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (samp->WrapS == GL_REPEAT &&
1387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       samp->WrapT == GL_REPEAT &&
1388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       swImg->_IsPowerOfTwo &&
1389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       image->Border == 0) {
1390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < n; i++) {
1391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_linear_repeat(ctx, samp, image, texcoords[i], rgba[i]);
1392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
1395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < n; i++) {
1396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_linear(ctx, samp, image, texcoords[i], rgba[i]);
1397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
1403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Optimized 2-D texture sampling:
1404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    S and T wrap mode == GL_REPEAT
1405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    GL_NEAREST min/mag filter
1406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    No border,
1407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    RowStride == Width,
1408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    Format = GL_RGB
1409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
1411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgopt_sample_rgb_2d(struct gl_context *ctx,
1412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const struct gl_sampler_object *samp,
1413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const struct gl_texture_object *tObj,
1414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  GLuint n, const GLfloat texcoords[][4],
1415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const GLfloat lambda[], GLfloat rgba[][4])
1416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct gl_texture_image *img = tObj->Image[0][tObj->BaseLevel];
1418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
1419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat width = (GLfloat) img->Width;
1420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat height = (GLfloat) img->Height;
1421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint colMask = img->Width - 1;
1422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint rowMask = img->Height - 1;
1423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint shift = img->WidthLog2;
1424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint k;
1425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) ctx;
1426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) lambda;
1427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(samp->WrapS==GL_REPEAT);
1428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(samp->WrapT==GL_REPEAT);
1429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(img->Border==0);
1430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(img->TexFormat == MESA_FORMAT_RGB888);
1431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(swImg->_IsPowerOfTwo);
1432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) swImg;
1433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (k=0; k<n; k++) {
1435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint i = IFLOOR(texcoords[k][0] * width) & colMask;
1436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint j = IFLOOR(texcoords[k][1] * height) & rowMask;
1437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint pos = (j << shift) | i;
1438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLubyte *texel = swImg->Map + 3 * pos;
1439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba[k][RCOMP] = UBYTE_TO_FLOAT(texel[2]);
1440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba[k][GCOMP] = UBYTE_TO_FLOAT(texel[1]);
1441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba[k][BCOMP] = UBYTE_TO_FLOAT(texel[0]);
1442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba[k][ACOMP] = 1.0F;
1443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
1448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Optimized 2-D texture sampling:
1449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    S and T wrap mode == GL_REPEAT
1450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    GL_NEAREST min/mag filter
1451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    No border
1452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    RowStride == Width,
1453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    Format = GL_RGBA
1454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
1456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgopt_sample_rgba_2d(struct gl_context *ctx,
1457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   const struct gl_sampler_object *samp,
1458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   const struct gl_texture_object *tObj,
1459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   GLuint n, const GLfloat texcoords[][4],
1460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   const GLfloat lambda[], GLfloat rgba[][4])
1461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct gl_texture_image *img = tObj->Image[0][tObj->BaseLevel];
1463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
1464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat width = (GLfloat) img->Width;
1465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat height = (GLfloat) img->Height;
1466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint colMask = img->Width - 1;
1467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint rowMask = img->Height - 1;
1468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint shift = img->WidthLog2;
1469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
1470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) ctx;
1471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) lambda;
1472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(samp->WrapS==GL_REPEAT);
1473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(samp->WrapT==GL_REPEAT);
1474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(img->Border==0);
1475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(img->TexFormat == MESA_FORMAT_RGBA8888);
1476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(swImg->_IsPowerOfTwo);
1477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) swImg;
1478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
1480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const GLint col = IFLOOR(texcoords[i][0] * width) & colMask;
1481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const GLint row = IFLOOR(texcoords[i][1] * height) & rowMask;
1482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const GLint pos = (row << shift) | col;
1483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const GLuint texel = *((GLuint *) swImg->Map + pos);
1484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba[i][RCOMP] = UBYTE_TO_FLOAT( (texel >> 24)        );
1485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba[i][GCOMP] = UBYTE_TO_FLOAT( (texel >> 16) & 0xff );
1486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba[i][BCOMP] = UBYTE_TO_FLOAT( (texel >>  8) & 0xff );
1487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba[i][ACOMP] = UBYTE_TO_FLOAT( (texel      ) & 0xff );
1488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Sample 2D texture, using lambda to choose between min/magnification */
1493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
1494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_lambda_2d(struct gl_context *ctx,
1495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const struct gl_sampler_object *samp,
1496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const struct gl_texture_object *tObj,
1497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 GLuint n, const GLfloat texcoords[][4],
1498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const GLfloat lambda[], GLfloat rgba[][4])
1499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct gl_texture_image *tImg = tObj->Image[0][tObj->BaseLevel];
1501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct swrast_texture_image *swImg = swrast_texture_image_const(tImg);
1502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint minStart, minEnd;  /* texels with minification */
1503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint magStart, magEnd;  /* texels with magnification */
1504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLboolean repeatNoBorderPOT = (samp->WrapS == GL_REPEAT)
1506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      && (samp->WrapT == GL_REPEAT)
1507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      && (tImg->Border == 0 && (tImg->Width == swImg->RowStride))
1508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      && swImg->_IsPowerOfTwo;
1509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(lambda != NULL);
1511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   compute_min_mag_ranges(samp, n, lambda,
1512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          &minStart, &minEnd, &magStart, &magEnd);
1513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (minStart < minEnd) {
1515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* do the minified texels */
1516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const GLuint m = minEnd - minStart;
1517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (samp->MinFilter) {
1518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_NEAREST:
1519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (repeatNoBorderPOT) {
1520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            switch (tImg->TexFormat) {
1521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case MESA_FORMAT_RGB888:
1522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               opt_sample_rgb_2d(ctx, samp, tObj, m, texcoords + minStart,
1523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 NULL, rgba + minStart);
1524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               break;
1525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case MESA_FORMAT_RGBA8888:
1526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       opt_sample_rgba_2d(ctx, samp, tObj, m, texcoords + minStart,
1527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  NULL, rgba + minStart);
1528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               break;
1529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            default:
1530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               sample_nearest_2d(ctx, samp, tObj, m, texcoords + minStart,
1531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 NULL, rgba + minStart );
1532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else {
1535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sample_nearest_2d(ctx, samp, tObj, m, texcoords + minStart,
1536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              NULL, rgba + minStart);
1537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_LINEAR:
1540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 sample_linear_2d(ctx, samp, tObj, m, texcoords + minStart,
1541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  NULL, rgba + minStart);
1542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_NEAREST_MIPMAP_NEAREST:
1544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_nearest_mipmap_nearest(ctx, samp, tObj, m,
1545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          texcoords + minStart,
1546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          lambda + minStart, rgba + minStart);
1547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_LINEAR_MIPMAP_NEAREST:
1549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_linear_mipmap_nearest(ctx, samp, tObj, m, texcoords + minStart,
1550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         lambda + minStart, rgba + minStart);
1551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_NEAREST_MIPMAP_LINEAR:
1553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_nearest_mipmap_linear(ctx, samp, tObj, m, texcoords + minStart,
1554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         lambda + minStart, rgba + minStart);
1555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_LINEAR_MIPMAP_LINEAR:
1557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (repeatNoBorderPOT)
1558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sample_2d_linear_mipmap_linear_repeat(ctx, samp, tObj, m,
1559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  texcoords + minStart, lambda + minStart, rgba + minStart);
1560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else
1561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sample_2d_linear_mipmap_linear(ctx, samp, tObj, m, texcoords + minStart,
1562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        lambda + minStart, rgba + minStart);
1563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
1565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_problem(ctx, "Bad min filter in sample_2d_texture");
1566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return;
1567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (magStart < magEnd) {
1571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* do the magnified texels */
1572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const GLuint m = magEnd - magStart;
1573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (samp->MagFilter) {
1575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_NEAREST:
1576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (repeatNoBorderPOT) {
1577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            switch (tImg->TexFormat) {
1578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case MESA_FORMAT_RGB888:
1579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               opt_sample_rgb_2d(ctx, samp, tObj, m, texcoords + magStart,
1580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 NULL, rgba + magStart);
1581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               break;
1582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case MESA_FORMAT_RGBA8888:
1583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       opt_sample_rgba_2d(ctx, samp, tObj, m, texcoords + magStart,
1584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  NULL, rgba + magStart);
1585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               break;
1586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            default:
1587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               sample_nearest_2d(ctx, samp, tObj, m, texcoords + magStart,
1588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 NULL, rgba + magStart );
1589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else {
1592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sample_nearest_2d(ctx, samp, tObj, m, texcoords + magStart,
1593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              NULL, rgba + magStart);
1594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_LINEAR:
1597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 sample_linear_2d(ctx, samp, tObj, m, texcoords + magStart,
1598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  NULL, rgba + magStart);
1599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
1601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_problem(ctx, "Bad mag filter in sample_lambda_2d");
1602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
1603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* For anisotropic filtering */
1609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define WEIGHT_LUT_SIZE 1024
1610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLfloat *weightLut = NULL;
1612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
1614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Creates the look-up table used to speed-up EWA sampling
1615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
1617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcreate_filter_table(void)
1618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
1620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!weightLut) {
1621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      weightLut = (GLfloat *) malloc(WEIGHT_LUT_SIZE * sizeof(GLfloat));
1622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < WEIGHT_LUT_SIZE; ++i) {
1624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         GLfloat alpha = 2;
1625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         GLfloat r2 = (GLfloat) i / (GLfloat) (WEIGHT_LUT_SIZE - 1);
1626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         GLfloat weight = (GLfloat) exp(-alpha * r2);
1627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         weightLut[i] = weight;
1628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
1634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Elliptical weighted average (EWA) filter for producing high quality
1635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * anisotropic filtered results.
1636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Based on the Higher Quality Elliptical Weighted Avarage Filter
1637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * published by Paul S. Heckbert in his Master's Thesis
1638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Fundamentals of Texture Mapping and Image Warping" (1989)
1639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
1641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_2d_ewa(struct gl_context *ctx,
1642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              const struct gl_sampler_object *samp,
1643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              const struct gl_texture_object *tObj,
1644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              const GLfloat texcoord[4],
1645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              const GLfloat dudx, const GLfloat dvdx,
1646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              const GLfloat dudy, const GLfloat dvdy, const GLint lod,
1647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              GLfloat rgba[])
1648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint level = lod > 0 ? lod : 0;
1650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat scaling = 1.0 / (1 << level);
1651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct gl_texture_image *img =	tObj->Image[0][level];
1652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct gl_texture_image *mostDetailedImage =
1653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tObj->Image[0][tObj->BaseLevel];
1654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct swrast_texture_image *swImg =
1655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swrast_texture_image_const(mostDetailedImage);
1656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat tex_u=-0.5 + texcoord[0] * swImg->WidthScale * scaling;
1657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat tex_v=-0.5 + texcoord[1] * swImg->HeightScale * scaling;
1658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat ux = dudx * scaling;
1660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat vx = dvdx * scaling;
1661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat uy = dudy * scaling;
1662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat vy = dvdy * scaling;
1663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* compute ellipse coefficients to bound the region:
1665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * A*x*x + B*x*y + C*y*y = F.
1666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat A = vx*vx+vy*vy+1;
1668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat B = -2*(ux*vx+uy*vy);
1669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat C = ux*ux+uy*uy+1;
1670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat F = A*C-B*B/4.0;
1671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* check if it is an ellipse */
1673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* ASSERT(F > 0.0); */
1674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Compute the ellipse's (u,v) bounding box in texture space */
1676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat d = -B*B+4.0*C*A;
1677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat box_u = 2.0 / d * sqrt(d*C*F); /* box_u -> half of bbox with   */
1678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat box_v = 2.0 / d * sqrt(A*d*F); /* box_v -> half of bbox height */
1679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint u0 = floor(tex_u - box_u);
1681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint u1 = ceil (tex_u + box_u);
1682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint v0 = floor(tex_v - box_v);
1683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint v1 = ceil (tex_v + box_v);
1684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat num[4] = {0.0F, 0.0F, 0.0F, 0.0F};
1686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat newCoord[2];
1687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat den = 0.0F;
1688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat ddq;
1689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat U = u0 - tex_u;
1690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint v;
1691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Scale ellipse formula to directly index the Filter Lookup Table.
1693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * i.e. scale so that F = WEIGHT_LUT_SIZE-1
1694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   double formScale = (double) (WEIGHT_LUT_SIZE - 1) / F;
1696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   A *= formScale;
1697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   B *= formScale;
1698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   C *= formScale;
1699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* F *= formScale; */ /* no need to scale F as we don't use it below here */
1700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Heckbert MS thesis, p. 59; scan over the bounding box of the ellipse
1702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * and incrementally update the value of Ax^2+Bxy*Cy^2; when this
1703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * value, q, is less than F, we're inside the ellipse
1704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ddq = 2 * A;
1706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (v = v0; v <= v1; ++v) {
1707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLfloat V = v - tex_v;
1708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLfloat dq = A * (2 * U + 1) + B * V;
1709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLfloat q = (C * V + B * U) * V + A * U * U;
1710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint u;
1712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (u = u0; u <= u1; ++u) {
1713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* Note that the ellipse has been pre-scaled so F = WEIGHT_LUT_SIZE - 1 */
1714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (q < WEIGHT_LUT_SIZE) {
1715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* as a LUT is used, q must never be negative;
1716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             * should not happen, though
1717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             */
1718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            const GLint qClamped = q >= 0.0F ? q : 0;
1719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            GLfloat weight = weightLut[qClamped];
1720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            newCoord[0] = u / ((GLfloat) img->Width2);
1722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            newCoord[1] = v / ((GLfloat) img->Height2);
1723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sample_2d_nearest(ctx, samp, img, newCoord, rgba);
1725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            num[0] += weight * rgba[0];
1726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            num[1] += weight * rgba[1];
1727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            num[2] += weight * rgba[2];
1728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            num[3] += weight * rgba[3];
1729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            den += weight;
1731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         q += dq;
1733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         dq += ddq;
1734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (den <= 0.0F) {
1738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Reaching this place would mean
1739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * that no pixels intersected the ellipse.
1740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * This should never happen because
1741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * the filter we use always
1742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * intersects at least one pixel.
1743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*rgba[0]=0;
1746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba[1]=0;
1747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba[2]=0;
1748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba[3]=0;*/
1749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* not enough pixels in resampling, resort to direct interpolation */
1750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sample_2d_linear(ctx, samp, img, texcoord, rgba);
1751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
1752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rgba[0] = num[0] / den;
1755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rgba[1] = num[1] / den;
1756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rgba[2] = num[2] / den;
1757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rgba[3] = num[3] / den;
1758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
1762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Anisotropic filtering using footprint assembly as outlined in the
1763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * EXT_texture_filter_anisotropic spec:
1764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * http://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt
1765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Faster than EWA but has less quality (more aliasing effects)
1766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
1768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_2d_footprint(struct gl_context *ctx,
1769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const struct gl_sampler_object *samp,
1770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const struct gl_texture_object *tObj,
1771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const GLfloat texcoord[4],
1772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const GLfloat dudx, const GLfloat dvdx,
1773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const GLfloat dudy, const GLfloat dvdy, const GLint lod,
1774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 GLfloat rgba[])
1775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint level = lod > 0 ? lod : 0;
1777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat scaling = 1.0F / (1 << level);
1778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct gl_texture_image *img = tObj->Image[0][level];
1779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat ux = dudx * scaling;
1781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat vx = dvdx * scaling;
1782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat uy = dudy * scaling;
1783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat vy = dvdy * scaling;
1784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat Px2 = ux * ux + vx * vx; /* squared length of dx */
1786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat Py2 = uy * uy + vy * vy; /* squared length of dy */
1787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint numSamples;
1789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat ds;
1790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat dt;
1791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat num[4] = {0.0F, 0.0F, 0.0F, 0.0F};
1793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat newCoord[2];
1794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint s;
1795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*  Calculate the per anisotropic sample offsets in s,t space. */
1797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (Px2 > Py2) {
1798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      numSamples = ceil(SQRTF(Px2));
1799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ds = ux / ((GLfloat) img->Width2);
1800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dt = vx / ((GLfloat) img->Height2);
1801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
1803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      numSamples = ceil(SQRTF(Py2));
1804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ds = uy / ((GLfloat) img->Width2);
1805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dt = vy / ((GLfloat) img->Height2);
1806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (s = 0; s<numSamples; s++) {
1809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      newCoord[0] = texcoord[0] + ds * ((GLfloat)(s+1) / (numSamples+1) -0.5);
1810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      newCoord[1] = texcoord[1] + dt * ((GLfloat)(s+1) / (numSamples+1) -0.5);
1811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sample_2d_linear(ctx, samp, img, newCoord, rgba);
1813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      num[0] += rgba[0];
1814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      num[1] += rgba[1];
1815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      num[2] += rgba[2];
1816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      num[3] += rgba[3];
1817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rgba[0] = num[0] / numSamples;
1820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rgba[1] = num[1] / numSamples;
1821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rgba[2] = num[2] / numSamples;
1822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rgba[3] = num[3] / numSamples;
1823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
1827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Returns the index of the specified texture object in the
1828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * gl_context texture unit array.
1829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline GLuint
1831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtexture_unit_index(const struct gl_context *ctx,
1832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   const struct gl_texture_object *tObj)
1833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLuint maxUnit
1835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      = (ctx->Texture._EnabledCoordUnits > 1) ? ctx->Const.MaxTextureUnits : 1;
1836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint u;
1837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* XXX CoordUnits vs. ImageUnits */
1839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (u = 0; u < maxUnit; u++) {
1840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ctx->Texture.Unit[u]._Current == tObj)
1841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break; /* found */
1842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (u >= maxUnit)
1844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      u = 0; /* not found, use 1st one; should never happen */
1845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return u;
1847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
1851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Sample 2D texture using an anisotropic filter.
1852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * NOTE: the const GLfloat lambda_iso[] parameter does *NOT* contain
1853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the lambda float array but a "hidden" SWspan struct which is required
1854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * by this function but is not available in the texture_sample_func signature.
1855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * See _swrast_texture_span( struct gl_context *ctx, SWspan *span ) on how
1856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * this function is called.
1857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
1858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
1859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_lambda_2d_aniso(struct gl_context *ctx,
1860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const struct gl_sampler_object *samp,
1861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const struct gl_texture_object *tObj,
1862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       GLuint n, const GLfloat texcoords[][4],
1863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const GLfloat lambda_iso[], GLfloat rgba[][4])
1864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct gl_texture_image *tImg = tObj->Image[0][tObj->BaseLevel];
1866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct swrast_texture_image *swImg = swrast_texture_image_const(tImg);
1867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat maxEccentricity =
1868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      samp->MaxAnisotropy * samp->MaxAnisotropy;
1869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* re-calculate the lambda values so that they are usable with anisotropic
1871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * filtering
1872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SWspan *span = (SWspan *)lambda_iso; /* access the "hidden" SWspan struct */
1874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* based on interpolate_texcoords(struct gl_context *ctx, SWspan *span)
1876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * in swrast/s_span.c
1877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* find the texture unit index by looking up the current texture object
1880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * from the context list of available texture objects.
1881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLuint u = texture_unit_index(ctx, tObj);
1883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLuint attr = FRAG_ATTRIB_TEX0 + u;
1884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat texW, texH;
1885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat dsdx = span->attrStepX[attr][0];
1887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat dsdy = span->attrStepY[attr][0];
1888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat dtdx = span->attrStepX[attr][1];
1889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat dtdy = span->attrStepY[attr][1];
1890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat dqdx = span->attrStepX[attr][3];
1891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat dqdy = span->attrStepY[attr][3];
1892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat s = span->attrStart[attr][0] + span->leftClip * dsdx;
1893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat t = span->attrStart[attr][1] + span->leftClip * dtdx;
1894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat q = span->attrStart[attr][3] + span->leftClip * dqdx;
1895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* from swrast/s_texcombine.c _swrast_texture_span */
1897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u];
1898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLboolean adjustLOD =
1899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (texUnit->LodBias + samp->LodBias != 0.0F)
1900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      || (samp->MinLod != -1000.0 || samp->MaxLod != 1000.0);
1901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
1903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* on first access create the lookup table containing the filter weights. */
1905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!weightLut) {
1906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      create_filter_table();
1907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   texW = swImg->WidthScale;
1910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   texH = swImg->HeightScale;
1911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
1913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
1914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLfloat dudx = texW * ((s + dsdx) / (q + dqdx) - s * invQ);
1916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLfloat dvdx = texH * ((t + dtdx) / (q + dqdx) - t * invQ);
1917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLfloat dudy = texW * ((s + dsdy) / (q + dqdy) - s * invQ);
1918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLfloat dvdy = texH * ((t + dtdy) / (q + dqdy) - t * invQ);
1919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* note: instead of working with Px and Py, we will use the
1921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * squared length instead, to avoid sqrt.
1922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLfloat Px2 = dudx * dudx + dvdx * dvdx;
1924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLfloat Py2 = dudy * dudy + dvdy * dvdy;
1925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLfloat Pmax2;
1927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLfloat Pmin2;
1928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLfloat e;
1929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLfloat lod;
1930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      s += dsdx;
1932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      t += dtdx;
1933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      q += dqdx;
1934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (Px2 < Py2) {
1936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         Pmax2 = Py2;
1937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         Pmin2 = Px2;
1938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
1940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         Pmax2 = Px2;
1941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         Pmin2 = Py2;
1942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* if the eccentricity of the ellipse is too big, scale up the shorter
1945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * of the two vectors to limit the maximum amount of work per pixel
1946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      e = Pmax2 / Pmin2;
1948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (e > maxEccentricity) {
1949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* GLfloat s=e / maxEccentricity;
1950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            minor[0] *= s;
1951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            minor[1] *= s;
1952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            Pmin2 *= s; */
1953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         Pmin2 = Pmax2 / maxEccentricity;
1954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* note: we need to have Pmin=sqrt(Pmin2) here, but we can avoid
1957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * this since 0.5*log(x) = log(sqrt(x))
1958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lod = 0.5 * LOG2(Pmin2);
1960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (adjustLOD) {
1962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* from swrast/s_texcombine.c _swrast_texture_span */
1963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (texUnit->LodBias + samp->LodBias != 0.0F) {
1964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* apply LOD bias, but don't clamp yet */
1965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            const GLfloat bias =
1966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               CLAMP(texUnit->LodBias + samp->LodBias,
1967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     -ctx->Const.MaxTextureLodBias,
1968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     ctx->Const.MaxTextureLodBias);
1969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            lod += bias;
1970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (samp->MinLod != -1000.0 ||
1972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                samp->MaxLod != 1000.0) {
1973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               /* apply LOD clamping to lambda */
1974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               lod = CLAMP(lod, samp->MinLod, samp->MaxLod);
1975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
1976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
1977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* If the ellipse covers the whole image, we can
1980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * simply return the average of the whole image.
1981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
1982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (lod >= tObj->_MaxLevel) {
1983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_linear(ctx, samp, tObj->Image[0][tObj->_MaxLevel],
1984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          texcoords[i], rgba[i]);
1985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
1987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* don't bother interpolating between multiple LODs; it doesn't
1988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * seem to be worth the extra running time.
1989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
1990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_ewa(ctx, samp, tObj, texcoords[i],
1991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       dudx, dvdx, dudy, dvdy, floor(lod), rgba[i]);
1992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* unused: */
1994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         (void) sample_2d_footprint;
1995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /*
1996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_footprint(ctx, tObj, texcoords[i],
1997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             dudx, dvdx, dudy, dvdy, floor(lod), rgba[i]);
1998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         */
1999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**********************************************************************/
2006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*                    3-D Texture Sampling Functions                  */
2007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**********************************************************************/
2008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
2010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter.
2011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
2012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline void
2013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_3d_nearest(struct gl_context *ctx,
2014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const struct gl_sampler_object *samp,
2015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const struct gl_texture_image *img,
2016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const GLfloat texcoord[4],
2017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  GLfloat rgba[4])
2018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
2020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint width = img->Width2;     /* without border, power of two */
2021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint height = img->Height2;   /* without border, power of two */
2022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint depth = img->Depth2;     /* without border, power of two */
2023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint i, j, k;
2024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) ctx;
2025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i = nearest_texel_location(samp->WrapS, img, width, texcoord[0]);
2027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   j = nearest_texel_location(samp->WrapT, img, height, texcoord[1]);
2028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   k = nearest_texel_location(samp->WrapR, img, depth, texcoord[2]);
2029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (i < 0 || i >= (GLint) img->Width ||
2031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       j < 0 || j >= (GLint) img->Height ||
2032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       k < 0 || k >= (GLint) img->Depth) {
2033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Need this test for GL_CLAMP_TO_BORDER mode */
2034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      get_border_color(samp, img, rgba);
2035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
2037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swImg->FetchTexel(swImg, i, j, k, rgba);
2038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
2043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter.
2044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
2045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
2046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_3d_linear(struct gl_context *ctx,
2047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const struct gl_sampler_object *samp,
2048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const struct gl_texture_image *img,
2049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const GLfloat texcoord[4],
2050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 GLfloat rgba[4])
2051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
2053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint width = img->Width2;
2054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint height = img->Height2;
2055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint depth = img->Depth2;
2056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint i0, j0, k0, i1, j1, k1;
2057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLbitfield useBorderColor = 0x0;
2058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat a, b, c;
2059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat t000[4], t010[4], t001[4], t011[4];
2060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat t100[4], t110[4], t101[4], t111[4];
2061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   linear_texel_locations(samp->WrapS, img, width, texcoord[0],  &i0, &i1, &a);
2063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   linear_texel_locations(samp->WrapT, img, height, texcoord[1], &j0, &j1, &b);
2064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   linear_texel_locations(samp->WrapR, img, depth, texcoord[2],  &k0, &k1, &c);
2065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (img->Border) {
2067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      i0 += img->Border;
2068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      i1 += img->Border;
2069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      j0 += img->Border;
2070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      j1 += img->Border;
2071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      k0 += img->Border;
2072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      k1 += img->Border;
2073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
2075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* check if sampling texture border color */
2076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (i0 < 0 || i0 >= width)   useBorderColor |= I0BIT;
2077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (i1 < 0 || i1 >= width)   useBorderColor |= I1BIT;
2078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (j0 < 0 || j0 >= height)  useBorderColor |= J0BIT;
2079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (j1 < 0 || j1 >= height)  useBorderColor |= J1BIT;
2080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (k0 < 0 || k0 >= depth)   useBorderColor |= K0BIT;
2081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (k1 < 0 || k1 >= depth)   useBorderColor |= K1BIT;
2082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Fetch texels */
2085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (useBorderColor & (I0BIT | J0BIT | K0BIT)) {
2086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      get_border_color(samp, img, t000);
2087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
2089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swImg->FetchTexel(swImg, i0, j0, k0, t000);
2090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (useBorderColor & (I1BIT | J0BIT | K0BIT)) {
2092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      get_border_color(samp, img, t100);
2093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
2095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swImg->FetchTexel(swImg, i1, j0, k0, t100);
2096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (useBorderColor & (I0BIT | J1BIT | K0BIT)) {
2098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      get_border_color(samp, img, t010);
2099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
2101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swImg->FetchTexel(swImg, i0, j1, k0, t010);
2102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (useBorderColor & (I1BIT | J1BIT | K0BIT)) {
2104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      get_border_color(samp, img, t110);
2105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
2107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swImg->FetchTexel(swImg, i1, j1, k0, t110);
2108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (useBorderColor & (I0BIT | J0BIT | K1BIT)) {
2111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      get_border_color(samp, img, t001);
2112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
2114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swImg->FetchTexel(swImg, i0, j0, k1, t001);
2115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (useBorderColor & (I1BIT | J0BIT | K1BIT)) {
2117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      get_border_color(samp, img, t101);
2118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
2120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swImg->FetchTexel(swImg, i1, j0, k1, t101);
2121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (useBorderColor & (I0BIT | J1BIT | K1BIT)) {
2123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      get_border_color(samp, img, t011);
2124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
2126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swImg->FetchTexel(swImg, i0, j1, k1, t011);
2127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (useBorderColor & (I1BIT | J1BIT | K1BIT)) {
2129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      get_border_color(samp, img, t111);
2130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
2132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swImg->FetchTexel(swImg, i1, j1, k1, t111);
2133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* trilinear interpolation of samples */
2136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lerp_rgba_3d(rgba, a, b, c, t000, t100, t010, t110, t001, t101, t011, t111);
2137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
2141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_3d_nearest_mipmap_nearest(struct gl_context *ctx,
2142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 const struct gl_sampler_object *samp,
2143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 const struct gl_texture_object *tObj,
2144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 GLuint n, const GLfloat texcoord[][4],
2145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 const GLfloat lambda[], GLfloat rgba[][4] )
2146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
2148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
2149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint level = nearest_mipmap_level(tObj, lambda[i]);
2150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sample_3d_nearest(ctx, samp, tObj->Image[0][level], texcoord[i], rgba[i]);
2151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
2156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_3d_linear_mipmap_nearest(struct gl_context *ctx,
2157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                const struct gl_sampler_object *samp,
2158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                const struct gl_texture_object *tObj,
2159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                GLuint n, const GLfloat texcoord[][4],
2160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                const GLfloat lambda[], GLfloat rgba[][4])
2161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
2163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(lambda != NULL);
2164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
2165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint level = nearest_mipmap_level(tObj, lambda[i]);
2166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sample_3d_linear(ctx, samp, tObj->Image[0][level], texcoord[i], rgba[i]);
2167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
2172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_3d_nearest_mipmap_linear(struct gl_context *ctx,
2173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                const struct gl_sampler_object *samp,
2174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                const struct gl_texture_object *tObj,
2175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                GLuint n, const GLfloat texcoord[][4],
2176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                const GLfloat lambda[], GLfloat rgba[][4])
2177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
2179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(lambda != NULL);
2180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
2181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint level = linear_mipmap_level(tObj, lambda[i]);
2182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (level >= tObj->_MaxLevel) {
2183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_3d_nearest(ctx, samp, tObj->Image[0][tObj->_MaxLevel],
2184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           texcoord[i], rgba[i]);
2185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
2187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         GLfloat t0[4], t1[4];  /* texels */
2188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat f = FRAC(lambda[i]);
2189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_3d_nearest(ctx, samp, tObj->Image[0][level  ], texcoord[i], t0);
2190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_3d_nearest(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1);
2191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lerp_rgba(rgba[i], f, t0, t1);
2192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
2198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_3d_linear_mipmap_linear(struct gl_context *ctx,
2199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               const struct gl_sampler_object *samp,
2200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               const struct gl_texture_object *tObj,
2201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               GLuint n, const GLfloat texcoord[][4],
2202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               const GLfloat lambda[], GLfloat rgba[][4])
2203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
2205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(lambda != NULL);
2206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
2207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint level = linear_mipmap_level(tObj, lambda[i]);
2208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (level >= tObj->_MaxLevel) {
2209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_3d_linear(ctx, samp, tObj->Image[0][tObj->_MaxLevel],
2210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          texcoord[i], rgba[i]);
2211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
2213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         GLfloat t0[4], t1[4];  /* texels */
2214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat f = FRAC(lambda[i]);
2215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_3d_linear(ctx, samp, tObj->Image[0][level  ], texcoord[i], t0);
2216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_3d_linear(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1);
2217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lerp_rgba(rgba[i], f, t0, t1);
2218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Sample 3D texture, nearest filtering for both min/magnification */
2224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
2225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_nearest_3d(struct gl_context *ctx,
2226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const struct gl_sampler_object *samp,
2227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const struct gl_texture_object *tObj, GLuint n,
2228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const GLfloat texcoords[][4], const GLfloat lambda[],
2229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  GLfloat rgba[][4])
2230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
2232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
2233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) lambda;
2234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
2235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sample_3d_nearest(ctx, samp, image, texcoords[i], rgba[i]);
2236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Sample 3D texture, linear filtering for both min/magnification */
2241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
2242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_linear_3d(struct gl_context *ctx,
2243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const struct gl_sampler_object *samp,
2244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const struct gl_texture_object *tObj, GLuint n,
2245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const GLfloat texcoords[][4],
2246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 const GLfloat lambda[], GLfloat rgba[][4])
2247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
2249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
2250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) lambda;
2251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
2252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sample_3d_linear(ctx, samp, image, texcoords[i], rgba[i]);
2253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Sample 3D texture, using lambda to choose between min/magnification */
2258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
2259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_lambda_3d(struct gl_context *ctx,
2260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const struct gl_sampler_object *samp,
2261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const struct gl_texture_object *tObj, GLuint n,
2262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const GLfloat texcoords[][4], const GLfloat lambda[],
2263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 GLfloat rgba[][4])
2264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint minStart, minEnd;  /* texels with minification */
2266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint magStart, magEnd;  /* texels with magnification */
2267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
2268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(lambda != NULL);
2270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   compute_min_mag_ranges(samp, n, lambda,
2271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          &minStart, &minEnd, &magStart, &magEnd);
2272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (minStart < minEnd) {
2274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* do the minified texels */
2275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLuint m = minEnd - minStart;
2276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (samp->MinFilter) {
2277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_NEAREST:
2278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = minStart; i < minEnd; i++)
2279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sample_3d_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel],
2280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              texcoords[i], rgba[i]);
2281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
2282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_LINEAR:
2283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = minStart; i < minEnd; i++)
2284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sample_3d_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel],
2285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             texcoords[i], rgba[i]);
2286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
2287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_NEAREST_MIPMAP_NEAREST:
2288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_3d_nearest_mipmap_nearest(ctx, samp, tObj, m, texcoords + minStart,
2289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          lambda + minStart, rgba + minStart);
2290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
2291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_LINEAR_MIPMAP_NEAREST:
2292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_3d_linear_mipmap_nearest(ctx, samp, tObj, m, texcoords + minStart,
2293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         lambda + minStart, rgba + minStart);
2294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
2295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_NEAREST_MIPMAP_LINEAR:
2296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_3d_nearest_mipmap_linear(ctx, samp, tObj, m, texcoords + minStart,
2297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         lambda + minStart, rgba + minStart);
2298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
2299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_LINEAR_MIPMAP_LINEAR:
2300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_3d_linear_mipmap_linear(ctx, samp, tObj, m, texcoords + minStart,
2301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        lambda + minStart, rgba + minStart);
2302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
2303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
2304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_problem(ctx, "Bad min filter in sample_3d_texture");
2305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return;
2306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (magStart < magEnd) {
2310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* do the magnified texels */
2311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (samp->MagFilter) {
2312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_NEAREST:
2313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = magStart; i < magEnd; i++)
2314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sample_3d_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel],
2315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              texcoords[i], rgba[i]);
2316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
2317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_LINEAR:
2318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = magStart; i < magEnd; i++)
2319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sample_3d_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel],
2320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             texcoords[i], rgba[i]);
2321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
2322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
2323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_problem(ctx, "Bad mag filter in sample_3d_texture");
2324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return;
2325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**********************************************************************/
2331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*                Texture Cube Map Sampling Functions                 */
2332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**********************************************************************/
2333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
2335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Choose one of six sides of a texture cube map given the texture
2336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * coord (rx,ry,rz).  Return pointer to corresponding array of texture
2337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * images.
2338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
2339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct gl_texture_image **
2340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgchoose_cube_face(const struct gl_texture_object *texObj,
2341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 const GLfloat texcoord[4], GLfloat newCoord[4])
2342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
2344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      major axis
2345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      direction     target                             sc     tc    ma
2346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ----------    -------------------------------    ---    ---   ---
2347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       +rx          TEXTURE_CUBE_MAP_POSITIVE_X_EXT    -rz    -ry   rx
2348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       -rx          TEXTURE_CUBE_MAP_NEGATIVE_X_EXT    +rz    -ry   rx
2349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       +ry          TEXTURE_CUBE_MAP_POSITIVE_Y_EXT    +rx    +rz   ry
2350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       -ry          TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT    +rx    -rz   ry
2351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       +rz          TEXTURE_CUBE_MAP_POSITIVE_Z_EXT    +rx    -ry   rz
2352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       -rz          TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT    -rx    -ry   rz
2353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   */
2354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat rx = texcoord[0];
2355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat ry = texcoord[1];
2356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat rz = texcoord[2];
2357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat arx = FABSF(rx), ary = FABSF(ry), arz = FABSF(rz);
2358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint face;
2359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat sc, tc, ma;
2360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (arx >= ary && arx >= arz) {
2362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (rx >= 0.0F) {
2363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         face = FACE_POS_X;
2364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sc = -rz;
2365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         tc = -ry;
2366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ma = arx;
2367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
2369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         face = FACE_NEG_X;
2370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sc = rz;
2371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         tc = -ry;
2372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ma = arx;
2373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (ary >= arx && ary >= arz) {
2376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ry >= 0.0F) {
2377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         face = FACE_POS_Y;
2378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sc = rx;
2379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         tc = rz;
2380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ma = ary;
2381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
2383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         face = FACE_NEG_Y;
2384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sc = rx;
2385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         tc = -rz;
2386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ma = ary;
2387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
2390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (rz > 0.0F) {
2391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         face = FACE_POS_Z;
2392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sc = rx;
2393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         tc = -ry;
2394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ma = arz;
2395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
2397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         face = FACE_NEG_Z;
2398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sc = -rx;
2399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         tc = -ry;
2400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ma = arz;
2401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
2405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const float ima = 1.0F / ma;
2406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      newCoord[0] = ( sc * ima + 1.0F ) * 0.5F;
2407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      newCoord[1] = ( tc * ima + 1.0F ) * 0.5F;
2408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (const struct gl_texture_image **) texObj->Image[face];
2411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
2415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_nearest_cube(struct gl_context *ctx,
2416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    const struct gl_sampler_object *samp,
2417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    const struct gl_texture_object *tObj, GLuint n,
2418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    const GLfloat texcoords[][4], const GLfloat lambda[],
2419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    GLfloat rgba[][4])
2420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
2422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) lambda;
2423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
2424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const struct gl_texture_image **images;
2425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLfloat newCoord[4];
2426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      images = choose_cube_face(tObj, texcoords[i], newCoord);
2427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sample_2d_nearest(ctx, samp, images[tObj->BaseLevel],
2428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        newCoord, rgba[i]);
2429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (is_depth_texture(tObj)) {
2431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < n; i++) {
2432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         apply_depth_mode(tObj->DepthMode, rgba[i][0], rgba[i]);
2433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
2439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_linear_cube(struct gl_context *ctx,
2440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   const struct gl_sampler_object *samp,
2441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   const struct gl_texture_object *tObj, GLuint n,
2442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   const GLfloat texcoords[][4],
2443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   const GLfloat lambda[], GLfloat rgba[][4])
2444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
2446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) lambda;
2447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
2448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const struct gl_texture_image **images;
2449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLfloat newCoord[4];
2450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      images = choose_cube_face(tObj, texcoords[i], newCoord);
2451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sample_2d_linear(ctx, samp, images[tObj->BaseLevel],
2452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       newCoord, rgba[i]);
2453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (is_depth_texture(tObj)) {
2455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < n; i++) {
2456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         apply_depth_mode(tObj->DepthMode, rgba[i][0], rgba[i]);
2457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
2463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_cube_nearest_mipmap_nearest(struct gl_context *ctx,
2464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   const struct gl_sampler_object *samp,
2465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   const struct gl_texture_object *tObj,
2466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   GLuint n, const GLfloat texcoord[][4],
2467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   const GLfloat lambda[], GLfloat rgba[][4])
2468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
2470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(lambda != NULL);
2471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
2472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const struct gl_texture_image **images;
2473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLfloat newCoord[4];
2474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint level;
2475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      images = choose_cube_face(tObj, texcoord[i], newCoord);
2476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* XXX we actually need to recompute lambda here based on the newCoords.
2478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * But we would need the texcoords of adjacent fragments to compute that
2479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * properly, and we don't have those here.
2480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * For now, do an approximation:  subtracting 1 from the chosen mipmap
2481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * level seems to work in some test cases.
2482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * The same adjustment is done in the next few functions.
2483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      */
2484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      level = nearest_mipmap_level(tObj, lambda[i]);
2485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      level = MAX2(level - 1, 0);
2486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sample_2d_nearest(ctx, samp, images[level], newCoord, rgba[i]);
2488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (is_depth_texture(tObj)) {
2490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < n; i++) {
2491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         apply_depth_mode(tObj->DepthMode, rgba[i][0], rgba[i]);
2492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
2498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_cube_linear_mipmap_nearest(struct gl_context *ctx,
2499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  const struct gl_sampler_object *samp,
2500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  const struct gl_texture_object *tObj,
2501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  GLuint n, const GLfloat texcoord[][4],
2502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  const GLfloat lambda[], GLfloat rgba[][4])
2503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
2505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(lambda != NULL);
2506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
2507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const struct gl_texture_image **images;
2508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLfloat newCoord[4];
2509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint level = nearest_mipmap_level(tObj, lambda[i]);
2510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      level = MAX2(level - 1, 0); /* see comment above */
2511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      images = choose_cube_face(tObj, texcoord[i], newCoord);
2512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sample_2d_linear(ctx, samp, images[level], newCoord, rgba[i]);
2513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (is_depth_texture(tObj)) {
2515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < n; i++) {
2516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         apply_depth_mode(tObj->DepthMode, rgba[i][0], rgba[i]);
2517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
2523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_cube_nearest_mipmap_linear(struct gl_context *ctx,
2524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  const struct gl_sampler_object *samp,
2525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  const struct gl_texture_object *tObj,
2526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  GLuint n, const GLfloat texcoord[][4],
2527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  const GLfloat lambda[], GLfloat rgba[][4])
2528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
2530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(lambda != NULL);
2531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
2532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const struct gl_texture_image **images;
2533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLfloat newCoord[4];
2534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint level = linear_mipmap_level(tObj, lambda[i]);
2535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      level = MAX2(level - 1, 0); /* see comment above */
2536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      images = choose_cube_face(tObj, texcoord[i], newCoord);
2537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (level >= tObj->_MaxLevel) {
2538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_nearest(ctx, samp, images[tObj->_MaxLevel],
2539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           newCoord, rgba[i]);
2540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
2542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         GLfloat t0[4], t1[4];  /* texels */
2543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat f = FRAC(lambda[i]);
2544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_nearest(ctx, samp, images[level  ], newCoord, t0);
2545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_nearest(ctx, samp, images[level+1], newCoord, t1);
2546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lerp_rgba(rgba[i], f, t0, t1);
2547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (is_depth_texture(tObj)) {
2550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < n; i++) {
2551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         apply_depth_mode(tObj->DepthMode, rgba[i][0], rgba[i]);
2552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
2558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_cube_linear_mipmap_linear(struct gl_context *ctx,
2559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 const struct gl_sampler_object *samp,
2560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 const struct gl_texture_object *tObj,
2561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 GLuint n, const GLfloat texcoord[][4],
2562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 const GLfloat lambda[], GLfloat rgba[][4])
2563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
2565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(lambda != NULL);
2566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
2567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const struct gl_texture_image **images;
2568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLfloat newCoord[4];
2569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint level = linear_mipmap_level(tObj, lambda[i]);
2570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      level = MAX2(level - 1, 0); /* see comment above */
2571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      images = choose_cube_face(tObj, texcoord[i], newCoord);
2572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (level >= tObj->_MaxLevel) {
2573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_linear(ctx, samp, images[tObj->_MaxLevel],
2574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          newCoord, rgba[i]);
2575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
2577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         GLfloat t0[4], t1[4];
2578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat f = FRAC(lambda[i]);
2579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_linear(ctx, samp, images[level  ], newCoord, t0);
2580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_linear(ctx, samp, images[level+1], newCoord, t1);
2581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lerp_rgba(rgba[i], f, t0, t1);
2582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (is_depth_texture(tObj)) {
2585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < n; i++) {
2586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         apply_depth_mode(tObj->DepthMode, rgba[i][0], rgba[i]);
2587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Sample cube texture, using lambda to choose between min/magnification */
2593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
2594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_lambda_cube(struct gl_context *ctx,
2595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   const struct gl_sampler_object *samp,
2596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   const struct gl_texture_object *tObj, GLuint n,
2597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   const GLfloat texcoords[][4], const GLfloat lambda[],
2598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   GLfloat rgba[][4])
2599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint minStart, minEnd;  /* texels with minification */
2601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint magStart, magEnd;  /* texels with magnification */
2602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(lambda != NULL);
2604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   compute_min_mag_ranges(samp, n, lambda,
2605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          &minStart, &minEnd, &magStart, &magEnd);
2606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (minStart < minEnd) {
2608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* do the minified texels */
2609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const GLuint m = minEnd - minStart;
2610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (samp->MinFilter) {
2611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_NEAREST:
2612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_nearest_cube(ctx, samp, tObj, m, texcoords + minStart,
2613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             lambda + minStart, rgba + minStart);
2614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
2615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_LINEAR:
2616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_linear_cube(ctx, samp, tObj, m, texcoords + minStart,
2617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            lambda + minStart, rgba + minStart);
2618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
2619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_NEAREST_MIPMAP_NEAREST:
2620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_cube_nearest_mipmap_nearest(ctx, samp, tObj, m,
2621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                            texcoords + minStart,
2622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           lambda + minStart, rgba + minStart);
2623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
2624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_LINEAR_MIPMAP_NEAREST:
2625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_cube_linear_mipmap_nearest(ctx, samp, tObj, m,
2626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           texcoords + minStart,
2627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           lambda + minStart, rgba + minStart);
2628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
2629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_NEAREST_MIPMAP_LINEAR:
2630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_cube_nearest_mipmap_linear(ctx, samp, tObj, m,
2631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           texcoords + minStart,
2632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           lambda + minStart, rgba + minStart);
2633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
2634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_LINEAR_MIPMAP_LINEAR:
2635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_cube_linear_mipmap_linear(ctx, samp, tObj, m,
2636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          texcoords + minStart,
2637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          lambda + minStart, rgba + minStart);
2638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
2639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
2640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_problem(ctx, "Bad min filter in sample_lambda_cube");
2641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
2642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (magStart < magEnd) {
2646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* do the magnified texels */
2647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const GLuint m = magEnd - magStart;
2648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (samp->MagFilter) {
2649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_NEAREST:
2650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_nearest_cube(ctx, samp, tObj, m, texcoords + magStart,
2651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             lambda + magStart, rgba + magStart);
2652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
2653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_LINEAR:
2654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_linear_cube(ctx, samp, tObj, m, texcoords + magStart,
2655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            lambda + magStart, rgba + magStart);
2656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
2657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
2658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_problem(ctx, "Bad mag filter in sample_lambda_cube");
2659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
2660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**********************************************************************/
2666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*               Texture Rectangle Sampling Functions                 */
2667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**********************************************************************/
2668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
2671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_nearest_rect(struct gl_context *ctx,
2672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    const struct gl_sampler_object *samp,
2673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    const struct gl_texture_object *tObj, GLuint n,
2674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    const GLfloat texcoords[][4], const GLfloat lambda[],
2675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    GLfloat rgba[][4])
2676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct gl_texture_image *img = tObj->Image[0][0];
2678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
2679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint width = img->Width;
2680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint height = img->Height;
2681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
2682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) ctx;
2684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) lambda;
2685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(samp->WrapS == GL_CLAMP ||
2687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          samp->WrapS == GL_CLAMP_TO_EDGE ||
2688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          samp->WrapS == GL_CLAMP_TO_BORDER);
2689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(samp->WrapT == GL_CLAMP ||
2690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          samp->WrapT == GL_CLAMP_TO_EDGE ||
2691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          samp->WrapT == GL_CLAMP_TO_BORDER);
2692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
2694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint row, col;
2695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      col = clamp_rect_coord_nearest(samp->WrapS, texcoords[i][0], width);
2696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      row = clamp_rect_coord_nearest(samp->WrapT, texcoords[i][1], height);
2697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (col < 0 || col >= width || row < 0 || row >= height)
2698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         get_border_color(samp, img, rgba[i]);
2699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
2700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         swImg->FetchTexel(swImg, col, row, 0, rgba[i]);
2701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
2706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_linear_rect(struct gl_context *ctx,
2707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   const struct gl_sampler_object *samp,
2708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   const struct gl_texture_object *tObj, GLuint n,
2709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   const GLfloat texcoords[][4],
2710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   const GLfloat lambda[], GLfloat rgba[][4])
2711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct gl_texture_image *img = tObj->Image[0][0];
2713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
2714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint width = img->Width;
2715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint height = img->Height;
2716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
2717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) ctx;
2719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) lambda;
2720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(samp->WrapS == GL_CLAMP ||
2722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          samp->WrapS == GL_CLAMP_TO_EDGE ||
2723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          samp->WrapS == GL_CLAMP_TO_BORDER);
2724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(samp->WrapT == GL_CLAMP ||
2725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          samp->WrapT == GL_CLAMP_TO_EDGE ||
2726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          samp->WrapT == GL_CLAMP_TO_BORDER);
2727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
2729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint i0, j0, i1, j1;
2730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLfloat t00[4], t01[4], t10[4], t11[4];
2731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLfloat a, b;
2732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLbitfield useBorderColor = 0x0;
2733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      clamp_rect_coord_linear(samp->WrapS, texcoords[i][0], width,
2735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              &i0, &i1, &a);
2736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      clamp_rect_coord_linear(samp->WrapT, texcoords[i][1], height,
2737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              &j0, &j1, &b);
2738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* compute integer rows/columns */
2740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (i0 < 0 || i0 >= width)   useBorderColor |= I0BIT;
2741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (i1 < 0 || i1 >= width)   useBorderColor |= I1BIT;
2742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (j0 < 0 || j0 >= height)  useBorderColor |= J0BIT;
2743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (j1 < 0 || j1 >= height)  useBorderColor |= J1BIT;
2744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* get four texel samples */
2746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (useBorderColor & (I0BIT | J0BIT))
2747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         get_border_color(samp, img, t00);
2748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
2749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         swImg->FetchTexel(swImg, i0, j0, 0, t00);
2750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (useBorderColor & (I1BIT | J0BIT))
2752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         get_border_color(samp, img, t10);
2753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
2754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         swImg->FetchTexel(swImg, i1, j0, 0, t10);
2755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (useBorderColor & (I0BIT | J1BIT))
2757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         get_border_color(samp, img, t01);
2758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
2759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         swImg->FetchTexel(swImg, i0, j1, 0, t01);
2760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (useBorderColor & (I1BIT | J1BIT))
2762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         get_border_color(samp, img, t11);
2763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
2764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         swImg->FetchTexel(swImg, i1, j1, 0, t11);
2765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lerp_rgba_2d(rgba[i], a, b, t00, t10, t01, t11);
2767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Sample Rect texture, using lambda to choose between min/magnification */
2772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
2773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_lambda_rect(struct gl_context *ctx,
2774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   const struct gl_sampler_object *samp,
2775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   const struct gl_texture_object *tObj, GLuint n,
2776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   const GLfloat texcoords[][4], const GLfloat lambda[],
2777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   GLfloat rgba[][4])
2778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint minStart, minEnd, magStart, magEnd;
2780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* We only need lambda to decide between minification and magnification.
2782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * There is no mipmapping with rectangular textures.
2783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
2784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   compute_min_mag_ranges(samp, n, lambda,
2785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          &minStart, &minEnd, &magStart, &magEnd);
2786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (minStart < minEnd) {
2788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (samp->MinFilter == GL_NEAREST) {
2789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_nearest_rect(ctx, samp, tObj, minEnd - minStart,
2790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             texcoords + minStart, NULL, rgba + minStart);
2791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
2793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_linear_rect(ctx, samp, tObj, minEnd - minStart,
2794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            texcoords + minStart, NULL, rgba + minStart);
2795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (magStart < magEnd) {
2798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (samp->MagFilter == GL_NEAREST) {
2799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_nearest_rect(ctx, samp, tObj, magEnd - magStart,
2800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             texcoords + magStart, NULL, rgba + magStart);
2801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
2803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_linear_rect(ctx, samp, tObj, magEnd - magStart,
2804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            texcoords + magStart, NULL, rgba + magStart);
2805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**********************************************************************/
2811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*                2D Texture Array Sampling Functions                 */
2812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**********************************************************************/
2813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
2815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter.
2816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
2817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
2818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_2d_array_nearest(struct gl_context *ctx,
2819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct gl_sampler_object *samp,
2820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct gl_texture_image *img,
2821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const GLfloat texcoord[4],
2822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        GLfloat rgba[4])
2823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
2825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint width = img->Width2;     /* without border, power of two */
2826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint height = img->Height2;   /* without border, power of two */
2827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint depth = img->Depth;
2828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint i, j;
2829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint array;
2830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) ctx;
2831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i = nearest_texel_location(samp->WrapS, img, width, texcoord[0]);
2833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   j = nearest_texel_location(samp->WrapT, img, height, texcoord[1]);
2834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   array = tex_array_slice(texcoord[2], depth);
2835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (i < 0 || i >= (GLint) img->Width ||
2837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       j < 0 || j >= (GLint) img->Height ||
2838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       array < 0 || array >= (GLint) img->Depth) {
2839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Need this test for GL_CLAMP_TO_BORDER mode */
2840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      get_border_color(samp, img, rgba);
2841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
2843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swImg->FetchTexel(swImg, i, j, array, rgba);
2844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
2849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter.
2850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
2851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
2852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_2d_array_linear(struct gl_context *ctx,
2853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const struct gl_sampler_object *samp,
2854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const struct gl_texture_image *img,
2855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const GLfloat texcoord[4],
2856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       GLfloat rgba[4])
2857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
2859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint width = img->Width2;
2860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint height = img->Height2;
2861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint depth = img->Depth;
2862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint i0, j0, i1, j1;
2863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint array;
2864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLbitfield useBorderColor = 0x0;
2865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat a, b;
2866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat t00[4], t01[4], t10[4], t11[4];
2867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   linear_texel_locations(samp->WrapS, img, width,  texcoord[0], &i0, &i1, &a);
2869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   linear_texel_locations(samp->WrapT, img, height, texcoord[1], &j0, &j1, &b);
2870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   array = tex_array_slice(texcoord[2], depth);
2871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (array < 0 || array >= depth) {
2873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      COPY_4V(rgba, samp->BorderColor.f);
2874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
2876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (img->Border) {
2877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 i0 += img->Border;
2878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 i1 += img->Border;
2879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 j0 += img->Border;
2880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 j1 += img->Border;
2881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
2883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* check if sampling texture border color */
2884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (i0 < 0 || i0 >= width)   useBorderColor |= I0BIT;
2885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (i1 < 0 || i1 >= width)   useBorderColor |= I1BIT;
2886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (j0 < 0 || j0 >= height)  useBorderColor |= J0BIT;
2887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (j1 < 0 || j1 >= height)  useBorderColor |= J1BIT;
2888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Fetch texels */
2891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (useBorderColor & (I0BIT | J0BIT)) {
2892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         get_border_color(samp, img, t00);
2893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
2895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 swImg->FetchTexel(swImg, i0, j0, array, t00);
2896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (useBorderColor & (I1BIT | J0BIT)) {
2898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         get_border_color(samp, img, t10);
2899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
2901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 swImg->FetchTexel(swImg, i1, j0, array, t10);
2902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (useBorderColor & (I0BIT | J1BIT)) {
2904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         get_border_color(samp, img, t01);
2905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
2907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 swImg->FetchTexel(swImg, i0, j1, array, t01);
2908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (useBorderColor & (I1BIT | J1BIT)) {
2910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         get_border_color(samp, img, t11);
2911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
2913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 swImg->FetchTexel(swImg, i1, j1, array, t11);
2914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* trilinear interpolation of samples */
2917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lerp_rgba_2d(rgba, a, b, t00, t10, t01, t11);
2918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
2923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_2d_array_nearest_mipmap_nearest(struct gl_context *ctx,
2924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       const struct gl_sampler_object *samp,
2925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       const struct gl_texture_object *tObj,
2926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       GLuint n, const GLfloat texcoord[][4],
2927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       const GLfloat lambda[], GLfloat rgba[][4])
2928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
2930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
2931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint level = nearest_mipmap_level(tObj, lambda[i]);
2932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sample_2d_array_nearest(ctx, samp, tObj->Image[0][level], texcoord[i],
2933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              rgba[i]);
2934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
2939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_2d_array_linear_mipmap_nearest(struct gl_context *ctx,
2940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      const struct gl_sampler_object *samp,
2941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      const struct gl_texture_object *tObj,
2942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      GLuint n, const GLfloat texcoord[][4],
2943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      const GLfloat lambda[], GLfloat rgba[][4])
2944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
2946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(lambda != NULL);
2947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
2948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint level = nearest_mipmap_level(tObj, lambda[i]);
2949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sample_2d_array_linear(ctx, samp, tObj->Image[0][level],
2950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             texcoord[i], rgba[i]);
2951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
2956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_2d_array_nearest_mipmap_linear(struct gl_context *ctx,
2957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      const struct gl_sampler_object *samp,
2958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      const struct gl_texture_object *tObj,
2959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      GLuint n, const GLfloat texcoord[][4],
2960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      const GLfloat lambda[], GLfloat rgba[][4])
2961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
2963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(lambda != NULL);
2964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
2965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint level = linear_mipmap_level(tObj, lambda[i]);
2966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (level >= tObj->_MaxLevel) {
2967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_array_nearest(ctx, samp, tObj->Image[0][tObj->_MaxLevel],
2968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 texcoord[i], rgba[i]);
2969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
2971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         GLfloat t0[4], t1[4];  /* texels */
2972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat f = FRAC(lambda[i]);
2973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_array_nearest(ctx, samp, tObj->Image[0][level  ],
2974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 texcoord[i], t0);
2975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_array_nearest(ctx, samp, tObj->Image[0][level+1],
2976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 texcoord[i], t1);
2977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lerp_rgba(rgba[i], f, t0, t1);
2978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
2980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
2984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_2d_array_linear_mipmap_linear(struct gl_context *ctx,
2985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     const struct gl_sampler_object *samp,
2986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     const struct gl_texture_object *tObj,
2987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     GLuint n, const GLfloat texcoord[][4],
2988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     const GLfloat lambda[], GLfloat rgba[][4])
2989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
2991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(lambda != NULL);
2992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
2993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint level = linear_mipmap_level(tObj, lambda[i]);
2994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (level >= tObj->_MaxLevel) {
2995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_array_linear(ctx, samp, tObj->Image[0][tObj->_MaxLevel],
2996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          texcoord[i], rgba[i]);
2997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
2999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         GLfloat t0[4], t1[4];  /* texels */
3000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat f = FRAC(lambda[i]);
3001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_array_linear(ctx, samp, tObj->Image[0][level  ],
3002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                texcoord[i], t0);
3003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_array_linear(ctx, samp, tObj->Image[0][level+1],
3004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                texcoord[i], t1);
3005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lerp_rgba(rgba[i], f, t0, t1);
3006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Sample 2D Array texture, nearest filtering for both min/magnification */
3012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
3013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_nearest_2d_array(struct gl_context *ctx,
3014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct gl_sampler_object *samp,
3015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct gl_texture_object *tObj, GLuint n,
3016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const GLfloat texcoords[][4], const GLfloat lambda[],
3017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        GLfloat rgba[][4])
3018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
3020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
3021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) lambda;
3022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
3023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sample_2d_array_nearest(ctx, samp, image, texcoords[i], rgba[i]);
3024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Sample 2D Array texture, linear filtering for both min/magnification */
3030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
3031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_linear_2d_array(struct gl_context *ctx,
3032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const struct gl_sampler_object *samp,
3033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const struct gl_texture_object *tObj, GLuint n,
3034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const GLfloat texcoords[][4],
3035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const GLfloat lambda[], GLfloat rgba[][4])
3036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
3038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
3039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) lambda;
3040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
3041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sample_2d_array_linear(ctx, samp, image, texcoords[i], rgba[i]);
3042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Sample 2D Array texture, using lambda to choose between min/magnification */
3047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
3048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_lambda_2d_array(struct gl_context *ctx,
3049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const struct gl_sampler_object *samp,
3050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const struct gl_texture_object *tObj, GLuint n,
3051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const GLfloat texcoords[][4], const GLfloat lambda[],
3052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       GLfloat rgba[][4])
3053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint minStart, minEnd;  /* texels with minification */
3055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint magStart, magEnd;  /* texels with magnification */
3056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
3057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(lambda != NULL);
3059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   compute_min_mag_ranges(samp, n, lambda,
3060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          &minStart, &minEnd, &magStart, &magEnd);
3061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (minStart < minEnd) {
3063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* do the minified texels */
3064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLuint m = minEnd - minStart;
3065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (samp->MinFilter) {
3066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_NEAREST:
3067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = minStart; i < minEnd; i++)
3068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sample_2d_array_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel],
3069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    texcoords[i], rgba[i]);
3070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_LINEAR:
3072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = minStart; i < minEnd; i++)
3073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sample_2d_array_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel],
3074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   texcoords[i], rgba[i]);
3075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_NEAREST_MIPMAP_NEAREST:
3077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_array_nearest_mipmap_nearest(ctx, samp, tObj, m,
3078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                texcoords + minStart,
3079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                lambda + minStart,
3080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                rgba + minStart);
3081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_LINEAR_MIPMAP_NEAREST:
3083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_array_linear_mipmap_nearest(ctx, samp, tObj, m,
3084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               texcoords + minStart,
3085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               lambda + minStart,
3086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               rgba + minStart);
3087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_NEAREST_MIPMAP_LINEAR:
3089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_array_nearest_mipmap_linear(ctx, samp, tObj, m,
3090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               texcoords + minStart,
3091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               lambda + minStart,
3092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               rgba + minStart);
3093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_LINEAR_MIPMAP_LINEAR:
3095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_2d_array_linear_mipmap_linear(ctx, samp, tObj, m,
3096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              texcoords + minStart,
3097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              lambda + minStart,
3098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              rgba + minStart);
3099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
3101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_problem(ctx, "Bad min filter in sample_2d_array_texture");
3102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return;
3103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (magStart < magEnd) {
3107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* do the magnified texels */
3108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (samp->MagFilter) {
3109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_NEAREST:
3110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = magStart; i < magEnd; i++)
3111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sample_2d_array_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel],
3112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              texcoords[i], rgba[i]);
3113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_LINEAR:
3115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = magStart; i < magEnd; i++)
3116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sample_2d_array_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel],
3117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   texcoords[i], rgba[i]);
3118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
3120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_problem(ctx, "Bad mag filter in sample_2d_array_texture");
3121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return;
3122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**********************************************************************/
3130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*                1D Texture Array Sampling Functions                 */
3131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**********************************************************************/
3132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
3134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter.
3135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
3136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
3137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_1d_array_nearest(struct gl_context *ctx,
3138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct gl_sampler_object *samp,
3139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct gl_texture_image *img,
3140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const GLfloat texcoord[4],
3141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        GLfloat rgba[4])
3142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
3144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint width = img->Width2;     /* without border, power of two */
3145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint height = img->Height;
3146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint i;
3147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint array;
3148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) ctx;
3149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   i = nearest_texel_location(samp->WrapS, img, width, texcoord[0]);
3151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   array = tex_array_slice(texcoord[1], height);
3152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (i < 0 || i >= (GLint) img->Width ||
3154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       array < 0 || array >= (GLint) img->Height) {
3155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Need this test for GL_CLAMP_TO_BORDER mode */
3156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      get_border_color(samp, img, rgba);
3157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
3159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swImg->FetchTexel(swImg, i, array, 0, rgba);
3160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
3165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter.
3166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
3167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
3168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_1d_array_linear(struct gl_context *ctx,
3169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const struct gl_sampler_object *samp,
3170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const struct gl_texture_image *img,
3171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const GLfloat texcoord[4],
3172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       GLfloat rgba[4])
3173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
3175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint width = img->Width2;
3176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint height = img->Height;
3177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint i0, i1;
3178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint array;
3179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLbitfield useBorderColor = 0x0;
3180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat a;
3181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat t0[4], t1[4];
3182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   linear_texel_locations(samp->WrapS, img, width, texcoord[0], &i0, &i1, &a);
3184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   array = tex_array_slice(texcoord[1], height);
3185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (img->Border) {
3187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      i0 += img->Border;
3188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      i1 += img->Border;
3189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
3191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* check if sampling texture border color */
3192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (i0 < 0 || i0 >= width)   useBorderColor |= I0BIT;
3193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (i1 < 0 || i1 >= width)   useBorderColor |= I1BIT;
3194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (array < 0 || array >= height)   useBorderColor |= K0BIT;
3197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Fetch texels */
3199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (useBorderColor & (I0BIT | K0BIT)) {
3200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      get_border_color(samp, img, t0);
3201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
3203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swImg->FetchTexel(swImg, i0, array, 0, t0);
3204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (useBorderColor & (I1BIT | K0BIT)) {
3206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      get_border_color(samp, img, t1);
3207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
3209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swImg->FetchTexel(swImg, i1, array, 0, t1);
3210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* bilinear interpolation of samples */
3213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lerp_rgba(rgba, a, t0, t1);
3214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
3218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_1d_array_nearest_mipmap_nearest(struct gl_context *ctx,
3219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       const struct gl_sampler_object *samp,
3220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       const struct gl_texture_object *tObj,
3221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       GLuint n, const GLfloat texcoord[][4],
3222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       const GLfloat lambda[], GLfloat rgba[][4])
3223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
3225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
3226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint level = nearest_mipmap_level(tObj, lambda[i]);
3227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sample_1d_array_nearest(ctx, samp, tObj->Image[0][level], texcoord[i],
3228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              rgba[i]);
3229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
3234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_1d_array_linear_mipmap_nearest(struct gl_context *ctx,
3235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      const struct gl_sampler_object *samp,
3236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      const struct gl_texture_object *tObj,
3237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      GLuint n, const GLfloat texcoord[][4],
3238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      const GLfloat lambda[], GLfloat rgba[][4])
3239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
3241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(lambda != NULL);
3242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
3243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint level = nearest_mipmap_level(tObj, lambda[i]);
3244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sample_1d_array_linear(ctx, samp, tObj->Image[0][level],
3245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             texcoord[i], rgba[i]);
3246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
3251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_1d_array_nearest_mipmap_linear(struct gl_context *ctx,
3252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      const struct gl_sampler_object *samp,
3253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      const struct gl_texture_object *tObj,
3254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      GLuint n, const GLfloat texcoord[][4],
3255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      const GLfloat lambda[], GLfloat rgba[][4])
3256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
3258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(lambda != NULL);
3259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
3260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint level = linear_mipmap_level(tObj, lambda[i]);
3261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (level >= tObj->_MaxLevel) {
3262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_1d_array_nearest(ctx, samp, tObj->Image[0][tObj->_MaxLevel],
3263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 texcoord[i], rgba[i]);
3264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
3266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         GLfloat t0[4], t1[4];  /* texels */
3267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat f = FRAC(lambda[i]);
3268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_1d_array_nearest(ctx, samp, tObj->Image[0][level  ], texcoord[i], t0);
3269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_1d_array_nearest(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1);
3270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lerp_rgba(rgba[i], f, t0, t1);
3271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
3277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_1d_array_linear_mipmap_linear(struct gl_context *ctx,
3278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     const struct gl_sampler_object *samp,
3279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     const struct gl_texture_object *tObj,
3280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     GLuint n, const GLfloat texcoord[][4],
3281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     const GLfloat lambda[], GLfloat rgba[][4])
3282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
3284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(lambda != NULL);
3285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
3286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLint level = linear_mipmap_level(tObj, lambda[i]);
3287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (level >= tObj->_MaxLevel) {
3288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_1d_array_linear(ctx, samp, tObj->Image[0][tObj->_MaxLevel],
3289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          texcoord[i], rgba[i]);
3290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
3292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         GLfloat t0[4], t1[4];  /* texels */
3293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfloat f = FRAC(lambda[i]);
3294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_1d_array_linear(ctx, samp, tObj->Image[0][level  ], texcoord[i], t0);
3295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_1d_array_linear(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1);
3296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         lerp_rgba(rgba[i], f, t0, t1);
3297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Sample 1D Array texture, nearest filtering for both min/magnification */
3303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
3304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_nearest_1d_array(struct gl_context *ctx,
3305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct gl_sampler_object *samp,
3306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct gl_texture_object *tObj, GLuint n,
3307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const GLfloat texcoords[][4], const GLfloat lambda[],
3308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        GLfloat rgba[][4])
3309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
3311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
3312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) lambda;
3313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
3314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sample_1d_array_nearest(ctx, samp, image, texcoords[i], rgba[i]);
3315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Sample 1D Array texture, linear filtering for both min/magnification */
3320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
3321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_linear_1d_array(struct gl_context *ctx,
3322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const struct gl_sampler_object *samp,
3323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const struct gl_texture_object *tObj, GLuint n,
3324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const GLfloat texcoords[][4],
3325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const GLfloat lambda[], GLfloat rgba[][4])
3326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
3328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
3329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) lambda;
3330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
3331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sample_1d_array_linear(ctx, samp, image, texcoords[i], rgba[i]);
3332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Sample 1D Array texture, using lambda to choose between min/magnification */
3337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
3338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_lambda_1d_array(struct gl_context *ctx,
3339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const struct gl_sampler_object *samp,
3340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const struct gl_texture_object *tObj, GLuint n,
3341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const GLfloat texcoords[][4], const GLfloat lambda[],
3342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       GLfloat rgba[][4])
3343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint minStart, minEnd;  /* texels with minification */
3345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint magStart, magEnd;  /* texels with magnification */
3346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
3347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(lambda != NULL);
3349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   compute_min_mag_ranges(samp, n, lambda,
3350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          &minStart, &minEnd, &magStart, &magEnd);
3351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (minStart < minEnd) {
3353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* do the minified texels */
3354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLuint m = minEnd - minStart;
3355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (samp->MinFilter) {
3356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_NEAREST:
3357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = minStart; i < minEnd; i++)
3358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sample_1d_array_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel],
3359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    texcoords[i], rgba[i]);
3360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_LINEAR:
3362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = minStart; i < minEnd; i++)
3363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sample_1d_array_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel],
3364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   texcoords[i], rgba[i]);
3365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_NEAREST_MIPMAP_NEAREST:
3367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_1d_array_nearest_mipmap_nearest(ctx, samp, tObj, m, texcoords + minStart,
3368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                lambda + minStart, rgba + minStart);
3369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_LINEAR_MIPMAP_NEAREST:
3371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_1d_array_linear_mipmap_nearest(ctx, samp, tObj, m,
3372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               texcoords + minStart,
3373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               lambda + minStart,
3374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               rgba + minStart);
3375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_NEAREST_MIPMAP_LINEAR:
3377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_1d_array_nearest_mipmap_linear(ctx, samp, tObj, m, texcoords + minStart,
3378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               lambda + minStart, rgba + minStart);
3379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_LINEAR_MIPMAP_LINEAR:
3381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sample_1d_array_linear_mipmap_linear(ctx, samp, tObj, m,
3382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              texcoords + minStart,
3383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              lambda + minStart,
3384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              rgba + minStart);
3385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
3387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_problem(ctx, "Bad min filter in sample_1d_array_texture");
3388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return;
3389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (magStart < magEnd) {
3393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* do the magnified texels */
3394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (samp->MagFilter) {
3395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_NEAREST:
3396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = magStart; i < magEnd; i++)
3397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sample_1d_array_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel],
3398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              texcoords[i], rgba[i]);
3399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_LINEAR:
3401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = magStart; i < magEnd; i++)
3402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sample_1d_array_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel],
3403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   texcoords[i], rgba[i]);
3404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
3405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
3406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_problem(ctx, "Bad mag filter in sample_1d_array_texture");
3407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return;
3408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
3414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Compare texcoord against depth sample.  Return 1.0 or 0.0 value.
3415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
3416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline GLfloat
3417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgshadow_compare(GLenum function, GLfloat coord, GLfloat depthSample)
3418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (function) {
3420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_LEQUAL:
3421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (coord <= depthSample) ? 1.0F : 0.0F;
3422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_GEQUAL:
3423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (coord >= depthSample) ? 1.0F : 0.0F;
3424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_LESS:
3425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (coord < depthSample) ? 1.0F : 0.0F;
3426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_GREATER:
3427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (coord > depthSample) ? 1.0F : 0.0F;
3428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_EQUAL:
3429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (coord == depthSample) ? 1.0F : 0.0F;
3430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_NOTEQUAL:
3431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return (coord != depthSample) ? 1.0F : 0.0F;
3432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_ALWAYS:
3433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 1.0F;
3434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_NEVER:
3435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 0.0F;
3436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_NONE:
3437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return depthSample;
3438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
3439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_problem(NULL, "Bad compare func in shadow_compare");
3440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 0.0F;
3441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
3446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Compare texcoord against four depth samples.
3447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
3448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline GLfloat
3449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgshadow_compare4(GLenum function, GLfloat coord,
3450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                GLfloat depth00, GLfloat depth01,
3451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                GLfloat depth10, GLfloat depth11,
3452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                GLfloat wi, GLfloat wj)
3453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat d = 0.25F;
3455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat luminance = 1.0F;
3456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (function) {
3458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_LEQUAL:
3459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (coord > depth00)  luminance -= d;
3460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (coord > depth01)  luminance -= d;
3461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (coord > depth10)  luminance -= d;
3462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (coord > depth11)  luminance -= d;
3463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return luminance;
3464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_GEQUAL:
3465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (coord < depth00)  luminance -= d;
3466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (coord < depth01)  luminance -= d;
3467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (coord < depth10)  luminance -= d;
3468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (coord < depth11)  luminance -= d;
3469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return luminance;
3470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_LESS:
3471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (coord >= depth00)  luminance -= d;
3472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (coord >= depth01)  luminance -= d;
3473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (coord >= depth10)  luminance -= d;
3474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (coord >= depth11)  luminance -= d;
3475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return luminance;
3476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_GREATER:
3477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (coord <= depth00)  luminance -= d;
3478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (coord <= depth01)  luminance -= d;
3479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (coord <= depth10)  luminance -= d;
3480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (coord <= depth11)  luminance -= d;
3481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return luminance;
3482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_EQUAL:
3483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (coord != depth00)  luminance -= d;
3484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (coord != depth01)  luminance -= d;
3485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (coord != depth10)  luminance -= d;
3486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (coord != depth11)  luminance -= d;
3487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return luminance;
3488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_NOTEQUAL:
3489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (coord == depth00)  luminance -= d;
3490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (coord == depth01)  luminance -= d;
3491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (coord == depth10)  luminance -= d;
3492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (coord == depth11)  luminance -= d;
3493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return luminance;
3494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_ALWAYS:
3495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 1.0F;
3496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_NEVER:
3497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 0.0F;
3498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_NONE:
3499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* ordinary bilinear filtering */
3500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return lerp_2d(wi, wj, depth00, depth10, depth01, depth11);
3501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
3502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_problem(NULL, "Bad compare func in sample_compare4");
3503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 0.0F;
3504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
3509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Choose the mipmap level to use when sampling from a depth texture.
3510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
3511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int
3512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgchoose_depth_texture_level(const struct gl_sampler_object *samp,
3513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           const struct gl_texture_object *tObj, GLfloat lambda)
3514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint level;
3516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (samp->MinFilter == GL_NEAREST || samp->MinFilter == GL_LINEAR) {
3518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* no mipmapping - use base level */
3519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      level = tObj->BaseLevel;
3520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
3522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* choose mipmap level */
3523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lambda = CLAMP(lambda, samp->MinLod, samp->MaxLod);
3524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      level = (GLint) lambda;
3525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      level = CLAMP(level, tObj->BaseLevel, tObj->_MaxLevel);
3526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return level;
3529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
3533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Sample a shadow/depth texture.  This function is incomplete.  It doesn't
3534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * check for minification vs. magnification, etc.
3535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
3536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
3537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsample_depth_texture( struct gl_context *ctx,
3538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      const struct gl_sampler_object *samp,
3539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      const struct gl_texture_object *tObj, GLuint n,
3540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      const GLfloat texcoords[][4], const GLfloat lambda[],
3541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      GLfloat texel[][4] )
3542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint level = choose_depth_texture_level(samp, tObj, lambda[0]);
3544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct gl_texture_image *img = tObj->Image[0][level];
3545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct swrast_texture_image *swImg = swrast_texture_image_const(img);
3546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint width = img->Width;
3547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint height = img->Height;
3548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint depth = img->Depth;
3549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLuint compare_coord = (tObj->Target == GL_TEXTURE_2D_ARRAY_EXT)
3550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       ? 3 : 2;
3551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLenum function;
3552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat result;
3553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(img->_BaseFormat == GL_DEPTH_COMPONENT ||
3555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          img->_BaseFormat == GL_DEPTH_STENCIL_EXT);
3556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(tObj->Target == GL_TEXTURE_1D ||
3558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          tObj->Target == GL_TEXTURE_2D ||
3559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          tObj->Target == GL_TEXTURE_RECTANGLE_NV ||
3560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          tObj->Target == GL_TEXTURE_1D_ARRAY_EXT ||
3561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          tObj->Target == GL_TEXTURE_2D_ARRAY_EXT ||
3562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          tObj->Target == GL_TEXTURE_CUBE_MAP);
3563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* XXXX if samp->MinFilter != samp->MagFilter, we're ignoring lambda */
3565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   function = (samp->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) ?
3567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      samp->CompareFunc : GL_NONE;
3568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (samp->MagFilter == GL_NEAREST) {
3570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLuint i;
3571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < n; i++) {
3572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         GLfloat depthSample, depthRef;
3573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         GLint col, row, slice;
3574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         nearest_texcoord(samp, tObj, level, texcoords[i], &col, &row, &slice);
3576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (col >= 0 && row >= 0 && col < width && row < height &&
3578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             slice >= 0 && slice < depth) {
3579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            swImg->FetchTexel(swImg, col, row, slice, &depthSample);
3580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else {
3582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            depthSample = samp->BorderColor.f[0];
3583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         depthRef = CLAMP(texcoords[i][compare_coord], 0.0F, 1.0F);
3586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         result = shadow_compare(function, depthRef, depthSample);
3588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         apply_depth_mode(tObj->DepthMode, result, texel[i]);
3590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
3593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLuint i;
3594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ASSERT(samp->MagFilter == GL_LINEAR);
3595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < n; i++) {
3596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         GLfloat depth00, depth01, depth10, depth11, depthRef;
3597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         GLint i0, i1, j0, j1;
3598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         GLint slice;
3599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         GLfloat wi, wj;
3600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         GLuint useBorderTexel;
3601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         linear_texcoord(samp, tObj, level, texcoords[i], &i0, &i1, &j0, &j1, &slice,
3603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         &wi, &wj);
3604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         useBorderTexel = 0;
3606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (img->Border) {
3607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            i0 += img->Border;
3608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            i1 += img->Border;
3609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (tObj->Target != GL_TEXTURE_1D_ARRAY_EXT) {
3610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               j0 += img->Border;
3611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               j1 += img->Border;
3612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
3613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else {
3615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (i0 < 0 || i0 >= (GLint) width)   useBorderTexel |= I0BIT;
3616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (i1 < 0 || i1 >= (GLint) width)   useBorderTexel |= I1BIT;
3617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (j0 < 0 || j0 >= (GLint) height)  useBorderTexel |= J0BIT;
3618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (j1 < 0 || j1 >= (GLint) height)  useBorderTexel |= J1BIT;
3619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (slice < 0 || slice >= (GLint) depth) {
3622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            depth00 = samp->BorderColor.f[0];
3623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            depth01 = samp->BorderColor.f[0];
3624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            depth10 = samp->BorderColor.f[0];
3625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            depth11 = samp->BorderColor.f[0];
3626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else {
3628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* get four depth samples from the texture */
3629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (useBorderTexel & (I0BIT | J0BIT)) {
3630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               depth00 = samp->BorderColor.f[0];
3631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
3632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            else {
3633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               swImg->FetchTexel(swImg, i0, j0, slice, &depth00);
3634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
3635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (useBorderTexel & (I1BIT | J0BIT)) {
3636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               depth10 = samp->BorderColor.f[0];
3637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
3638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            else {
3639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               swImg->FetchTexel(swImg, i1, j0, slice, &depth10);
3640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
3641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (tObj->Target != GL_TEXTURE_1D_ARRAY_EXT) {
3643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               if (useBorderTexel & (I0BIT | J1BIT)) {
3644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  depth01 = samp->BorderColor.f[0];
3645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               }
3646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               else {
3647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  swImg->FetchTexel(swImg, i0, j1, slice, &depth01);
3648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               }
3649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               if (useBorderTexel & (I1BIT | J1BIT)) {
3650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  depth11 = samp->BorderColor.f[0];
3651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               }
3652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               else {
3653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  swImg->FetchTexel(swImg, i1, j1, slice, &depth11);
3654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               }
3655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
3656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            else {
3657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               depth01 = depth00;
3658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               depth11 = depth10;
3659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
3660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         depthRef = CLAMP(texcoords[i][compare_coord], 0.0F, 1.0F);
3663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         result = shadow_compare4(function, depthRef,
3665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  depth00, depth01, depth10, depth11,
3666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  wi, wj);
3667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         apply_depth_mode(tObj->DepthMode, result, texel[i]);
3669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }  /* for */
3670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }  /* if filter */
3671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
3675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * We use this function when a texture object is in an "incomplete" state.
3676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * When a fragment program attempts to sample an incomplete texture we
3677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * return black (see issue 23 in GL_ARB_fragment_program spec).
3678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Note: fragment programs don't observe the texture enable/disable flags.
3679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
3680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
3681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnull_sample_func( struct gl_context *ctx,
3682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const struct gl_sampler_object *samp,
3683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  const struct gl_texture_object *tObj, GLuint n,
3684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  const GLfloat texcoords[][4], const GLfloat lambda[],
3685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  GLfloat rgba[][4])
3686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
3688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) ctx;
3689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) tObj;
3690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) texcoords;
3691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) lambda;
3692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) samp;
3693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < n; i++) {
3694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba[i][RCOMP] = 0;
3695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba[i][GCOMP] = 0;
3696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba[i][BCOMP] = 0;
3697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgba[i][ACOMP] = 1.0;
3698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
3703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Choose the texture sampling function for the given texture object.
3704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
3705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtexture_sample_func
3706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_swrast_choose_texture_sample_func( struct gl_context *ctx,
3707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				    const struct gl_texture_object *t,
3708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    const struct gl_sampler_object *sampler)
3709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
3710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!t || !_mesa_is_texture_complete(t, sampler)) {
3711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return &null_sample_func;
3712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
3714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const GLboolean needLambda =
3715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         (GLboolean) (sampler->MinFilter != sampler->MagFilter);
3716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (t->Target) {
3718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_TEXTURE_1D:
3719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (is_depth_texture(t)) {
3720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return &sample_depth_texture;
3721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else if (needLambda) {
3723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return &sample_lambda_1d;
3724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else if (sampler->MinFilter == GL_LINEAR) {
3726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return &sample_linear_1d;
3727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else {
3729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            ASSERT(sampler->MinFilter == GL_NEAREST);
3730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return &sample_nearest_1d;
3731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_TEXTURE_2D:
3733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (is_depth_texture(t)) {
3734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return &sample_depth_texture;
3735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else if (needLambda) {
3737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* Anisotropic filtering extension. Activated only if mipmaps are used */
3738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (sampler->MaxAnisotropy > 1.0 &&
3739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                sampler->MinFilter == GL_LINEAR_MIPMAP_LINEAR) {
3740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               return &sample_lambda_2d_aniso;
3741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
3742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return &sample_lambda_2d;
3743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else if (sampler->MinFilter == GL_LINEAR) {
3745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return &sample_linear_2d;
3746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else {
3748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* check for a few optimized cases */
3749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            const struct gl_texture_image *img = t->Image[0][t->BaseLevel];
3750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            const struct swrast_texture_image *swImg =
3751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               swrast_texture_image_const(img);
3752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            texture_sample_func func;
3753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            ASSERT(sampler->MinFilter == GL_NEAREST);
3755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            func = &sample_nearest_2d;
3756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (sampler->WrapS == GL_REPEAT &&
3757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                sampler->WrapT == GL_REPEAT &&
3758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                swImg->_IsPowerOfTwo &&
3759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                img->Border == 0) {
3760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               if (img->TexFormat == MESA_FORMAT_RGB888)
3761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  func = &opt_sample_rgb_2d;
3762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               else if (img->TexFormat == MESA_FORMAT_RGBA8888)
3763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  func = &opt_sample_rgba_2d;
3764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
3765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return func;
3767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_TEXTURE_3D:
3769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (needLambda) {
3770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return &sample_lambda_3d;
3771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else if (sampler->MinFilter == GL_LINEAR) {
3773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return &sample_linear_3d;
3774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else {
3776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            ASSERT(sampler->MinFilter == GL_NEAREST);
3777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return &sample_nearest_3d;
3778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_TEXTURE_CUBE_MAP:
3780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (needLambda) {
3781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return &sample_lambda_cube;
3782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else if (sampler->MinFilter == GL_LINEAR) {
3784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return &sample_linear_cube;
3785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else {
3787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            ASSERT(sampler->MinFilter == GL_NEAREST);
3788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return &sample_nearest_cube;
3789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_TEXTURE_RECTANGLE_NV:
3791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (is_depth_texture(t)) {
3792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return &sample_depth_texture;
3793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else if (needLambda) {
3795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return &sample_lambda_rect;
3796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else if (sampler->MinFilter == GL_LINEAR) {
3798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return &sample_linear_rect;
3799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else {
3801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            ASSERT(sampler->MinFilter == GL_NEAREST);
3802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return &sample_nearest_rect;
3803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_TEXTURE_1D_ARRAY_EXT:
3805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (is_depth_texture(t)) {
3806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return &sample_depth_texture;
3807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 else if (needLambda) {
3809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return &sample_lambda_1d_array;
3810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else if (sampler->MinFilter == GL_LINEAR) {
3812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return &sample_linear_1d_array;
3813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else {
3815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            ASSERT(sampler->MinFilter == GL_NEAREST);
3816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return &sample_nearest_1d_array;
3817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_TEXTURE_2D_ARRAY_EXT:
3819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (is_depth_texture(t)) {
3820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return &sample_depth_texture;
3821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 else if (needLambda) {
3823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return &sample_lambda_2d_array;
3824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else if (sampler->MinFilter == GL_LINEAR) {
3826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return &sample_linear_2d_array;
3827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else {
3829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            ASSERT(sampler->MinFilter == GL_NEAREST);
3830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return &sample_nearest_2d_array;
3831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
3832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
3833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _mesa_problem(ctx,
3834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       "invalid target in _swrast_choose_texture_sample_func");
3835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return &null_sample_func;
3836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
3837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
3838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3839