10dc4eea64f56cc93e5359372b08b99a2d600273cBrian/**************************************************************************
20dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
30dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
40dc4eea64f56cc93e5359372b08b99a2d600273cBrian * All Rights Reserved.
54bfe1c955fe679547c8a03119d1681e33593c768Michal Krol * Copyright 2008-2010 VMware, Inc.  All rights reserved.
60dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
70dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Permission is hereby granted, free of charge, to any person obtaining a
80dc4eea64f56cc93e5359372b08b99a2d600273cBrian * copy of this software and associated documentation files (the
90dc4eea64f56cc93e5359372b08b99a2d600273cBrian * "Software"), to deal in the Software without restriction, including
100dc4eea64f56cc93e5359372b08b99a2d600273cBrian * without limitation the rights to use, copy, modify, merge, publish,
110dc4eea64f56cc93e5359372b08b99a2d600273cBrian * distribute, sub license, and/or sell copies of the Software, and to
120dc4eea64f56cc93e5359372b08b99a2d600273cBrian * permit persons to whom the Software is furnished to do so, subject to
130dc4eea64f56cc93e5359372b08b99a2d600273cBrian * the following conditions:
140dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
150dc4eea64f56cc93e5359372b08b99a2d600273cBrian * The above copyright notice and this permission notice (including the
160dc4eea64f56cc93e5359372b08b99a2d600273cBrian * next paragraph) shall be included in all copies or substantial portions
170dc4eea64f56cc93e5359372b08b99a2d600273cBrian * of the Software.
180dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
190dc4eea64f56cc93e5359372b08b99a2d600273cBrian * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
200dc4eea64f56cc93e5359372b08b99a2d600273cBrian * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
210dc4eea64f56cc93e5359372b08b99a2d600273cBrian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
220dc4eea64f56cc93e5359372b08b99a2d600273cBrian * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
230dc4eea64f56cc93e5359372b08b99a2d600273cBrian * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
240dc4eea64f56cc93e5359372b08b99a2d600273cBrian * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
250dc4eea64f56cc93e5359372b08b99a2d600273cBrian * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
260dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
270dc4eea64f56cc93e5359372b08b99a2d600273cBrian **************************************************************************/
280dc4eea64f56cc93e5359372b08b99a2d600273cBrian
290dc4eea64f56cc93e5359372b08b99a2d600273cBrian/**
300dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Texture sampling
310dc4eea64f56cc93e5359372b08b99a2d600273cBrian *
320dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Authors:
330dc4eea64f56cc93e5359372b08b99a2d600273cBrian *   Brian Paul
344fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell *   Keith Whitwell
350dc4eea64f56cc93e5359372b08b99a2d600273cBrian */
360dc4eea64f56cc93e5359372b08b99a2d600273cBrian
370dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "pipe/p_context.h"
380dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "pipe/p_defines.h"
3900c835918259f8d41c3f74eca679a972713b11b2Keith Whitwell#include "pipe/p_shader_tokens.h"
401a46dcc8a927dfb38ca1381e7b3dafb789f8257cBrian Paul#include "util/u_math.h"
414f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h"
42d204659c8c725c02212ad4a49275c7447f2d02a6Brian Paul#include "sp_quad.h"   /* only for #define QUAD_* tokens */
43d204659c8c725c02212ad4a49275c7447f2d02a6Brian Paul#include "sp_tex_sample.h"
447670102468a55de50cf0cfa0b938d36aaf212f1fKeith Whitwell#include "sp_tex_tile_cache.h"
450dc4eea64f56cc93e5359372b08b99a2d600273cBrian
460dc4eea64f56cc93e5359372b08b99a2d600273cBrian
474250882ccf8326ba9074c671110370534489caa6Brian Paul/** Set to one to help debug texture sampling */
484250882ccf8326ba9074c671110370534489caa6Brian Paul#define DEBUG_TEX 0
494250882ccf8326ba9074c671110370534489caa6Brian Paul
503ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul
5108f33a025100dea2d951e6d628891fe294b18082Brian/*
52b4a40d10524a4be6a59805589ee4209ebdb1de4fBrian Paul * Return fractional part of 'f'.  Used for computing interpolation weights.
53b4a40d10524a4be6a59805589ee4209ebdb1de4fBrian Paul * Need to be careful with negative values.
54b4a40d10524a4be6a59805589ee4209ebdb1de4fBrian Paul * Note, if this function isn't perfect you'll sometimes see 1-pixel bands
55b4a40d10524a4be6a59805589ee4209ebdb1de4fBrian Paul * of improperly weighted linear-filtered textures.
5608f33a025100dea2d951e6d628891fe294b18082Brian * The tests/texwrap.c demo is a good test.
5708f33a025100dea2d951e6d628891fe294b18082Brian */
58b4a40d10524a4be6a59805589ee4209ebdb1de4fBrian Paulstatic INLINE float
59b4a40d10524a4be6a59805589ee4209ebdb1de4fBrian Paulfrac(float f)
60b4a40d10524a4be6a59805589ee4209ebdb1de4fBrian Paul{
61b37c54150058c07ab2d3db2d7e5891a457b51e76Brian Paul   return f - floorf(f);
62b4a40d10524a4be6a59805589ee4209ebdb1de4fBrian Paul}
63b4a40d10524a4be6a59805589ee4209ebdb1de4fBrian Paul
6408f33a025100dea2d951e6d628891fe294b18082Brian
6508f33a025100dea2d951e6d628891fe294b18082Brian
6608f33a025100dea2d951e6d628891fe294b18082Brian/**
6708f33a025100dea2d951e6d628891fe294b18082Brian * Linear interpolation macro
6808f33a025100dea2d951e6d628891fe294b18082Brian */
6938bee46e83b18ff4ad42d340b507b1a15b4326c7Brianstatic INLINE float
7038bee46e83b18ff4ad42d340b507b1a15b4326c7Brianlerp(float a, float v0, float v1)
7138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian{
7238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   return v0 + a * (v1 - v0);
7338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian}
740dc4eea64f56cc93e5359372b08b99a2d600273cBrian
750dc4eea64f56cc93e5359372b08b99a2d600273cBrian
760dc4eea64f56cc93e5359372b08b99a2d600273cBrian/**
77fd60bf8e33bbcba7b7749ae5a4285bad60769b9bBrian Paul * Do 2D/bilinear interpolation of float values.
780dc4eea64f56cc93e5359372b08b99a2d600273cBrian * v00, v10, v01 and v11 are typically four texture samples in a square/box.
790dc4eea64f56cc93e5359372b08b99a2d600273cBrian * a and b are the horizontal and vertical interpolants.
800dc4eea64f56cc93e5359372b08b99a2d600273cBrian * It's important that this function is inlined when compiled with
810dc4eea64f56cc93e5359372b08b99a2d600273cBrian * optimization!  If we find that's not true on some systems, convert
820dc4eea64f56cc93e5359372b08b99a2d600273cBrian * to a macro.
830dc4eea64f56cc93e5359372b08b99a2d600273cBrian */
84b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic INLINE float
85b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianlerp_2d(float a, float b,
86b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian        float v00, float v10, float v01, float v11)
870dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
8838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   const float temp0 = lerp(a, v00, v10);
8938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   const float temp1 = lerp(a, v01, v11);
9038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   return lerp(b, temp0, temp1);
9138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian}
9238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
9338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
9438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian/**
9538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * As above, but 3D interpolation of 8 values.
9638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian */
9738bee46e83b18ff4ad42d340b507b1a15b4326c7Brianstatic INLINE float
9838bee46e83b18ff4ad42d340b507b1a15b4326c7Brianlerp_3d(float a, float b, float c,
9938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian        float v000, float v100, float v010, float v110,
10038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian        float v001, float v101, float v011, float v111)
10138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian{
10238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   const float temp0 = lerp_2d(a, b, v000, v100, v010, v110);
10338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   const float temp1 = lerp_2d(a, b, v001, v101, v011, v111);
10438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian   return lerp(c, temp0, temp1);
1050dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
1060dc4eea64f56cc93e5359372b08b99a2d600273cBrian
1070dc4eea64f56cc93e5359372b08b99a2d600273cBrian
10838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
1090dc4eea64f56cc93e5359372b08b99a2d600273cBrian/**
110b4a40d10524a4be6a59805589ee4209ebdb1de4fBrian Paul * Compute coord % size for repeat wrap modes.
111e31f0f996537046228602a251706613ca4163209Brian Paul * Note that if coord is negative, coord % size doesn't give the right
112e31f0f996537046228602a251706613ca4163209Brian Paul * value.  To avoid that problem we add a large multiple of the size
113e31f0f996537046228602a251706613ca4163209Brian Paul * (rather than using a conditional).
1140dc4eea64f56cc93e5359372b08b99a2d600273cBrian */
115b4a40d10524a4be6a59805589ee4209ebdb1de4fBrian Paulstatic INLINE int
116b4a40d10524a4be6a59805589ee4209ebdb1de4fBrian Paulrepeat(int coord, unsigned size)
117b4a40d10524a4be6a59805589ee4209ebdb1de4fBrian Paul{
118e31f0f996537046228602a251706613ca4163209Brian Paul   return (coord + size * 1024) % size;
119b4a40d10524a4be6a59805589ee4209ebdb1de4fBrian Paul}
12008f33a025100dea2d951e6d628891fe294b18082Brian
12108f33a025100dea2d951e6d628891fe294b18082Brian
12208f33a025100dea2d951e6d628891fe294b18082Brian/**
12338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * Apply texture coord wrapping mode and return integer texture indexes
12438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * for a vector of four texcoords (S or T or P).
12508f33a025100dea2d951e6d628891fe294b18082Brian * \param wrapMode  PIPE_TEX_WRAP_x
12638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param s  the incoming texcoords
12708f33a025100dea2d951e6d628891fe294b18082Brian * \param size  the texture image size
12838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param icoord  returns the integer texcoords
12908f33a025100dea2d951e6d628891fe294b18082Brian * \return  integer texture index
13008f33a025100dea2d951e6d628891fe294b18082Brian */
1314fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
132229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertwrap_nearest_repeat(float s, unsigned size, int *icoord)
1334fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
1344fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* s limited to [0,1) */
1354fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* i limited to [0,size-1] */
136229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int i = util_ifloor(s * size);
137229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord = repeat(i, size);
1384fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
1394fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1404fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1414fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
142229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertwrap_nearest_clamp(float s, unsigned size, int *icoord)
1430dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
1444fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* s limited to [0,1] */
1454fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* i limited to [0,size-1] */
146229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (s <= 0.0F)
147229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = 0;
148229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else if (s >= 1.0F)
149229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = size - 1;
150229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else
151229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = util_ifloor(s * size);
1524fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
1534fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1544fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1554fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
156229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertwrap_nearest_clamp_to_edge(float s, unsigned size, int *icoord)
1574fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
1584fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* s limited to [min,max] */
1594fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* i limited to [0, size-1] */
1604fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float min = 1.0F / (2.0F * size);
1614fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float max = 1.0F - min;
162229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (s < min)
163229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = 0;
164229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else if (s > max)
165229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = size - 1;
166229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else
167229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = util_ifloor(s * size);
1684fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
1694fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1704fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1714fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
172229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertwrap_nearest_clamp_to_border(float s, unsigned size, int *icoord)
1734fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
1744fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* s limited to [min,max] */
1754fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* i limited to [-1, size] */
1764fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float min = -1.0F / (2.0F * size);
1774fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float max = 1.0F - min;
178229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (s <= min)
179229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = -1;
180229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else if (s >= max)
181229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = size;
182229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else
183229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = util_ifloor(s * size);
1844fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
1854fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
186e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
1874fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
188229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertwrap_nearest_mirror_repeat(float s, unsigned size, int *icoord)
1894fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
1904fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float min = 1.0F / (2.0F * size);
1914fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float max = 1.0F - min;
192229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const int flr = util_ifloor(s);
193229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float u = frac(s);
194229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (flr & 1)
195229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      u = 1.0F - u;
196229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (u < min)
197229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = 0;
198229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else if (u > max)
199229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = size - 1;
200229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else
201229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = util_ifloor(u * size);
2024fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
2034fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
204e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
2054fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
206229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertwrap_nearest_mirror_clamp(float s, unsigned size, int *icoord)
207229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
208229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   /* s limited to [0,1] */
209229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   /* i limited to [0,size-1] */
210229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float u = fabsf(s);
211229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (u <= 0.0F)
212229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = 0;
213229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else if (u >= 1.0F)
214229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = size - 1;
215229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else
216229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = util_ifloor(u * size);
2174fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
2184fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
219e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
2204fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
221229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertwrap_nearest_mirror_clamp_to_edge(float s, unsigned size, int *icoord)
2224fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
2234fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* s limited to [min,max] */
2244fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* i limited to [0, size-1] */
2254fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float min = 1.0F / (2.0F * size);
2264fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float max = 1.0F - min;
227229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float u = fabsf(s);
228229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (u < min)
229229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = 0;
230229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else if (u > max)
231229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = size - 1;
232229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else
233229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = util_ifloor(u * size);
2344fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
2354fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
2364fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
2374fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
238229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertwrap_nearest_mirror_clamp_to_border(float s, unsigned size, int *icoord)
2394fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
2404fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* s limited to [min,max] */
2414fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* i limited to [0, size-1] */
2424fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float min = -1.0F / (2.0F * size);
2434fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float max = 1.0F - min;
244229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float u = fabsf(s);
245229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (u < min)
246229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = -1;
247229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else if (u > max)
248229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = size;
249229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else
250229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = util_ifloor(u * size);
2510dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
2520dc4eea64f56cc93e5359372b08b99a2d600273cBrian
25308f33a025100dea2d951e6d628891fe294b18082Brian
25408f33a025100dea2d951e6d628891fe294b18082Brian/**
255229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert * Used to compute texel locations for linear sampling
25608f33a025100dea2d951e6d628891fe294b18082Brian * \param wrapMode  PIPE_TEX_WRAP_x
257229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert * \param s  the texcoord
25808f33a025100dea2d951e6d628891fe294b18082Brian * \param size  the texture image size
259229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert * \param icoord0  returns first texture index
260229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert * \param icoord1  returns second texture index (usually icoord0 + 1)
261229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert * \param w  returns blend factor/weight between texture indices
262229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert * \param icoord  returns the computed integer texture coord
26308f33a025100dea2d951e6d628891fe294b18082Brian */
2644fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
265229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertwrap_linear_repeat(float s, unsigned size,
266229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                   int *icoord0, int *icoord1, float *w)
267229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
268229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float u = s * size - 0.5F;
269229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = repeat(util_ifloor(u), size);
270229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = repeat(*icoord0 + 1, size);
271229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
2724fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
2734fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
274e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
2754fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
276229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertwrap_linear_clamp(float s, unsigned size,
277229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                  int *icoord0, int *icoord1, float *w)
278229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
279229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float u = CLAMP(s, 0.0F, 1.0F);
280229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   u = u * size - 0.5f;
281229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
282229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
283229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
2844fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
28538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian
286e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
2874fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
288229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertwrap_linear_clamp_to_edge(float s, unsigned size,
289229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                          int *icoord0, int *icoord1, float *w)
290229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
291229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float u = CLAMP(s, 0.0F, 1.0F);
292229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   u = u * size - 0.5f;
293229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
294229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
295229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (*icoord0 < 0)
296229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord0 = 0;
297229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (*icoord1 >= (int) size)
298229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord1 = size - 1;
299229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
3004fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
3014fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
302e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
3034fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
304229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertwrap_linear_clamp_to_border(float s, unsigned size,
305229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                            int *icoord0, int *icoord1, float *w)
3064fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
3074fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float min = -1.0F / (2.0F * size);
3084fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float max = 1.0F - min;
309229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float u = CLAMP(s, min, max);
310229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   u = u * size - 0.5f;
311229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
312229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
313229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
3144fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
3154fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
3164fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
3174fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
318229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertwrap_linear_mirror_repeat(float s, unsigned size,
319229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                          int *icoord0, int *icoord1, float *w)
320229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
321229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const int flr = util_ifloor(s);
322229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float u = frac(s);
323229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (flr & 1)
324229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      u = 1.0F - u;
325229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   u = u * size - 0.5F;
326229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
327229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
328229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (*icoord0 < 0)
329229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord0 = 0;
330229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (*icoord1 >= (int) size)
331229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord1 = size - 1;
332229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
3334fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
3344fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
335e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
3364fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
337229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertwrap_linear_mirror_clamp(float s, unsigned size,
338229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                         int *icoord0, int *icoord1, float *w)
339229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
340229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float u = fabsf(s);
341229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (u >= 1.0F)
342229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      u = (float) size;
343229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else
344229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      u *= size;
345229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   u -= 0.5F;
346229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
347229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
348229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
3494fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
3504fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
351e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
3524fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
353229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertwrap_linear_mirror_clamp_to_edge(float s, unsigned size,
354229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                 int *icoord0, int *icoord1, float *w)
355229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
356229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float u = fabsf(s);
357229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (u >= 1.0F)
358229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      u = (float) size;
359229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else
360229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      u *= size;
361229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   u -= 0.5F;
362229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
363229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
364229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (*icoord0 < 0)
365229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord0 = 0;
366229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (*icoord1 >= (int) size)
367229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord1 = size - 1;
368229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
3694fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
3704fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
371e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
3724fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
373229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertwrap_linear_mirror_clamp_to_border(float s, unsigned size,
374229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                   int *icoord0, int *icoord1, float *w)
3754fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
3764fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float min = -1.0F / (2.0F * size);
3774fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float max = 1.0F - min;
378229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float u = fabsf(s);
379229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (u <= min)
380229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      u = min * size;
381229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else if (u >= max)
382229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      u = max * size;
383229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else
384229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      u *= size;
385229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   u -= 0.5F;
386229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
387229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
388229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
3890dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
3900dc4eea64f56cc93e5359372b08b99a2d600273cBrian
3910dc4eea64f56cc93e5359372b08b99a2d600273cBrian
392b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian/**
393b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul * PIPE_TEX_WRAP_CLAMP for nearest sampling, unnormalized coords.
394b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian */
3954fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
396229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertwrap_nearest_unorm_clamp(float s, unsigned size, int *icoord)
397b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{
398229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int i = util_ifloor(s);
399229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord = CLAMP(i, 0, (int) size-1);
4004fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
4014fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
402e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
403e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul/**
404b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul * PIPE_TEX_WRAP_CLAMP_TO_BORDER for nearest sampling, unnormalized coords.
4054fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell */
4064fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
407229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertwrap_nearest_unorm_clamp_to_border(float s, unsigned size, int *icoord)
4084fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
409229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord = util_ifloor( CLAMP(s, -0.5F, (float) size + 0.5F) );
410b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul}
411b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul
412b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul
413b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul/**
414b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul * PIPE_TEX_WRAP_CLAMP_TO_EDGE for nearest sampling, unnormalized coords.
415b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul */
416b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paulstatic void
417229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertwrap_nearest_unorm_clamp_to_edge(float s, unsigned size, int *icoord)
418b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul{
419229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord = util_ifloor( CLAMP(s, 0.5F, (float) size - 0.5F) );
420b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian}
421b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
422b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
423b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian/**
424b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul * PIPE_TEX_WRAP_CLAMP for linear sampling, unnormalized coords.
425b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian */
4264fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
427229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertwrap_linear_unorm_clamp(float s, unsigned size,
428229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                        int *icoord0, int *icoord1, float *w)
429229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
430229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   /* Not exactly what the spec says, but it matches NVIDIA output */
431229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float u = CLAMP(s - 0.5F, 0.0f, (float) size - 1.0f);
432229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
433229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
434229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
435b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian}
436b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
437e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
438b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul/**
439b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul * PIPE_TEX_WRAP_CLAMP_TO_BORDER for linear sampling, unnormalized coords.
440b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul */
4414fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
442229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertwrap_linear_unorm_clamp_to_border(float s, unsigned size,
443229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                  int *icoord0, int *icoord1, float *w)
444229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
445229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float u = CLAMP(s, -0.5F, (float) size + 0.5F);
446229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   u -= 0.5F;
447229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
448229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
449229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (*icoord1 > (int) size - 1)
450229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord1 = size - 1;
451229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
452b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul}
453b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul
454b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul
455b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul/**
456b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul * PIPE_TEX_WRAP_CLAMP_TO_EDGE for linear sampling, unnormalized coords.
457b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul */
458b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paulstatic void
459229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertwrap_linear_unorm_clamp_to_edge(float s, unsigned size,
460229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                int *icoord0, int *icoord1, float *w)
461229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
462229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float u = CLAMP(s, +0.5F, (float) size - 0.5F);
463229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   u -= 0.5F;
464229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
465229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
466229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (*icoord1 > (int) size - 1)
467229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord1 = size - 1;
468229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
4694fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
4704fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
47134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
472779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul/**
473779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul * Do coordinate to array index conversion.  For array textures.
474779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul */
475779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paulstatic INLINE void
476229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertwrap_array_layer(float coord, unsigned size, int *layer)
477779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul{
478229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c = util_ifloor(coord + 0.5F);
479229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *layer = CLAMP(c, 0, size - 1);
480779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul}
481779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
48234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
483b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/**
484b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * Examine the quad's texture coordinates to compute the partial
485b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * derivatives w.r.t X and Y, then compute lambda (level of detail).
486b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian */
487b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic float
488f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paulcompute_lambda_1d(const struct sp_sampler_variant *samp,
4896b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float s[TGSI_QUAD_SIZE],
4906b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float t[TGSI_QUAD_SIZE],
4916b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float p[TGSI_QUAD_SIZE])
492b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian{
49321148e6a8806736b4487da41b01e2d3c01cbc743Henri Verbeet   const struct pipe_resource *texture = samp->view->texture;
4944fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]);
4954fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   float dsdy = fabsf(s[QUAD_TOP_LEFT]     - s[QUAD_BOTTOM_LEFT]);
4969acdd7739b729375444f8669fc2419d9eb57acc5Henri Verbeet   float rho = MAX2(dsdx, dsdy) * u_minify(texture->width0, samp->view->u.tex.first_level);
497b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
4984bfe1c955fe679547c8a03119d1681e33593c768Michal Krol   return util_fast_log2(rho);
499b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian}
500b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
501e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
5024fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic float
503f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paulcompute_lambda_2d(const struct sp_sampler_variant *samp,
5046b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float s[TGSI_QUAD_SIZE],
5056b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float t[TGSI_QUAD_SIZE],
5066b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float p[TGSI_QUAD_SIZE])
50709a1b912605ff48c8782dcc5aae55ac77e27037bBrian{
50821148e6a8806736b4487da41b01e2d3c01cbc743Henri Verbeet   const struct pipe_resource *texture = samp->view->texture;
5094fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]);
5104fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   float dsdy = fabsf(s[QUAD_TOP_LEFT]     - s[QUAD_BOTTOM_LEFT]);
5114fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   float dtdx = fabsf(t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]);
5124fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   float dtdy = fabsf(t[QUAD_TOP_LEFT]     - t[QUAD_BOTTOM_LEFT]);
5139acdd7739b729375444f8669fc2419d9eb57acc5Henri Verbeet   float maxx = MAX2(dsdx, dsdy) * u_minify(texture->width0, samp->view->u.tex.first_level);
5149acdd7739b729375444f8669fc2419d9eb57acc5Henri Verbeet   float maxy = MAX2(dtdx, dtdy) * u_minify(texture->height0, samp->view->u.tex.first_level);
5154fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   float rho  = MAX2(maxx, maxy);
516c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian
5174bfe1c955fe679547c8a03119d1681e33593c768Michal Krol   return util_fast_log2(rho);
51809a1b912605ff48c8782dcc5aae55ac77e27037bBrian}
51909a1b912605ff48c8782dcc5aae55ac77e27037bBrian
52008f33a025100dea2d951e6d628891fe294b18082Brian
5214fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic float
522f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paulcompute_lambda_3d(const struct sp_sampler_variant *samp,
5236b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float s[TGSI_QUAD_SIZE],
5246b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float t[TGSI_QUAD_SIZE],
5256b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float p[TGSI_QUAD_SIZE])
52609a1b912605ff48c8782dcc5aae55ac77e27037bBrian{
52721148e6a8806736b4487da41b01e2d3c01cbc743Henri Verbeet   const struct pipe_resource *texture = samp->view->texture;
5284fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]);
5294fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   float dsdy = fabsf(s[QUAD_TOP_LEFT]     - s[QUAD_BOTTOM_LEFT]);
5304fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   float dtdx = fabsf(t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]);
5314fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   float dtdy = fabsf(t[QUAD_TOP_LEFT]     - t[QUAD_BOTTOM_LEFT]);
5324fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   float dpdx = fabsf(p[QUAD_BOTTOM_RIGHT] - p[QUAD_BOTTOM_LEFT]);
5334fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   float dpdy = fabsf(p[QUAD_TOP_LEFT]     - p[QUAD_BOTTOM_LEFT]);
5349acdd7739b729375444f8669fc2419d9eb57acc5Henri Verbeet   float maxx = MAX2(dsdx, dsdy) * u_minify(texture->width0, samp->view->u.tex.first_level);
5359acdd7739b729375444f8669fc2419d9eb57acc5Henri Verbeet   float maxy = MAX2(dtdx, dtdy) * u_minify(texture->height0, samp->view->u.tex.first_level);
5369acdd7739b729375444f8669fc2419d9eb57acc5Henri Verbeet   float maxz = MAX2(dpdx, dpdy) * u_minify(texture->depth0, samp->view->u.tex.first_level);
5374bfe1c955fe679547c8a03119d1681e33593c768Michal Krol   float rho;
53800c835918259f8d41c3f74eca679a972713b11b2Keith Whitwell
5394fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   rho = MAX2(maxx, maxy);
5404fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   rho = MAX2(rho, maxz);
541c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian
5424bfe1c955fe679547c8a03119d1681e33593c768Michal Krol   return util_fast_log2(rho);
54309a1b912605ff48c8782dcc5aae55ac77e27037bBrian}
54409a1b912605ff48c8782dcc5aae55ac77e27037bBrian
54508f33a025100dea2d951e6d628891fe294b18082Brian
546e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul/**
547e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul * Compute lambda for a vertex texture sampler.
5484bfe1c955fe679547c8a03119d1681e33593c768Michal Krol * Since there aren't derivatives to use, just return 0.
549e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul */
5504fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic float
551f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paulcompute_lambda_vert(const struct sp_sampler_variant *samp,
5526b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                    const float s[TGSI_QUAD_SIZE],
5536b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                    const float t[TGSI_QUAD_SIZE],
5546b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                    const float p[TGSI_QUAD_SIZE])
5554fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
5564bfe1c955fe679547c8a03119d1681e33593c768Michal Krol   return 0.0f;
5574fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
5584fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
5594fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
5604fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
5614fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell/**
5624fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell * Get a texel from a texture, using the texture tile cache.
5634fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell *
56481601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell * \param addr  the template tex address containing cube, z, face info.
5654fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell * \param x  the x coord of texel within 2D image
566b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param y  the y coord of texel within 2D image
567b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param rgba  the quad to put the texel/color into
56870eb7996f265f3634dabda078f13d1be3533cc65Brian *
56980c78472ad43f4288c9ef5076074ba9d31a39885Keith Whitwell * XXX maybe move this into sp_tex_tile_cache.c and merge with the
570229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert * sp_get_cached_tile_tex() function.
571b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian */
57281601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
57381601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
57481601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
57581601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
57681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwellstatic INLINE const float *
577f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paulget_texel_2d_no_border(const struct sp_sampler_variant *samp,
57881601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell		       union tex_tile_address addr, int x, int y)
579b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian{
58081601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   const struct softpipe_tex_cached_tile *tile;
58181601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
58281601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   addr.bits.x = x / TILE_SIZE;
58381601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   addr.bits.y = y / TILE_SIZE;
58481601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   y %= TILE_SIZE;
58581601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   x %= TILE_SIZE;
58681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
58781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   tile = sp_get_cached_tile_tex(samp->cache, addr);
58881601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
58981601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   return &tile->data.color[y][x][0];
59081601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell}
59181601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
59281601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
59381601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwellstatic INLINE const float *
594f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paulget_texel_2d(const struct sp_sampler_variant *samp,
59581601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell	     union tex_tile_address addr, int x, int y)
59681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell{
59721148e6a8806736b4487da41b01e2d3c01cbc743Henri Verbeet   const struct pipe_resource *texture = samp->view->texture;
59881601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   unsigned level = addr.bits.level;
59981601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
600683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell   if (x < 0 || x >= (int) u_minify(texture->width0, level) ||
601683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell       y < 0 || y >= (int) u_minify(texture->height0, level)) {
6029f61e43b4903c6cf0ac03a479ec9ed7b15fd6ccfDave Airlie      return samp->sampler->border_color.f;
60381601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   }
60481601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   else {
60581601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell      return get_texel_2d_no_border( samp, addr, x, y );
60681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   }
60781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell}
6086142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
6096142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
61081601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell/* Gather a quad of adjacent texels within a tile:
61181601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell */
61281601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwellstatic INLINE void
613f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paulget_texel_quad_2d_no_border_single_tile(const struct sp_sampler_variant *samp,
61481601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell					union tex_tile_address addr,
61581601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell					unsigned x, unsigned y,
61681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell					const float *out[4])
61781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell{
61881601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   const struct softpipe_tex_cached_tile *tile;
61981601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
62081601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   addr.bits.x = x / TILE_SIZE;
62181601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   addr.bits.y = y / TILE_SIZE;
6226142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   y %= TILE_SIZE;
6236142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   x %= TILE_SIZE;
62481601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
62581601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   tile = sp_get_cached_tile_tex(samp->cache, addr);
6266142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
6276142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   out[0] = &tile->data.color[y  ][x  ][0];
6286142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   out[1] = &tile->data.color[y  ][x+1][0];
6296142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   out[2] = &tile->data.color[y+1][x  ][0];
6306142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   out[3] = &tile->data.color[y+1][x+1][0];
6316142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell}
6326142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
63381601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
63481601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell/* Gather a quad of potentially non-adjacent texels:
63581601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell */
63681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwellstatic INLINE void
637f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paulget_texel_quad_2d_no_border(const struct sp_sampler_variant *samp,
63881601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell			    union tex_tile_address addr,
63981601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell			    int x0, int y0,
64081601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell			    int x1, int y1,
64181601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell			    const float *out[4])
64281601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell{
64381601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   out[0] = get_texel_2d_no_border( samp, addr, x0, y0 );
64481601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   out[1] = get_texel_2d_no_border( samp, addr, x1, y0 );
64581601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   out[2] = get_texel_2d_no_border( samp, addr, x0, y1 );
64681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   out[3] = get_texel_2d_no_border( samp, addr, x1, y1 );
64781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell}
64881601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
64981601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell/* Can involve a lot of unnecessary checks for border color:
65081601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell */
65181601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwellstatic INLINE void
652f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paulget_texel_quad_2d(const struct sp_sampler_variant *samp,
65381601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell		  union tex_tile_address addr,
65481601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell		  int x0, int y0,
65581601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell		  int x1, int y1,
65681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell		  const float *out[4])
65781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell{
65881601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   out[0] = get_texel_2d( samp, addr, x0, y0 );
65981601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   out[1] = get_texel_2d( samp, addr, x1, y0 );
66081601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   out[3] = get_texel_2d( samp, addr, x1, y1 );
66181601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   out[2] = get_texel_2d( samp, addr, x0, y1 );
66281601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell}
66381601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
66481601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
66581601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
666f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paul/* 3d variants:
66781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell */
6686142de393fe34ff0866f8489f1292eb473276f11Keith Whitwellstatic INLINE const float *
669f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paulget_texel_3d_no_border(const struct sp_sampler_variant *samp,
670e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul                       union tex_tile_address addr, int x, int y, int z)
6716142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell{
672153e474d22d1b440bb6bd7b04dabf244d7455582Keith Whitwell   const struct softpipe_tex_cached_tile *tile;
6736142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
674153e474d22d1b440bb6bd7b04dabf244d7455582Keith Whitwell   addr.bits.x = x / TILE_SIZE;
675153e474d22d1b440bb6bd7b04dabf244d7455582Keith Whitwell   addr.bits.y = y / TILE_SIZE;
67681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   addr.bits.z = z;
6776142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   y %= TILE_SIZE;
6786142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   x %= TILE_SIZE;
6796142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
680153e474d22d1b440bb6bd7b04dabf244d7455582Keith Whitwell   tile = sp_get_cached_tile_tex(samp->cache, addr);
681153e474d22d1b440bb6bd7b04dabf244d7455582Keith Whitwell
6826142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   return &tile->data.color[y][x][0];
6836142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell}
6846142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
6856142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
68681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwellstatic INLINE const float *
687f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paulget_texel_3d(const struct sp_sampler_variant *samp,
688e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul	     union tex_tile_address addr, int x, int y, int z)
689b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian{
69021148e6a8806736b4487da41b01e2d3c01cbc743Henri Verbeet   const struct pipe_resource *texture = samp->view->texture;
69181601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   unsigned level = addr.bits.level;
6920b9e96fae9493d5d58f046e01c983a3c4267090eBrian
693683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell   if (x < 0 || x >= (int) u_minify(texture->width0, level) ||
694683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell       y < 0 || y >= (int) u_minify(texture->height0, level) ||
695683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell       z < 0 || z >= (int) u_minify(texture->depth0, level)) {
6969f61e43b4903c6cf0ac03a479ec9ed7b15fd6ccfDave Airlie      return samp->sampler->border_color.f;
697ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul   }
698ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul   else {
69981601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell      return get_texel_3d_no_border( samp, addr, x, y, z );
700ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul   }
701b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian}
702b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
703b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
70480777743b7b6238f034b8cb81d8d907d74929334Brian Paul/* Get texel pointer for 1D array texture */
70580777743b7b6238f034b8cb81d8d907d74929334Brian Paulstatic INLINE const float *
70680777743b7b6238f034b8cb81d8d907d74929334Brian Paulget_texel_1d_array(const struct sp_sampler_variant *samp,
70780777743b7b6238f034b8cb81d8d907d74929334Brian Paul                   union tex_tile_address addr, int x, int y)
70880777743b7b6238f034b8cb81d8d907d74929334Brian Paul{
70980777743b7b6238f034b8cb81d8d907d74929334Brian Paul   const struct pipe_resource *texture = samp->view->texture;
71080777743b7b6238f034b8cb81d8d907d74929334Brian Paul   unsigned level = addr.bits.level;
71180777743b7b6238f034b8cb81d8d907d74929334Brian Paul
71280777743b7b6238f034b8cb81d8d907d74929334Brian Paul   if (x < 0 || x >= (int) u_minify(texture->width0, level)) {
7139f61e43b4903c6cf0ac03a479ec9ed7b15fd6ccfDave Airlie      return samp->sampler->border_color.f;
71480777743b7b6238f034b8cb81d8d907d74929334Brian Paul   }
71580777743b7b6238f034b8cb81d8d907d74929334Brian Paul   else {
71680777743b7b6238f034b8cb81d8d907d74929334Brian Paul      return get_texel_2d_no_border(samp, addr, x, y);
71780777743b7b6238f034b8cb81d8d907d74929334Brian Paul   }
71880777743b7b6238f034b8cb81d8d907d74929334Brian Paul}
71980777743b7b6238f034b8cb81d8d907d74929334Brian Paul
72080777743b7b6238f034b8cb81d8d907d74929334Brian Paul
72180777743b7b6238f034b8cb81d8d907d74929334Brian Paul/* Get texel pointer for 2D array texture */
72280777743b7b6238f034b8cb81d8d907d74929334Brian Paulstatic INLINE const float *
72380777743b7b6238f034b8cb81d8d907d74929334Brian Paulget_texel_2d_array(const struct sp_sampler_variant *samp,
72480777743b7b6238f034b8cb81d8d907d74929334Brian Paul                   union tex_tile_address addr, int x, int y, int layer)
72580777743b7b6238f034b8cb81d8d907d74929334Brian Paul{
72680777743b7b6238f034b8cb81d8d907d74929334Brian Paul   const struct pipe_resource *texture = samp->view->texture;
72780777743b7b6238f034b8cb81d8d907d74929334Brian Paul   unsigned level = addr.bits.level;
72880777743b7b6238f034b8cb81d8d907d74929334Brian Paul
72992d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul   assert(layer < (int) texture->array_size);
73092d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul   assert(layer >= 0);
73180777743b7b6238f034b8cb81d8d907d74929334Brian Paul
73280777743b7b6238f034b8cb81d8d907d74929334Brian Paul   if (x < 0 || x >= (int) u_minify(texture->width0, level) ||
73380777743b7b6238f034b8cb81d8d907d74929334Brian Paul       y < 0 || y >= (int) u_minify(texture->height0, level)) {
7349f61e43b4903c6cf0ac03a479ec9ed7b15fd6ccfDave Airlie      return samp->sampler->border_color.f;
73580777743b7b6238f034b8cb81d8d907d74929334Brian Paul   }
73680777743b7b6238f034b8cb81d8d907d74929334Brian Paul   else {
73780777743b7b6238f034b8cb81d8d907d74929334Brian Paul      return get_texel_3d_no_border(samp, addr, x, y, layer);
73880777743b7b6238f034b8cb81d8d907d74929334Brian Paul   }
73980777743b7b6238f034b8cb81d8d907d74929334Brian Paul}
74080777743b7b6238f034b8cb81d8d907d74929334Brian Paul
74180777743b7b6238f034b8cb81d8d907d74929334Brian Paul
74275276ea316610a5737f2115326482024aa09d02aroot/**
74375276ea316610a5737f2115326482024aa09d02aroot * Given the logbase2 of a mipmap's base level size and a mipmap level,
74475276ea316610a5737f2115326482024aa09d02aroot * return the size (in texels) of that mipmap level.
74575276ea316610a5737f2115326482024aa09d02aroot * For example, if level[0].width = 256 then base_pot will be 8.
74675276ea316610a5737f2115326482024aa09d02aroot * If level = 2, then we'll return 64 (the width at level=2).
74775276ea316610a5737f2115326482024aa09d02aroot * Return 1 if level > base_pot.
74875276ea316610a5737f2115326482024aa09d02aroot */
74975276ea316610a5737f2115326482024aa09d02arootstatic INLINE unsigned
75075276ea316610a5737f2115326482024aa09d02arootpot_level_size(unsigned base_pot, unsigned level)
75175276ea316610a5737f2115326482024aa09d02aroot{
75275276ea316610a5737f2115326482024aa09d02aroot   return (base_pot >= level) ? (1 << (base_pot - level)) : 1;
75375276ea316610a5737f2115326482024aa09d02aroot}
75475276ea316610a5737f2115326482024aa09d02aroot
75575276ea316610a5737f2115326482024aa09d02aroot
7564250882ccf8326ba9074c671110370534489caa6Brian Paulstatic void
757229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertprint_sample(const char *function, const float *rgba)
758229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
759229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   debug_printf("%s %g %g %g %g\n",
760229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                function,
761229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                rgba[0], rgba[TGSI_NUM_CHANNELS], rgba[2*TGSI_NUM_CHANNELS], rgba[3*TGSI_NUM_CHANNELS]);
762229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert}
763229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert
764229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert
765229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertstatic void
766229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertprint_sample_4(const char *function, float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
7674250882ccf8326ba9074c671110370534489caa6Brian Paul{
7684250882ccf8326ba9074c671110370534489caa6Brian Paul   debug_printf("%s %g %g %g %g, %g %g %g %g, %g %g %g %g, %g %g %g %g\n",
7694250882ccf8326ba9074c671110370534489caa6Brian Paul                function,
7704250882ccf8326ba9074c671110370534489caa6Brian Paul                rgba[0][0], rgba[1][0], rgba[2][0], rgba[3][0],
7714250882ccf8326ba9074c671110370534489caa6Brian Paul                rgba[0][1], rgba[1][1], rgba[2][1], rgba[3][1],
7724250882ccf8326ba9074c671110370534489caa6Brian Paul                rgba[0][2], rgba[1][2], rgba[2][2], rgba[3][2],
7734250882ccf8326ba9074c671110370534489caa6Brian Paul                rgba[0][3], rgba[1][3], rgba[2][3], rgba[3][3]);
7744250882ccf8326ba9074c671110370534489caa6Brian Paul}
7754250882ccf8326ba9074c671110370534489caa6Brian Paul
77681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell/* Some image-filter fastpaths:
77781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell */
778efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paulstatic INLINE void
7794fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellimg_filter_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler,
780229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                float s,
781229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                float t,
782229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                float p,
783229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert				unsigned level,
784229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                unsigned face_id,
7854440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol                                enum tgsi_sampler_control control,
786229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                float *rgba)
7876142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell{
788f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paul   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
78975276ea316610a5737f2115326482024aa09d02aroot   unsigned xpot = pot_level_size(samp->xpot, level);
79075276ea316610a5737f2115326482024aa09d02aroot   unsigned ypot = pot_level_size(samp->ypot, level);
7911fd40e506c2207664f0c3f435e4614472ea4c540Keith Whitwell   unsigned xmax = (xpot - 1) & (TILE_SIZE - 1); /* MIN2(TILE_SIZE, xpot) - 1; */
7921fd40e506c2207664f0c3f435e4614472ea4c540Keith Whitwell   unsigned ymax = (ypot - 1) & (TILE_SIZE - 1); /* MIN2(TILE_SIZE, ypot) - 1; */
793153e474d22d1b440bb6bd7b04dabf244d7455582Keith Whitwell   union tex_tile_address addr;
794229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
795153e474d22d1b440bb6bd7b04dabf244d7455582Keith Whitwell
796153e474d22d1b440bb6bd7b04dabf244d7455582Keith Whitwell
7976142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
798229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float u = s * xpot - 0.5F;
799229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float v = t * ypot - 0.5F;
8006142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
801229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int uflr = util_ifloor(u);
802229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int vflr = util_ifloor(v);
8036142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
804229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float xw = u - (float)uflr;
805229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float yw = v - (float)vflr;
8066142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
807229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x0 = uflr & (xpot - 1);
808229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int y0 = vflr & (ypot - 1);
8096142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
810229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *tx[4];
8116142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
812229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   addr.value = 0;
813229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   addr.bits.level = level;
8146142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
815229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   /* Can we fetch all four at once:
816229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert    */
817229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (x0 < xmax && y0 < ymax) {
818229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      get_texel_quad_2d_no_border_single_tile(samp, addr, x0, y0, tx);
819229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   }
820229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else {
821229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      unsigned x1 = (x0 + 1) & (xpot - 1);
822229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      unsigned y1 = (y0 + 1) & (ypot - 1);
823229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      get_texel_quad_2d_no_border(samp, addr, x0, y0, x1, y1, tx);
824229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   }
825229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert
826229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   /* interpolate R, G, B, A */
827229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++) {
828229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw,
829229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                       tx[0][c], tx[1][c],
830229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                       tx[2][c], tx[3][c]);
8316142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   }
8324250882ccf8326ba9074c671110370534489caa6Brian Paul
8334250882ccf8326ba9074c671110370534489caa6Brian Paul   if (DEBUG_TEX) {
8344250882ccf8326ba9074c671110370534489caa6Brian Paul      print_sample(__FUNCTION__, rgba);
8354250882ccf8326ba9074c671110370534489caa6Brian Paul   }
8366142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell}
8376142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
8386142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
8394fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic INLINE void
8404fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellimg_filter_2d_nearest_repeat_POT(struct tgsi_sampler *tgsi_sampler,
841229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                 float s,
842229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                 float t,
843229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                 float p,
844229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                 unsigned level,
845229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                 unsigned face_id,
8464440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol                                 enum tgsi_sampler_control control,
847229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                 float rgba[TGSI_QUAD_SIZE])
8486142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell{
849f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paul   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
85075276ea316610a5737f2115326482024aa09d02aroot   unsigned xpot = pot_level_size(samp->xpot, level);
85175276ea316610a5737f2115326482024aa09d02aroot   unsigned ypot = pot_level_size(samp->ypot, level);
852229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *out;
853153e474d22d1b440bb6bd7b04dabf244d7455582Keith Whitwell   union tex_tile_address addr;
854229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
855153e474d22d1b440bb6bd7b04dabf244d7455582Keith Whitwell
856229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float u = s * xpot;
857229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float v = t * ypot;
8586142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
859229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int uflr = util_ifloor(u);
860229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int vflr = util_ifloor(v);
8616142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
862229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x0 = uflr & (xpot - 1);
863229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int y0 = vflr & (ypot - 1);
8646142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
865229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   addr.value = 0;
866229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   addr.bits.level = level;
8676142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
868229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   out = get_texel_2d_no_border(samp, addr, x0, y0);
869229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++)
870229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = out[c];
8714250882ccf8326ba9074c671110370534489caa6Brian Paul
8724250882ccf8326ba9074c671110370534489caa6Brian Paul   if (DEBUG_TEX) {
8734250882ccf8326ba9074c671110370534489caa6Brian Paul      print_sample(__FUNCTION__, rgba);
8744250882ccf8326ba9074c671110370534489caa6Brian Paul   }
8756142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell}
8766142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
8776142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
8784fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic INLINE void
8794fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellimg_filter_2d_nearest_clamp_POT(struct tgsi_sampler *tgsi_sampler,
880229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                float s,
881229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                float t,
882229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                float p,
883229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                unsigned level,
884229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                unsigned face_id,
8854440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol                                enum tgsi_sampler_control control,
886229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                float rgba[TGSI_QUAD_SIZE])
8876142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell{
888f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paul   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
88975276ea316610a5737f2115326482024aa09d02aroot   unsigned xpot = pot_level_size(samp->xpot, level);
89075276ea316610a5737f2115326482024aa09d02aroot   unsigned ypot = pot_level_size(samp->ypot, level);
891153e474d22d1b440bb6bd7b04dabf244d7455582Keith Whitwell   union tex_tile_address addr;
892229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
893153e474d22d1b440bb6bd7b04dabf244d7455582Keith Whitwell
894229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float u = s * xpot;
895229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float v = t * ypot;
8966142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
897229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x0, y0;
898229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *out;
8996142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
900229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   addr.value = 0;
901229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   addr.bits.level = level;
902229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert
903229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   x0 = util_ifloor(u);
904229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (x0 < 0)
905229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      x0 = 0;
906229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else if (x0 > xpot - 1)
907229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      x0 = xpot - 1;
908229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert
909229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   y0 = util_ifloor(v);
910229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (y0 < 0)
911229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      y0 = 0;
912229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else if (y0 > ypot - 1)
913229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      y0 = ypot - 1;
914229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert
915229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   out = get_texel_2d_no_border(samp, addr, x0, y0);
916229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++)
917229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = out[c];
9184250882ccf8326ba9074c671110370534489caa6Brian Paul
9194250882ccf8326ba9074c671110370534489caa6Brian Paul   if (DEBUG_TEX) {
9204250882ccf8326ba9074c671110370534489caa6Brian Paul      print_sample(__FUNCTION__, rgba);
9214250882ccf8326ba9074c671110370534489caa6Brian Paul   }
9226142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell}
9236142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
924e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
9256142de393fe34ff0866f8489f1292eb473276f11Keith Whitwellstatic void
9264fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellimg_filter_1d_nearest(struct tgsi_sampler *tgsi_sampler,
927229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                      float s,
928229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                      float t,
929229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                      float p,
930229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                      unsigned level,
931229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                      unsigned face_id,
932229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                      enum tgsi_sampler_control control,
933229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                      float rgba[TGSI_QUAD_SIZE])
9346142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell{
935f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paul   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
93621148e6a8806736b4487da41b01e2d3c01cbc743Henri Verbeet   const struct pipe_resource *texture = samp->view->texture;
9374fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   int width;
938229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x;
93981601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   union tex_tile_address addr;
940229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *out;
941229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
9426142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
943229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   width = u_minify(texture->width0, level);
9446142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
9454fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   assert(width > 0);
9464f409da3456070946eda2d8ff5153b3b4306bb46Keith Whitwell
94781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   addr.value = 0;
948229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   addr.bits.level = level;
94981601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
950229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   samp->nearest_texcoord_s(s, width, &x);
9514f409da3456070946eda2d8ff5153b3b4306bb46Keith Whitwell
952229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   out = get_texel_2d(samp, addr, x, 0);
953229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++)
954229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = out[c];
9554250882ccf8326ba9074c671110370534489caa6Brian Paul
9564250882ccf8326ba9074c671110370534489caa6Brian Paul   if (DEBUG_TEX) {
9574250882ccf8326ba9074c671110370534489caa6Brian Paul      print_sample(__FUNCTION__, rgba);
9584250882ccf8326ba9074c671110370534489caa6Brian Paul   }
9596142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell}
9606142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
9614fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
96260adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwellstatic void
963779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paulimg_filter_1d_array_nearest(struct tgsi_sampler *tgsi_sampler,
964229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                            float s,
965229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                            float t,
966229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                            float p,
967229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                            unsigned level,
968229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                            unsigned face_id,
969779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul                            enum tgsi_sampler_control control,
970229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                            float *rgba)
971779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul{
972779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
973779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   const struct pipe_resource *texture = samp->view->texture;
974779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   int width;
975229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x, layer;
976779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   union tex_tile_address addr;
977229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *out;
978229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
979779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
980229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   width = u_minify(texture->width0, level);
981779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
982779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   assert(width > 0);
983779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
984779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   addr.value = 0;
985229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   addr.bits.level = level;
986779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
987229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   samp->nearest_texcoord_s(s, width, &x);
988229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   wrap_array_layer(t, texture->array_size, &layer);
989779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
990229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   out = get_texel_1d_array(samp, addr, x, layer);
991229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++)
992229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = out[c];
993779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
994779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   if (DEBUG_TEX) {
995779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul      print_sample(__FUNCTION__, rgba);
996779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   }
997779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul}
998779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
999779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1000779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paulstatic void
100160adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwellimg_filter_2d_nearest(struct tgsi_sampler *tgsi_sampler,
1002229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                      float s,
1003229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                      float t,
1004229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                      float p,
1005229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                      unsigned level,
1006229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                      unsigned face_id,
10074440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol                      enum tgsi_sampler_control control,
1008229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                      float *rgba)
100960adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell{
1010f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paul   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
101121148e6a8806736b4487da41b01e2d3c01cbc743Henri Verbeet   const struct pipe_resource *texture = samp->view->texture;
101260adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell   int width, height;
1013229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x, y;
101460adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell   union tex_tile_address addr;
1015229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *out;
1016229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
101781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
1018229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   width = u_minify(texture->width0, level);
1019229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   height = u_minify(texture->height0, level);
102060adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
102160adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell   assert(width > 0);
10225dbedf3d7e99efe35fad308d382670e44cd60e25Brian Paul   assert(height > 0);
102360adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
102460adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell   addr.value = 0;
1025229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   addr.bits.level = level;
102660adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
1027229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   samp->nearest_texcoord_s(s, width, &x);
1028229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   samp->nearest_texcoord_t(t, height, &y);
102960adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
1030229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   out = get_texel_2d(samp, addr, x, y);
1031229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++)
1032229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = out[c];
10334250882ccf8326ba9074c671110370534489caa6Brian Paul
10344250882ccf8326ba9074c671110370534489caa6Brian Paul   if (DEBUG_TEX) {
10354250882ccf8326ba9074c671110370534489caa6Brian Paul      print_sample(__FUNCTION__, rgba);
10364250882ccf8326ba9074c671110370534489caa6Brian Paul   }
103760adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell}
103860adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
1039e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
1040779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paulstatic void
1041779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paulimg_filter_2d_array_nearest(struct tgsi_sampler *tgsi_sampler,
1042229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                            float s,
1043229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                            float t,
1044229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                            float p,
1045229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                            unsigned level,
1046229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                            unsigned face_id,
1047779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul                            enum tgsi_sampler_control control,
1048229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                            float *rgba)
1049779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul{
1050779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
1051779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   const struct pipe_resource *texture = samp->view->texture;
1052779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   int width, height;
1053229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x, y, layer;
1054779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   union tex_tile_address addr;
1055229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *out;
1056229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
1057779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1058229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   width = u_minify(texture->width0, level);
1059229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   height = u_minify(texture->height0, level);
1060779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1061779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   assert(width > 0);
1062779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   assert(height > 0);
1063779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1064779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   addr.value = 0;
1065229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   addr.bits.level = level;
1066779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1067229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   samp->nearest_texcoord_s(s, width, &x);
1068229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   samp->nearest_texcoord_t(t, height, &y);
1069229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   wrap_array_layer(p, texture->array_size, &layer);
1070779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1071229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   out = get_texel_2d_array(samp, addr, x, y, layer);
1072229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++)
1073229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = out[c];
1074779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1075779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   if (DEBUG_TEX) {
1076779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul      print_sample(__FUNCTION__, rgba);
1077779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   }
1078779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul}
1079779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1080779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
10819659aa6482291d1530c74450612bcd952f542e01José Fonsecastatic INLINE union tex_tile_address
1082e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paulface(union tex_tile_address addr, unsigned face )
108381601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell{
108481601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   addr.bits.face = face;
108581601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   return addr;
108681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell}
108781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
1088e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
1089e12810d92ffb3547680b227bf88937c03018112bBrianstatic void
109060adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwellimg_filter_cube_nearest(struct tgsi_sampler *tgsi_sampler,
1091229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                        float s,
1092229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                        float t,
1093229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                        float p,
1094229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                        unsigned level,
1095229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                        unsigned face_id,
10964440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol                        enum tgsi_sampler_control control,
1097229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                        float *rgba)
10980dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
1099f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paul   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
110021148e6a8806736b4487da41b01e2d3c01cbc743Henri Verbeet   const struct pipe_resource *texture = samp->view->texture;
1101f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian   int width, height;
1102229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x, y;
110381601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   union tex_tile_address addr;
1104229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *out;
1105229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
110681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
1107229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   width = u_minify(texture->width0, level);
1108229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   height = u_minify(texture->height0, level);
110909a1b912605ff48c8782dcc5aae55ac77e27037bBrian
1110b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   assert(width > 0);
11115dbedf3d7e99efe35fad308d382670e44cd60e25Brian Paul   assert(height > 0);
111281601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
111381601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   addr.value = 0;
1114229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   addr.bits.level = level;
1115612cfb749c3526eeb446bbc631bf24716522f373Brian
1116229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   samp->nearest_texcoord_s(s, width, &x);
1117229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   samp->nearest_texcoord_t(t, height, &y);
1118f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian
1119229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   out = get_texel_2d(samp, face(addr, face_id), x, y);
1120229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++)
1121229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = out[c];
11224250882ccf8326ba9074c671110370534489caa6Brian Paul
11234250882ccf8326ba9074c671110370534489caa6Brian Paul   if (DEBUG_TEX) {
11244250882ccf8326ba9074c671110370534489caa6Brian Paul      print_sample(__FUNCTION__, rgba);
11254250882ccf8326ba9074c671110370534489caa6Brian Paul   }
11260dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
112734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
112834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
11294fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
11304fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellimg_filter_3d_nearest(struct tgsi_sampler *tgsi_sampler,
1131229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                      float s,
1132229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                      float t,
1133229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                      float p,
1134229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                      unsigned level,
1135229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                      unsigned face_id,
11364440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol                      enum tgsi_sampler_control control,
1137229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                      float *rgba)
113834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
1139f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paul   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
114021148e6a8806736b4487da41b01e2d3c01cbc743Henri Verbeet   const struct pipe_resource *texture = samp->view->texture;
11413d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   int width, height, depth;
1142229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x, y, z;
114381601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   union tex_tile_address addr;
1144229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *out;
1145229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
1146b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
1147229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   width = u_minify(texture->width0, level);
1148229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   height = u_minify(texture->height0, level);
1149229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   depth = u_minify(texture->depth0, level);
11503d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
11513d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   assert(width > 0);
11523d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   assert(height > 0);
11533d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   assert(depth > 0);
11543d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
1155229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   samp->nearest_texcoord_s(s, width,  &x);
1156229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   samp->nearest_texcoord_t(t, height, &y);
1157229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   samp->nearest_texcoord_p(p, depth,  &z);
11583d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian
115981601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   addr.value = 0;
1160229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   addr.bits.level = level;
116181601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
1162229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   out = get_texel_3d(samp, addr, x, y, z);
1163229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++)
1164229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = out[c];
116534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
116634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
116734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
116834a48abd5ff82ce9748fc29191e35a0985d47c5fBrianstatic void
11694fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellimg_filter_1d_linear(struct tgsi_sampler *tgsi_sampler,
1170229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                     float s,
1171229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                     float t,
1172229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                     float p,
1173229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                     unsigned level,
1174229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                     unsigned face_id,
11754440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol                     enum tgsi_sampler_control control,
1176229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                     float *rgba)
117734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
1178f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paul   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
117921148e6a8806736b4487da41b01e2d3c01cbc743Henri Verbeet   const struct pipe_resource *texture = samp->view->texture;
11804fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   int width;
1181229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x0, x1;
1182229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float xw; /* weights */
118381601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   union tex_tile_address addr;
1184229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *tx0, *tx1;
1185229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
11864fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1187229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   width = u_minify(texture->width0, level);
11884fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
11894fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   assert(width > 0);
11904fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
119181601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   addr.value = 0;
1192229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   addr.bits.level = level;
119381601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
1194229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   samp->linear_texcoord_s(s, width, &x0, &x1, &xw);
11954fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1196229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   tx0 = get_texel_2d(samp, addr, x0, 0);
1197229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   tx1 = get_texel_2d(samp, addr, x1, 0);
11984fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1199229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   /* interpolate R, G, B, A */
1200229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++)
1201229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = lerp(xw, tx0[c], tx1[c]);
120234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
120334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
120481601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
120560adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwellstatic void
1206779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paulimg_filter_1d_array_linear(struct tgsi_sampler *tgsi_sampler,
1207229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                           float s,
1208229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                           float t,
1209229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                           float p,
1210229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                           unsigned level,
1211229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                           unsigned face_id,
1212779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul                           enum tgsi_sampler_control control,
1213229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                           float *rgba)
1214779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul{
1215779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
1216779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   const struct pipe_resource *texture = samp->view->texture;
1217779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   int width;
1218229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x0, x1, layer;
1219229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float xw; /* weights */
1220779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   union tex_tile_address addr;
1221229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *tx0, *tx1;
1222229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
1223779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1224229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   width = u_minify(texture->width0, level);
1225779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1226779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   assert(width > 0);
1227779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1228779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   addr.value = 0;
1229229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   addr.bits.level = level;
1230779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1231229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   samp->linear_texcoord_s(s, width, &x0, &x1, &xw);
1232229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   wrap_array_layer(t, texture->array_size, &layer);
1233779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1234229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   tx0 = get_texel_1d_array(samp, addr, x0, layer);
1235229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   tx1 = get_texel_1d_array(samp, addr, x1, layer);
1236779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1237229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   /* interpolate R, G, B, A */
1238229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++)
1239229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = lerp(xw, tx0[c], tx1[c]);
1240779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul}
1241779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1242779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1243779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paulstatic void
124460adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwellimg_filter_2d_linear(struct tgsi_sampler *tgsi_sampler,
1245229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                     float s,
1246229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                     float t,
1247229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                     float p,
1248229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                     unsigned level,
1249229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                     unsigned face_id,
12504440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol                     enum tgsi_sampler_control control,
1251229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                     float *rgba)
125260adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell{
1253f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paul   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
125421148e6a8806736b4487da41b01e2d3c01cbc743Henri Verbeet   const struct pipe_resource *texture = samp->view->texture;
125560adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell   int width, height;
1256229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x0, y0, x1, y1;
1257229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float xw, yw; /* weights */
125860adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell   union tex_tile_address addr;
1259229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *tx0, *tx1, *tx2, *tx3;
1260229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
126160adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
1262229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   width = u_minify(texture->width0, level);
1263229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   height = u_minify(texture->height0, level);
126460adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
126560adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell   assert(width > 0);
12665dbedf3d7e99efe35fad308d382670e44cd60e25Brian Paul   assert(height > 0);
126760adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
126860adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell   addr.value = 0;
1269229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   addr.bits.level = level;
127060adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
1271229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   samp->linear_texcoord_s(s, width,  &x0, &x1, &xw);
1272229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   samp->linear_texcoord_t(t, height, &y0, &y1, &yw);
127360adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
1274229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   tx0 = get_texel_2d(samp, addr, x0, y0);
1275229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   tx1 = get_texel_2d(samp, addr, x1, y0);
1276229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   tx2 = get_texel_2d(samp, addr, x0, y1);
1277229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   tx3 = get_texel_2d(samp, addr, x1, y1);
127860adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
1279229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   /* interpolate R, G, B, A */
1280229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++)
1281229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw,
1282229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                          tx0[c], tx1[c],
1283229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                          tx2[c], tx3[c]);
128460adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell}
128581601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
128681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
1287b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrianstatic void
1288779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paulimg_filter_2d_array_linear(struct tgsi_sampler *tgsi_sampler,
1289229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                           float s,
1290229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                           float t,
1291229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                           float p,
1292229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                           unsigned level,
1293229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                           unsigned face_id,
1294779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul                           enum tgsi_sampler_control control,
1295229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                           float *rgba)
1296779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul{
1297779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
1298779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   const struct pipe_resource *texture = samp->view->texture;
1299779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   int width, height;
1300229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x0, y0, x1, y1, layer;
1301229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float xw, yw; /* weights */
1302779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   union tex_tile_address addr;
1303229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *tx0, *tx1, *tx2, *tx3;
1304229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
1305779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1306229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   width = u_minify(texture->width0, level);
1307229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   height = u_minify(texture->height0, level);
1308779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1309779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   assert(width > 0);
1310779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   assert(height > 0);
1311779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1312779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   addr.value = 0;
1313229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   addr.bits.level = level;
1314779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1315229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   samp->linear_texcoord_s(s, width,  &x0, &x1, &xw);
1316229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   samp->linear_texcoord_t(t, height, &y0, &y1, &yw);
1317229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   wrap_array_layer(p, texture->array_size, &layer);
1318779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1319229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   tx0 = get_texel_2d_array(samp, addr, x0, y0, layer);
1320229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   tx1 = get_texel_2d_array(samp, addr, x1, y0, layer);
1321229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   tx2 = get_texel_2d_array(samp, addr, x0, y1, layer);
1322229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   tx3 = get_texel_2d_array(samp, addr, x1, y1, layer);
1323779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1324229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   /* interpolate R, G, B, A */
1325229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++)
1326229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw,
1327229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                          tx0[c], tx1[c],
1328229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                          tx2[c], tx3[c]);
1329779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul}
1330779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1331779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1332779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paulstatic void
133360adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwellimg_filter_cube_linear(struct tgsi_sampler *tgsi_sampler,
1334229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                       float s,
1335229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                       float t,
1336229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                       float p,
1337229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                       unsigned level,
1338229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                       unsigned face_id,
13394440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol                       enum tgsi_sampler_control control,
1340229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                       float *rgba)
1341b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{
1342f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paul   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
134321148e6a8806736b4487da41b01e2d3c01cbc743Henri Verbeet   const struct pipe_resource *texture = samp->view->texture;
1344b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   int width, height;
1345229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x0, y0, x1, y1;
1346229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float xw, yw; /* weights */
1347229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   union tex_tile_address addr, addrj;
1348229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *tx0, *tx1, *tx2, *tx3;
1349229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
1350b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
1351229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   width = u_minify(texture->width0, level);
1352229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   height = u_minify(texture->height0, level);
1353b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
1354b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   assert(width > 0);
13555dbedf3d7e99efe35fad308d382670e44cd60e25Brian Paul   assert(height > 0);
1356b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
135781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   addr.value = 0;
1358229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   addr.bits.level = level;
135981601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
1360229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   samp->linear_texcoord_s(s, width,  &x0, &x1, &xw);
1361229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   samp->linear_texcoord_t(t, height, &y0, &y1, &yw);
13624fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1363229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   addrj = face(addr, face_id);
1364229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   tx0 = get_texel_2d(samp, addrj, x0, y0);
1365229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   tx1 = get_texel_2d(samp, addrj, x1, y0);
1366229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   tx2 = get_texel_2d(samp, addrj, x0, y1);
1367229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   tx3 = get_texel_2d(samp, addrj, x1, y1);
13684fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1369229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   /* interpolate R, G, B, A */
1370229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++)
1371229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw,
1372229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                          tx0[c], tx1[c],
1373229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                          tx2[c], tx3[c]);
13744fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
13754fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
13764fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
13774fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
13784fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellimg_filter_3d_linear(struct tgsi_sampler *tgsi_sampler,
1379229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                     float s,
1380229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                     float t,
1381229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                     float p,
1382229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                     unsigned level,
1383229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                     unsigned face_id,
13844440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol                     enum tgsi_sampler_control control,
1385229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                     float *rgba)
13864fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
1387f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paul   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
138821148e6a8806736b4487da41b01e2d3c01cbc743Henri Verbeet   const struct pipe_resource *texture = samp->view->texture;
13894fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   int width, height, depth;
1390229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x0, x1, y0, y1, z0, z1;
1391229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float xw, yw, zw; /* interpolation weights */
139281601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   union tex_tile_address addr;
1393229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *tx00, *tx01, *tx02, *tx03, *tx10, *tx11, *tx12, *tx13;
1394229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
13954fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1396229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   width = u_minify(texture->width0, level);
1397229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   height = u_minify(texture->height0, level);
1398229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   depth = u_minify(texture->depth0, level);
13994fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
140081601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   addr.value = 0;
1401229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   addr.bits.level = level;
140281601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
14034fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   assert(width > 0);
14044fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   assert(height > 0);
14054fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   assert(depth > 0);
14064fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1407229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   samp->linear_texcoord_s(s, width,  &x0, &x1, &xw);
1408229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   samp->linear_texcoord_t(t, height, &y0, &y1, &yw);
1409229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   samp->linear_texcoord_p(p, depth,  &z0, &z1, &zw);
14104fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
14114fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1412229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   tx00 = get_texel_3d(samp, addr, x0, y0, z0);
1413229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   tx01 = get_texel_3d(samp, addr, x1, y0, z0);
1414229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   tx02 = get_texel_3d(samp, addr, x0, y1, z0);
1415229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   tx03 = get_texel_3d(samp, addr, x1, y1, z0);
141681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
1417229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   tx10 = get_texel_3d(samp, addr, x0, y0, z1);
1418229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   tx11 = get_texel_3d(samp, addr, x1, y0, z1);
1419229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   tx12 = get_texel_3d(samp, addr, x0, y1, z1);
1420229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   tx13 = get_texel_3d(samp, addr, x1, y1, z1);
142181601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
14224fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      /* interpolate R, G, B, A */
1423229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++)
1424229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] =  lerp_3d(xw, yw, zw,
1425229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                           tx00[c], tx01[c],
1426229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                           tx02[c], tx03[c],
1427229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                           tx10[c], tx11[c],
1428229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                           tx12[c], tx13[c]);
14294fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
14304fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
14314fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
14324bfe1c955fe679547c8a03119d1681e33593c768Michal Krol/* Calculate level of detail for every fragment.
14334bfe1c955fe679547c8a03119d1681e33593c768Michal Krol * Note that lambda has already been biased by global LOD bias.
14344bfe1c955fe679547c8a03119d1681e33593c768Michal Krol */
14354bfe1c955fe679547c8a03119d1681e33593c768Michal Krolstatic INLINE void
14364bfe1c955fe679547c8a03119d1681e33593c768Michal Krolcompute_lod(const struct pipe_sampler_state *sampler,
14374bfe1c955fe679547c8a03119d1681e33593c768Michal Krol            const float biased_lambda,
14386b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard            const float lodbias[TGSI_QUAD_SIZE],
14396b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard            float lod[TGSI_QUAD_SIZE])
14404bfe1c955fe679547c8a03119d1681e33593c768Michal Krol{
14414bfe1c955fe679547c8a03119d1681e33593c768Michal Krol   uint i;
14424bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
14436b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   for (i = 0; i < TGSI_QUAD_SIZE; i++) {
14444bfe1c955fe679547c8a03119d1681e33593c768Michal Krol      lod[i] = biased_lambda + lodbias[i];
14454bfe1c955fe679547c8a03119d1681e33593c768Michal Krol      lod[i] = CLAMP(lod[i], sampler->min_lod, sampler->max_lod);
14464bfe1c955fe679547c8a03119d1681e33593c768Michal Krol   }
14474bfe1c955fe679547c8a03119d1681e33593c768Michal Krol}
14484bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
14494bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
14504fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
14514fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellmip_filter_linear(struct tgsi_sampler *tgsi_sampler,
14526b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float s[TGSI_QUAD_SIZE],
14536b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float t[TGSI_QUAD_SIZE],
14546b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float p[TGSI_QUAD_SIZE],
14556b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float c0[TGSI_QUAD_SIZE],
14564440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol                  enum tgsi_sampler_control control,
14576b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
14584fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
1459f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paul   struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
146021148e6a8806736b4487da41b01e2d3c01cbc743Henri Verbeet   const struct pipe_resource *texture = samp->view->texture;
1461229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int j;
14626b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float lod[TGSI_QUAD_SIZE];
14634fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
14644440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol   if (control == tgsi_sampler_lod_bias) {
1465229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      float lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias;
14664440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol      compute_lod(samp->sampler, lambda, c0, lod);
14674440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol   } else {
14684440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol      assert(control == tgsi_sampler_lod_explicit);
14694bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
14704440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol      memcpy(lod, c0, sizeof(lod));
14714440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol   }
14724bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
1473229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
1474229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      int level0 = samp->view->u.tex.first_level + (int)lod[j];
14754fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1476229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      if (lod[j] < 0.0)
1477229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         samp->mag_img_filter(tgsi_sampler, s[j], t[j], p[j], samp->view->u.tex.first_level, samp->faces[j], tgsi_sampler_lod_bias, &rgba[0][j]);
14784fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1479229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      else if (level0 >= texture->last_level)
1480229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         samp->min_img_filter(tgsi_sampler, s[j], t[j], p[j], texture->last_level, samp->faces[j], tgsi_sampler_lod_bias, &rgba[0][j]);
14814fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1482229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      else {
1483229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         float levelBlend = frac(lod[j]);
1484229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         float rgbax[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
1485229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         int c;
1486229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert
1487229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         samp->min_img_filter(tgsi_sampler, s[j], t[j], p[j], level0,   samp->faces[j], tgsi_sampler_lod_bias, &rgbax[0][0]);
1488229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         samp->min_img_filter(tgsi_sampler, s[j], t[j], p[j], level0+1, samp->faces[j], tgsi_sampler_lod_bias, &rgbax[0][1]);
14894fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
14904fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         for (c = 0; c < 4; c++) {
1491229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert            rgba[c][j] = lerp(levelBlend, rgbax[c][0], rgbax[c][1]);
1492b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         }
1493b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      }
1494b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   }
14954250882ccf8326ba9074c671110370534489caa6Brian Paul
14964250882ccf8326ba9074c671110370534489caa6Brian Paul   if (DEBUG_TEX) {
1497229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      print_sample_4(__FUNCTION__, rgba);
14984250882ccf8326ba9074c671110370534489caa6Brian Paul   }
1499b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian}
1500b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
1501b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
150285425b3b609c480cd024b217b1efd0b9153bed58Brian Paul/**
150385425b3b609c480cd024b217b1efd0b9153bed58Brian Paul * Compute nearest mipmap level from texcoords.
150485425b3b609c480cd024b217b1efd0b9153bed58Brian Paul * Then sample the texture level for four elements of a quad.
150585425b3b609c480cd024b217b1efd0b9153bed58Brian Paul * \param c0  the LOD bias factors, or absolute LODs (depending on control)
150685425b3b609c480cd024b217b1efd0b9153bed58Brian Paul */
15074fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
15084fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellmip_filter_nearest(struct tgsi_sampler *tgsi_sampler,
15096b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                   const float s[TGSI_QUAD_SIZE],
15106b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                   const float t[TGSI_QUAD_SIZE],
15116b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                   const float p[TGSI_QUAD_SIZE],
15126b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                   const float c0[TGSI_QUAD_SIZE],
15134440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol                   enum tgsi_sampler_control control,
15146b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                   float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
15154fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
1516f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paul   struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
151721148e6a8806736b4487da41b01e2d3c01cbc743Henri Verbeet   const struct pipe_resource *texture = samp->view->texture;
15186b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float lod[TGSI_QUAD_SIZE];
1519229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int j;
15204fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
15214440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol   if (control == tgsi_sampler_lod_bias) {
1522229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      float lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias;
15234440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol      compute_lod(samp->sampler, lambda, c0, lod);
15244440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol   } else {
15254440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol      assert(control == tgsi_sampler_lod_explicit);
15264bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
15274440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol      memcpy(lod, c0, sizeof(lod));
15284440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol   }
15294bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
1530229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
1531229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      if (lod[j] < 0.0)
1532229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         samp->mag_img_filter(tgsi_sampler, s[j], t[j], p[j], samp->view->u.tex.first_level, samp->faces[j], tgsi_sampler_lod_bias, &rgba[0][j]);
1533229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      else {
1534229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         float level = samp->view->u.tex.first_level + (int)(lod[j] + 0.5F) ;
1535229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         level = MIN2(level, (int)texture->last_level);
1536229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         samp->min_img_filter(tgsi_sampler, s[j], t[j], p[j], level, samp->faces[j], tgsi_sampler_lod_bias, &rgba[0][j]);
1537229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      }
15384fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   }
153975276ea316610a5737f2115326482024aa09d02aroot
15404250882ccf8326ba9074c671110370534489caa6Brian Paul   if (DEBUG_TEX) {
1541229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      print_sample_4(__FUNCTION__, rgba);
15424250882ccf8326ba9074c671110370534489caa6Brian Paul   }
15434fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
15444fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
15454fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
15464fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
15474fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellmip_filter_none(struct tgsi_sampler *tgsi_sampler,
15486b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                const float s[TGSI_QUAD_SIZE],
15496b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                const float t[TGSI_QUAD_SIZE],
15506b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                const float p[TGSI_QUAD_SIZE],
15516b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                const float c0[TGSI_QUAD_SIZE],
15524440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol                enum tgsi_sampler_control control,
15536b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
15544fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
1555f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paul   struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
15566b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float lod[TGSI_QUAD_SIZE];
1557229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int j;
15584bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
15594440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol   if (control == tgsi_sampler_lod_bias) {
1560229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      float lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias;
15614440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol      compute_lod(samp->sampler, lambda, c0, lod);
15624440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol   } else {
15634440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol      assert(control == tgsi_sampler_lod_explicit);
15644bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
15654440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol      memcpy(lod, c0, sizeof(lod));
15664440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol   }
15674bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
1568229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
1569229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      if (lod[j] < 0.0) {
1570229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         samp->mag_img_filter(tgsi_sampler, s[j], t[j], p[j], samp->view->u.tex.first_level, samp->faces[j], tgsi_sampler_lod_bias, &rgba[0][j]);
1571229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      }
1572229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      else {
1573229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         samp->min_img_filter(tgsi_sampler, s[j], t[j], p[j], samp->view->u.tex.first_level, samp->faces[j], tgsi_sampler_lod_bias, &rgba[0][j]);
1574229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      }
15754fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   }
15764fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
15774fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
15784fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1579229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertstatic void
1580229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertmip_filter_none_no_filter_select(struct tgsi_sampler *tgsi_sampler,
1581229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                     const float s[TGSI_QUAD_SIZE],
1582229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                     const float t[TGSI_QUAD_SIZE],
1583229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                     const float p[TGSI_QUAD_SIZE],
1584229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                     const float c0[TGSI_QUAD_SIZE],
1585229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                     enum tgsi_sampler_control control,
1586229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                     float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
1587229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
1588229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
1589229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int j;
1590229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert
1591229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (j = 0; j < TGSI_QUAD_SIZE; j++)
1592229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      samp->mag_img_filter(tgsi_sampler, s[j], t[j], p[j], samp->view->u.tex.first_level, samp->faces[j], tgsi_sampler_lod_bias, &rgba[0][j]);
1593229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert}
1594229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert
1595229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert
1596f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger/* For anisotropic filtering */
1597f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger#define WEIGHT_LUT_SIZE 1024
1598f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1599f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faengerstatic float *weightLut = NULL;
1600f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1601f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger/**
1602f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger * Creates the look-up table used to speed-up EWA sampling
1603f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger */
1604f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faengerstatic void
1605f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faengercreate_filter_table(void)
1606f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger{
1607f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   unsigned i;
1608f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   if (!weightLut) {
1609f32c9c210875b2ce4878f97b84bdd4739bd489f9José Fonseca      weightLut = (float *) MALLOC(WEIGHT_LUT_SIZE * sizeof(float));
1610f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1611f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      for (i = 0; i < WEIGHT_LUT_SIZE; ++i) {
1612f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger         float alpha = 2;
1613f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger         float r2 = (float) i / (float) (WEIGHT_LUT_SIZE - 1);
1614f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger         float weight = (float) exp(-alpha * r2);
1615f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger         weightLut[i] = weight;
1616f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      }
1617f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   }
1618f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger}
1619f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1620f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1621f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger/**
1622f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger * Elliptical weighted average (EWA) filter for producing high quality
1623f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger * anisotropic filtered results.
1624229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert * Based on the Higher Quality Elliptical Weighted Average Filter
1625f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger * published by Paul S. Heckbert in his Master's Thesis
1626f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger * "Fundamentals of Texture Mapping and Image Warping" (1989)
1627f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger */
1628f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faengerstatic void
1629f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faengerimg_filter_2d_ewa(struct tgsi_sampler *tgsi_sampler,
16306b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float s[TGSI_QUAD_SIZE],
16316b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float t[TGSI_QUAD_SIZE],
16326b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float p[TGSI_QUAD_SIZE],
1633229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                  unsigned level,
1634f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger                  enum tgsi_sampler_control control,
1635f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger                  const float dudx, const float dvdx,
1636f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger                  const float dudy, const float dvdy,
16376b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
1638f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger{
1639f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
1640f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   const struct pipe_resource *texture = samp->view->texture;
1641f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1642229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   // ??? Won't the image filters blow up if level is negative?
1643229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   unsigned level0 = level > 0 ? level : 0;
1644f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   float scaling = 1.0 / (1 << level0);
1645f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   int width = u_minify(texture->width0, level0);
1646f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   int height = u_minify(texture->height0, level0);
1647f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1648f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   float ux = dudx * scaling;
1649f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   float vx = dvdx * scaling;
1650f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   float uy = dudy * scaling;
1651f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   float vy = dvdy * scaling;
1652f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1653f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   /* compute ellipse coefficients to bound the region:
1654f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger    * A*x*x + B*x*y + C*y*y = F.
1655f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger    */
1656f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   float A = vx*vx+vy*vy+1;
1657f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   float B = -2*(ux*vx+uy*vy);
1658f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   float C = ux*ux+uy*uy+1;
1659f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   float F = A*C-B*B/4.0;
1660f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1661f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   /* check if it is an ellipse */
1662f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   /* ASSERT(F > 0.0); */
1663f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1664f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   /* Compute the ellipse's (u,v) bounding box in texture space */
1665f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   float d = -B*B+4.0*C*A;
1666f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   float box_u = 2.0 / d * sqrt(d*C*F); /* box_u -> half of bbox with   */
1667f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   float box_v = 2.0 / d * sqrt(A*d*F); /* box_v -> half of bbox height */
1668f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
16696b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float rgba_temp[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
16706b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float s_buffer[TGSI_QUAD_SIZE];
16716b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float t_buffer[TGSI_QUAD_SIZE];
16726b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float weight_buffer[TGSI_QUAD_SIZE];
1673f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   unsigned buffer_next;
1674f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   int j;
1675b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul   float den; /* = 0.0F; */
1676f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   float ddq;
1677b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul   float U; /* = u0 - tex_u; */
1678f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   int v;
1679f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1680f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   /* Scale ellipse formula to directly index the Filter Lookup Table.
1681f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger    * i.e. scale so that F = WEIGHT_LUT_SIZE-1
1682f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger    */
1683f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   double formScale = (double) (WEIGHT_LUT_SIZE - 1) / F;
1684f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   A *= formScale;
1685f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   B *= formScale;
1686f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   C *= formScale;
1687f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   /* F *= formScale; */ /* no need to scale F as we don't use it below here */
1688f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1689f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   /* For each quad, the du and dx values are the same and so the ellipse is
1690f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger    * also the same. Note that texel/image access can only be performed using
1691f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger    * a quad, i.e. it is not possible to get the pixel value for a single
1692f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger    * tex coord. In order to have a better performance, the access is buffered
1693b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul    * using the s_buffer/t_buffer and weight_buffer. Only when the buffer is
1694b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul    * full, then the pixel values are read from the image.
1695f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger    */
1696f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   ddq = 2 * A;
1697f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
16986b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
1699f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      /* Heckbert MS thesis, p. 59; scan over the bounding box of the ellipse
1700f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger       * and incrementally update the value of Ax^2+Bxy*Cy^2; when this
1701f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger       * value, q, is less than F, we're inside the ellipse
1702f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger       */
1703b82db9a3c0a1b96d8eb5d0d78aecaf0ab331431aBrian Paul      float tex_u = -0.5F + s[j] * texture->width0 * scaling;
1704b82db9a3c0a1b96d8eb5d0d78aecaf0ab331431aBrian Paul      float tex_v = -0.5F + t[j] * texture->height0 * scaling;
1705f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1706b82db9a3c0a1b96d8eb5d0d78aecaf0ab331431aBrian Paul      int u0 = (int) floorf(tex_u - box_u);
1707b82db9a3c0a1b96d8eb5d0d78aecaf0ab331431aBrian Paul      int u1 = (int) ceilf(tex_u + box_u);
1708b82db9a3c0a1b96d8eb5d0d78aecaf0ab331431aBrian Paul      int v0 = (int) floorf(tex_v - box_v);
1709b82db9a3c0a1b96d8eb5d0d78aecaf0ab331431aBrian Paul      int v1 = (int) ceilf(tex_v + box_v);
1710f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1711f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      float num[4] = {0.0F, 0.0F, 0.0F, 0.0F};
1712f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      buffer_next = 0;
1713f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      den = 0;
1714f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      U = u0 - tex_u;
1715f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      for (v = v0; v <= v1; ++v) {
1716f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger         float V = v - tex_v;
1717f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger         float dq = A * (2 * U + 1) + B * V;
1718f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger         float q = (C * V + B * U) * V + A * U * U;
1719f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1720f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger         int u;
1721f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger         for (u = u0; u <= u1; ++u) {
1722b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul            /* Note that the ellipse has been pre-scaled so F =
1723b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul             * WEIGHT_LUT_SIZE - 1
1724b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul             */
1725f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger            if (q < WEIGHT_LUT_SIZE) {
1726f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger               /* as a LUT is used, q must never be negative;
1727f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger                * should not happen, though
1728f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger                */
1729f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger               const int qClamped = q >= 0.0F ? q : 0;
1730f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger               float weight = weightLut[qClamped];
1731f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1732f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger               weight_buffer[buffer_next] = weight;
1733f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger               s_buffer[buffer_next] = u / ((float) width);
1734f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger               t_buffer[buffer_next] = v / ((float) height);
1735f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1736f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger               buffer_next++;
17376b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard               if (buffer_next == TGSI_QUAD_SIZE) {
1738f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger                  /* 4 texel coords are in the buffer -> read it now */
1739b82db9a3c0a1b96d8eb5d0d78aecaf0ab331431aBrian Paul                  unsigned jj;
1740f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger                  /* it is assumed that samp->min_img_filter is set to
1741f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger                   * img_filter_2d_nearest or one of the
1742f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger                   * accelerated img_filter_2d_nearest_XXX functions.
1743f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger                   */
1744f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger                  for (jj = 0; jj < buffer_next; jj++) {
1745229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                     samp->min_img_filter(tgsi_sampler, s_buffer[jj], t_buffer[jj], p[jj], level, samp->faces[j],
1746229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                          tgsi_sampler_lod_bias, &rgba_temp[0][jj]);
1747f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger                     num[0] += weight_buffer[jj] * rgba_temp[0][jj];
1748f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger                     num[1] += weight_buffer[jj] * rgba_temp[1][jj];
1749f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger                     num[2] += weight_buffer[jj] * rgba_temp[2][jj];
1750f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger                     num[3] += weight_buffer[jj] * rgba_temp[3][jj];
1751f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger                  }
1752f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1753f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger                  buffer_next = 0;
1754f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger               }
1755f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1756f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger               den += weight;
1757f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger            }
1758f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger            q += dq;
1759f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger            dq += ddq;
1760f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger         }
1761f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      }
1762f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1763b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul      /* if the tex coord buffer contains unread values, we will read
1764229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert       * them now.
1765f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger       */
1766f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      if (buffer_next > 0) {
1767b82db9a3c0a1b96d8eb5d0d78aecaf0ab331431aBrian Paul         unsigned jj;
1768f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger         /* it is assumed that samp->min_img_filter is set to
1769f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger          * img_filter_2d_nearest or one of the
1770f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger          * accelerated img_filter_2d_nearest_XXX functions.
1771f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger          */
1772f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger         for (jj = 0; jj < buffer_next; jj++) {
1773229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert            samp->min_img_filter(tgsi_sampler, s_buffer[jj], t_buffer[jj], p[jj], level, samp->faces[j],
1774229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                 tgsi_sampler_lod_bias, &rgba_temp[0][jj]);
1775f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger            num[0] += weight_buffer[jj] * rgba_temp[0][jj];
1776f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger            num[1] += weight_buffer[jj] * rgba_temp[1][jj];
1777f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger            num[2] += weight_buffer[jj] * rgba_temp[2][jj];
1778f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger            num[3] += weight_buffer[jj] * rgba_temp[3][jj];
1779f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger         }
1780f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      }
1781f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1782f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      if (den <= 0.0F) {
1783b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul         /* Reaching this place would mean that no pixels intersected
1784b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul          * the ellipse.  This should never happen because the filter
1785b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul          * we use always intersects at least one pixel.
1786f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger          */
1787f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1788f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger         /*rgba[0]=0;
1789f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger         rgba[1]=0;
1790f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger         rgba[2]=0;
1791f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger         rgba[3]=0;*/
1792f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger         /* not enough pixels in resampling, resort to direct interpolation */
1793229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         samp->min_img_filter(tgsi_sampler, s[j], t[j], p[j], level, samp->faces[j],
1794229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                              tgsi_sampler_lod_bias, &rgba_temp[0][j]);
1795f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger         den = 1;
1796f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger         num[0] = rgba_temp[0][j];
1797f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger         num[1] = rgba_temp[1][j];
1798f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger         num[2] = rgba_temp[2][j];
1799f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger         num[3] = rgba_temp[3][j];
1800f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      }
1801f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1802f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      rgba[0][j] = num[0] / den;
1803f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      rgba[1][j] = num[1] / den;
1804f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      rgba[2][j] = num[2] / den;
1805f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      rgba[3][j] = num[3] / den;
1806f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   }
1807f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger}
1808f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1809f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1810f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger/**
1811f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger * Sample 2D texture using an anisotropic filter.
1812f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger */
1813f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faengerstatic void
1814f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faengermip_filter_linear_aniso(struct tgsi_sampler *tgsi_sampler,
18156b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                        const float s[TGSI_QUAD_SIZE],
18166b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                        const float t[TGSI_QUAD_SIZE],
18176b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                        const float p[TGSI_QUAD_SIZE],
18186b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                        const float c0[TGSI_QUAD_SIZE],
1819f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger                        enum tgsi_sampler_control control,
18206b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                        float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
1821f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger{
1822f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
1823f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   const struct pipe_resource *texture = samp->view->texture;
1824f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   int level0;
1825f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   float lambda;
18266b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float lod[TGSI_QUAD_SIZE];
1827f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1828f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   float s_to_u = u_minify(texture->width0, samp->view->u.tex.first_level);
1829f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   float t_to_v = u_minify(texture->height0, samp->view->u.tex.first_level);
1830f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   float dudx = (s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]) * s_to_u;
1831f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   float dudy = (s[QUAD_TOP_LEFT]     - s[QUAD_BOTTOM_LEFT]) * s_to_u;
1832f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   float dvdx = (t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]) * t_to_v;
1833f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   float dvdy = (t[QUAD_TOP_LEFT]     - t[QUAD_BOTTOM_LEFT]) * t_to_v;
1834f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1835f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   if (control == tgsi_sampler_lod_bias) {
1836f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      /* note: instead of working with Px and Py, we will use the
1837f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger       * squared length instead, to avoid sqrt.
1838f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger       */
1839f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      float Px2 = dudx * dudx + dvdx * dvdx;
1840f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      float Py2 = dudy * dudy + dvdy * dvdy;
1841f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1842f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      float Pmax2;
1843f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      float Pmin2;
1844f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      float e;
1845f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      const float maxEccentricity = samp->sampler->max_anisotropy * samp->sampler->max_anisotropy;
1846f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1847f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      if (Px2 < Py2) {
1848f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger         Pmax2 = Py2;
1849f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger         Pmin2 = Px2;
1850f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      }
1851f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      else {
1852f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger         Pmax2 = Px2;
1853f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger         Pmin2 = Py2;
1854f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      }
1855f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1856f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      /* if the eccentricity of the ellipse is too big, scale up the shorter
1857f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger       * of the two vectors to limit the maximum amount of work per pixel
1858f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger       */
1859f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      e = Pmax2 / Pmin2;
1860f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      if (e > maxEccentricity) {
1861f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger         /* float s=e / maxEccentricity;
1862f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger            minor[0] *= s;
1863f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger            minor[1] *= s;
1864f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger            Pmin2 *= s; */
1865f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger         Pmin2 = Pmax2 / maxEccentricity;
1866f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      }
1867f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1868f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      /* note: we need to have Pmin=sqrt(Pmin2) here, but we can avoid
1869f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger       * this since 0.5*log(x) = log(sqrt(x))
1870f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger       */
1871b82db9a3c0a1b96d8eb5d0d78aecaf0ab331431aBrian Paul      lambda = 0.5F * util_fast_log2(Pmin2) + samp->sampler->lod_bias;
1872f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      compute_lod(samp->sampler, lambda, c0, lod);
1873f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   }
1874f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   else {
1875f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      assert(control == tgsi_sampler_lod_explicit);
1876f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1877f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      memcpy(lod, c0, sizeof(lod));
1878f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   }
1879f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1880f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   /* XXX: Take into account all lod values.
1881f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger    */
1882f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   lambda = lod[0];
1883f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   level0 = samp->view->u.tex.first_level + (int)lambda;
1884f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1885f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   /* If the ellipse covers the whole image, we can
1886f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger    * simply return the average of the whole image.
1887f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger    */
1888b82db9a3c0a1b96d8eb5d0d78aecaf0ab331431aBrian Paul   if (level0 >= (int) texture->last_level) {
1889229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      int j;
1890229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      for (j = 0; j < TGSI_QUAD_SIZE; j++)
1891229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         samp->min_img_filter(tgsi_sampler, s[j], t[j], p[j], texture->last_level, samp->faces[j], tgsi_sampler_lod_bias, &rgba[0][j]);
1892f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   }
1893f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   else {
1894f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      /* don't bother interpolating between multiple LODs; it doesn't
1895f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger       * seem to be worth the extra running time.
1896f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger       */
1897229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      img_filter_2d_ewa(tgsi_sampler, s, t, p, level0, tgsi_sampler_lod_bias,
1898f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger                        dudx, dvdx, dudy, dvdy, rgba);
1899f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   }
1900f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1901f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   if (DEBUG_TEX) {
1902229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      print_sample_4(__FUNCTION__, rgba);
1903f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger   }
1904f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger}
1905f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1906f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
1907e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul/**
1908e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul * Specialized version of mip_filter_linear with hard-wired calls to
19094fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell * 2d lambda calculation and 2d_linear_repeat_POT img filters.
1910a34b8594b7b2d00404bb639621ec1ce918ba0786Brian */
19114fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
19124fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellmip_filter_linear_2d_linear_repeat_POT(
19134fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   struct tgsi_sampler *tgsi_sampler,
19146b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   const float s[TGSI_QUAD_SIZE],
19156b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   const float t[TGSI_QUAD_SIZE],
19166b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   const float p[TGSI_QUAD_SIZE],
19176b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   const float c0[TGSI_QUAD_SIZE],
19184440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol   enum tgsi_sampler_control control,
19196b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
192000c835918259f8d41c3f74eca679a972713b11b2Keith Whitwell{
1921f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paul   struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
192221148e6a8806736b4487da41b01e2d3c01cbc743Henri Verbeet   const struct pipe_resource *texture = samp->view->texture;
1923229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int j;
19244fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   float lambda;
19256b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float lod[TGSI_QUAD_SIZE];
19264bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
19274440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol   if (control == tgsi_sampler_lod_bias) {
19284440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol      lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias;
19294440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol      compute_lod(samp->sampler, lambda, c0, lod);
19304440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol   } else {
19314440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol      assert(control == tgsi_sampler_lod_explicit);
193200c835918259f8d41c3f74eca679a972713b11b2Keith Whitwell
19334440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol      memcpy(lod, c0, sizeof(lod));
19344440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol   }
19354bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
1936229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
1937229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      int level0 = samp->view->u.tex.first_level + (int)lod[j];
19384fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1939229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      /* Catches both negative and large values of level0:
1940229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert       */
1941229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      if ((unsigned)level0 >= texture->last_level) {
1942229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         if (level0 < 0)
1943229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert            img_filter_2d_linear_repeat_POT(tgsi_sampler, s[j], t[j], p[j], samp->view->u.tex.first_level, samp->faces[j], tgsi_sampler_lod_bias, &rgba[0][j]);
1944229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         else
1945229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert            img_filter_2d_linear_repeat_POT(tgsi_sampler, s[j], t[j], p[j], samp->view->texture->last_level, samp->faces[j], tgsi_sampler_lod_bias, &rgba[0][j]);
19464fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1947229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      }
1948229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      else {
1949229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         float levelBlend = frac(lod[j]);
1950229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         float rgbax[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
1951229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         int c;
19524fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1953fa76d04aeaf249956072c023661b1e2cda103584Olivier Galibert         img_filter_2d_linear_repeat_POT(tgsi_sampler, s[j], t[j], p[j], level0,   samp->faces[j], tgsi_sampler_lod_bias, &rgbax[0][0]);
1954fa76d04aeaf249956072c023661b1e2cda103584Olivier Galibert         img_filter_2d_linear_repeat_POT(tgsi_sampler, s[j], t[j], p[j], level0+1, samp->faces[j], tgsi_sampler_lod_bias, &rgbax[0][1]);
19554fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1956229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         for (c = 0; c < TGSI_NUM_CHANNELS; c++)
1957229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert            rgba[c][j] = lerp(levelBlend, rgbax[c][0], rgbax[c][1]);
1958b1ff7dac537947d412bf423a73e7eacd76f90d84Brian Paul      }
1959ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul   }
19604250882ccf8326ba9074c671110370534489caa6Brian Paul
19614250882ccf8326ba9074c671110370534489caa6Brian Paul   if (DEBUG_TEX) {
1962229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      print_sample_4(__FUNCTION__, rgba);
19634250882ccf8326ba9074c671110370534489caa6Brian Paul   }
1964b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian}
1965b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
1966b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian
1967e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul/**
1968e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul * Do shadow/depth comparisons.
19693d8c05f7320151898dd224c1daaf3118e1f7ea34Brian */
19704fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
19714fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellsample_compare(struct tgsi_sampler *tgsi_sampler,
19726b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard               const float s[TGSI_QUAD_SIZE],
19736b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard               const float t[TGSI_QUAD_SIZE],
19746b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard               const float p[TGSI_QUAD_SIZE],
19756b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard               const float c0[TGSI_QUAD_SIZE],
19764440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol               enum tgsi_sampler_control control,
19776b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard               float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
19783d8c05f7320151898dd224c1daaf3118e1f7ea34Brian{
1979f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paul   struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
1980aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell   const struct pipe_sampler_state *sampler = samp->sampler;
19814fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   int j, k0, k1, k2, k3;
19824fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   float val;
19830eef561a5bb10df343837d58d37d5c0d5b708243Philip Taylor   float pc0, pc1, pc2, pc3;
19843d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
19854440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol   samp->mip_filter(tgsi_sampler, s, t, p, c0, control, rgba);
19863d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
19874fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /**
19884fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell    * Compare texcoord 'p' (aka R) against texture value 'rgba[0]'
198997b778efe7949977b4e857413807d1efcad346aaDave Airlie    * for 2D Array texture we need to use the 'c0' (aka Q).
19904fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell    * When we sampled the depth texture, the depth value was put into all
19914fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell    * RGBA channels.  We look at the red channel here.
19924fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell    */
1993efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul
1994fffca9046c96e3411493c39ebb1855012620495cDave Airlie   if (samp->view->texture->target == PIPE_TEXTURE_2D_ARRAY ||
1995fffca9046c96e3411493c39ebb1855012620495cDave Airlie       samp->view->texture->target == PIPE_TEXTURE_CUBE) {
199697b778efe7949977b4e857413807d1efcad346aaDave Airlie      pc0 = CLAMP(c0[0], 0.0F, 1.0F);
199797b778efe7949977b4e857413807d1efcad346aaDave Airlie      pc1 = CLAMP(c0[1], 0.0F, 1.0F);
199897b778efe7949977b4e857413807d1efcad346aaDave Airlie      pc2 = CLAMP(c0[2], 0.0F, 1.0F);
199997b778efe7949977b4e857413807d1efcad346aaDave Airlie      pc3 = CLAMP(c0[3], 0.0F, 1.0F);
200097b778efe7949977b4e857413807d1efcad346aaDave Airlie   } else {
200197b778efe7949977b4e857413807d1efcad346aaDave Airlie      pc0 = CLAMP(p[0], 0.0F, 1.0F);
200297b778efe7949977b4e857413807d1efcad346aaDave Airlie      pc1 = CLAMP(p[1], 0.0F, 1.0F);
200397b778efe7949977b4e857413807d1efcad346aaDave Airlie      pc2 = CLAMP(p[2], 0.0F, 1.0F);
200497b778efe7949977b4e857413807d1efcad346aaDave Airlie      pc3 = CLAMP(p[3], 0.0F, 1.0F);
200597b778efe7949977b4e857413807d1efcad346aaDave Airlie   }
2006efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   /* compare four texcoords vs. four texture samples */
2007efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   switch (sampler->compare_func) {
2008efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_LESS:
20090eef561a5bb10df343837d58d37d5c0d5b708243Philip Taylor      k0 = pc0 < rgba[0][0];
20100eef561a5bb10df343837d58d37d5c0d5b708243Philip Taylor      k1 = pc1 < rgba[0][1];
20110eef561a5bb10df343837d58d37d5c0d5b708243Philip Taylor      k2 = pc2 < rgba[0][2];
20120eef561a5bb10df343837d58d37d5c0d5b708243Philip Taylor      k3 = pc3 < rgba[0][3];
2013efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
2014efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_LEQUAL:
20150eef561a5bb10df343837d58d37d5c0d5b708243Philip Taylor      k0 = pc0 <= rgba[0][0];
20160eef561a5bb10df343837d58d37d5c0d5b708243Philip Taylor      k1 = pc1 <= rgba[0][1];
20170eef561a5bb10df343837d58d37d5c0d5b708243Philip Taylor      k2 = pc2 <= rgba[0][2];
20180eef561a5bb10df343837d58d37d5c0d5b708243Philip Taylor      k3 = pc3 <= rgba[0][3];
2019efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
2020efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_GREATER:
20210eef561a5bb10df343837d58d37d5c0d5b708243Philip Taylor      k0 = pc0 > rgba[0][0];
20220eef561a5bb10df343837d58d37d5c0d5b708243Philip Taylor      k1 = pc1 > rgba[0][1];
20230eef561a5bb10df343837d58d37d5c0d5b708243Philip Taylor      k2 = pc2 > rgba[0][2];
20240eef561a5bb10df343837d58d37d5c0d5b708243Philip Taylor      k3 = pc3 > rgba[0][3];
2025efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
2026efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_GEQUAL:
20270eef561a5bb10df343837d58d37d5c0d5b708243Philip Taylor      k0 = pc0 >= rgba[0][0];
20280eef561a5bb10df343837d58d37d5c0d5b708243Philip Taylor      k1 = pc1 >= rgba[0][1];
20290eef561a5bb10df343837d58d37d5c0d5b708243Philip Taylor      k2 = pc2 >= rgba[0][2];
20300eef561a5bb10df343837d58d37d5c0d5b708243Philip Taylor      k3 = pc3 >= rgba[0][3];
2031efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
2032efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_EQUAL:
20330eef561a5bb10df343837d58d37d5c0d5b708243Philip Taylor      k0 = pc0 == rgba[0][0];
20340eef561a5bb10df343837d58d37d5c0d5b708243Philip Taylor      k1 = pc1 == rgba[0][1];
20350eef561a5bb10df343837d58d37d5c0d5b708243Philip Taylor      k2 = pc2 == rgba[0][2];
20360eef561a5bb10df343837d58d37d5c0d5b708243Philip Taylor      k3 = pc3 == rgba[0][3];
2037efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
2038efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_NOTEQUAL:
20390eef561a5bb10df343837d58d37d5c0d5b708243Philip Taylor      k0 = pc0 != rgba[0][0];
20400eef561a5bb10df343837d58d37d5c0d5b708243Philip Taylor      k1 = pc1 != rgba[0][1];
20410eef561a5bb10df343837d58d37d5c0d5b708243Philip Taylor      k2 = pc2 != rgba[0][2];
20420eef561a5bb10df343837d58d37d5c0d5b708243Philip Taylor      k3 = pc3 != rgba[0][3];
2043efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
2044efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_ALWAYS:
2045efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k0 = k1 = k2 = k3 = 1;
2046efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
2047efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_NEVER:
2048efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k0 = k1 = k2 = k3 = 0;
2049efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
2050efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   default:
2051efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      k0 = k1 = k2 = k3 = 0;
2052efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      assert(0);
2053efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
2054efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   }
2055efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul
2056417aad5a992c8d7659438d20f82b4cf405c9c7b2Dave Airlie   if (sampler->mag_img_filter == PIPE_TEX_FILTER_LINEAR) {
2057417aad5a992c8d7659438d20f82b4cf405c9c7b2Dave Airlie      /* convert four pass/fail values to an intensity in [0,1] */
2058417aad5a992c8d7659438d20f82b4cf405c9c7b2Dave Airlie      val = 0.25F * (k0 + k1 + k2 + k3);
2059417aad5a992c8d7659438d20f82b4cf405c9c7b2Dave Airlie
2060417aad5a992c8d7659438d20f82b4cf405c9c7b2Dave Airlie      /* XXX returning result for default GL_DEPTH_TEXTURE_MODE = GL_LUMINANCE */
2061417aad5a992c8d7659438d20f82b4cf405c9c7b2Dave Airlie      for (j = 0; j < 4; j++) {
2062417aad5a992c8d7659438d20f82b4cf405c9c7b2Dave Airlie	 rgba[0][j] = rgba[1][j] = rgba[2][j] = val;
2063417aad5a992c8d7659438d20f82b4cf405c9c7b2Dave Airlie	 rgba[3][j] = 1.0F;
2064417aad5a992c8d7659438d20f82b4cf405c9c7b2Dave Airlie      }
2065417aad5a992c8d7659438d20f82b4cf405c9c7b2Dave Airlie   } else {
2066417aad5a992c8d7659438d20f82b4cf405c9c7b2Dave Airlie      for (j = 0; j < 4; j++) {
2067417aad5a992c8d7659438d20f82b4cf405c9c7b2Dave Airlie	 rgba[0][j] = k0;
2068417aad5a992c8d7659438d20f82b4cf405c9c7b2Dave Airlie	 rgba[1][j] = k1;
2069417aad5a992c8d7659438d20f82b4cf405c9c7b2Dave Airlie	 rgba[2][j] = k2;
2070417aad5a992c8d7659438d20f82b4cf405c9c7b2Dave Airlie	 rgba[3][j] = 1.0F;
2071417aad5a992c8d7659438d20f82b4cf405c9c7b2Dave Airlie      }
2072efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   }
2073efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul}
2074efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul
2075e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
2076e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul/**
207785425b3b609c480cd024b217b1efd0b9153bed58Brian Paul * Use 3D texcoords to choose a cube face, then sample the 2D cube faces.
207885425b3b609c480cd024b217b1efd0b9153bed58Brian Paul * Put face info into the sampler faces[] array.
20790dc4eea64f56cc93e5359372b08b99a2d600273cBrian */
2080e12810d92ffb3547680b227bf88937c03018112bBrianstatic void
20814fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellsample_cube(struct tgsi_sampler *tgsi_sampler,
20826b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard            const float s[TGSI_QUAD_SIZE],
20836b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard            const float t[TGSI_QUAD_SIZE],
20846b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard            const float p[TGSI_QUAD_SIZE],
20856b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard            const float c0[TGSI_QUAD_SIZE],
20864440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol            enum tgsi_sampler_control control,
20876b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard            float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
20880dc4eea64f56cc93e5359372b08b99a2d600273cBrian{
2089f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paul   struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
20904fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   unsigned j;
20914fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   float ssss[4], tttt[4];
209209a1b912605ff48c8782dcc5aae55ac77e27037bBrian
2093fbe3fa74e5cdaf02f3738da7d6052e1f1fd7bbf2Olivier Galibert   /* Not actually used, but the intermediate steps that do the
2094fbe3fa74e5cdaf02f3738da7d6052e1f1fd7bbf2Olivier Galibert    * dereferencing don't know it.
2095fbe3fa74e5cdaf02f3738da7d6052e1f1fd7bbf2Olivier Galibert    */
2096fbe3fa74e5cdaf02f3738da7d6052e1f1fd7bbf2Olivier Galibert   static const float pppp[4] = { 0, 0, 0, 0 };
2097fbe3fa74e5cdaf02f3738da7d6052e1f1fd7bbf2Olivier Galibert
20984fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /*
20994fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell     major axis
210085425b3b609c480cd024b217b1efd0b9153bed58Brian Paul     direction    target                             sc     tc    ma
210185425b3b609c480cd024b217b1efd0b9153bed58Brian Paul     ----------   -------------------------------    ---    ---   ---
21024fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell     +rx          TEXTURE_CUBE_MAP_POSITIVE_X_EXT    -rz    -ry   rx
21034fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell     -rx          TEXTURE_CUBE_MAP_NEGATIVE_X_EXT    +rz    -ry   rx
21044fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell     +ry          TEXTURE_CUBE_MAP_POSITIVE_Y_EXT    +rx    +rz   ry
21054fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell     -ry          TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT    +rx    -rz   ry
21064fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell     +rz          TEXTURE_CUBE_MAP_POSITIVE_Z_EXT    +rx    -ry   rz
21074fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell     -rz          TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT    -rx    -ry   rz
21084fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   */
210985425b3b609c480cd024b217b1efd0b9153bed58Brian Paul
21109ffdc78d1a308bb21a8627abb7bfc9da8abd2f81Brian Paul   /* Choose the cube face and compute new s/t coords for the 2D face.
21119ffdc78d1a308bb21a8627abb7bfc9da8abd2f81Brian Paul    *
211285425b3b609c480cd024b217b1efd0b9153bed58Brian Paul    * Use the same cube face for all four pixels in the quad.
211385425b3b609c480cd024b217b1efd0b9153bed58Brian Paul    *
211485425b3b609c480cd024b217b1efd0b9153bed58Brian Paul    * This isn't ideal, but if we want to use a different cube face
211585425b3b609c480cd024b217b1efd0b9153bed58Brian Paul    * per pixel in the quad, we'd have to also compute the per-face
211685425b3b609c480cd024b217b1efd0b9153bed58Brian Paul    * LOD here too.  That's because the four post-face-selection
211785425b3b609c480cd024b217b1efd0b9153bed58Brian Paul    * texcoords are no longer related to each other (they're
211885425b3b609c480cd024b217b1efd0b9153bed58Brian Paul    * per-face!)  so we can't use subtraction to compute the partial
211985425b3b609c480cd024b217b1efd0b9153bed58Brian Paul    * deriviates to compute the LOD.  Doing so (near cube edges
212085425b3b609c480cd024b217b1efd0b9153bed58Brian Paul    * anyway) gives us pretty much random values.
212185425b3b609c480cd024b217b1efd0b9153bed58Brian Paul    */
212285425b3b609c480cd024b217b1efd0b9153bed58Brian Paul   {
212385425b3b609c480cd024b217b1efd0b9153bed58Brian Paul      /* use the average of the four pixel's texcoords to choose the face */
2124b82db9a3c0a1b96d8eb5d0d78aecaf0ab331431aBrian Paul      const float rx = 0.25F * (s[0] + s[1] + s[2] + s[3]);
2125b82db9a3c0a1b96d8eb5d0d78aecaf0ab331431aBrian Paul      const float ry = 0.25F * (t[0] + t[1] + t[2] + t[3]);
2126b82db9a3c0a1b96d8eb5d0d78aecaf0ab331431aBrian Paul      const float rz = 0.25F * (p[0] + p[1] + p[2] + p[3]);
21274fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz);
21284fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
2129890679d4322e7ba4f12f32532a3fdd277edff886Keith Whitwell      if (arx >= ary && arx >= arz) {
2130c72a3b4f2ffe0673e753ad144d1b5557a42c670fBrian Paul         float sign = (rx >= 0.0F) ? 1.0F : -1.0F;
2131c72a3b4f2ffe0673e753ad144d1b5557a42c670fBrian Paul         uint face = (rx >= 0.0F) ? PIPE_TEX_FACE_POS_X : PIPE_TEX_FACE_NEG_X;
21326b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard         for (j = 0; j < TGSI_QUAD_SIZE; j++) {
2133c72a3b4f2ffe0673e753ad144d1b5557a42c670fBrian Paul            const float ima = -0.5F / fabsf(s[j]);
2134c72a3b4f2ffe0673e753ad144d1b5557a42c670fBrian Paul            ssss[j] = sign *  p[j] * ima + 0.5F;
2135c72a3b4f2ffe0673e753ad144d1b5557a42c670fBrian Paul            tttt[j] =         t[j] * ima + 0.5F;
2136c72a3b4f2ffe0673e753ad144d1b5557a42c670fBrian Paul            samp->faces[j] = face;
21374fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         }
21384fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      }
2139890679d4322e7ba4f12f32532a3fdd277edff886Keith Whitwell      else if (ary >= arx && ary >= arz) {
2140c72a3b4f2ffe0673e753ad144d1b5557a42c670fBrian Paul         float sign = (ry >= 0.0F) ? 1.0F : -1.0F;
2141c72a3b4f2ffe0673e753ad144d1b5557a42c670fBrian Paul         uint face = (ry >= 0.0F) ? PIPE_TEX_FACE_POS_Y : PIPE_TEX_FACE_NEG_Y;
21426b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard         for (j = 0; j < TGSI_QUAD_SIZE; j++) {
2143c72a3b4f2ffe0673e753ad144d1b5557a42c670fBrian Paul            const float ima = -0.5F / fabsf(t[j]);
2144c72a3b4f2ffe0673e753ad144d1b5557a42c670fBrian Paul            ssss[j] =        -s[j] * ima + 0.5F;
2145c72a3b4f2ffe0673e753ad144d1b5557a42c670fBrian Paul            tttt[j] = sign * -p[j] * ima + 0.5F;
2146c72a3b4f2ffe0673e753ad144d1b5557a42c670fBrian Paul            samp->faces[j] = face;
21474fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         }
21484fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      }
21494fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      else {
2150c72a3b4f2ffe0673e753ad144d1b5557a42c670fBrian Paul         float sign = (rz >= 0.0F) ? 1.0F : -1.0F;
2151c72a3b4f2ffe0673e753ad144d1b5557a42c670fBrian Paul         uint face = (rz >= 0.0F) ? PIPE_TEX_FACE_POS_Z : PIPE_TEX_FACE_NEG_Z;
21526b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard         for (j = 0; j < TGSI_QUAD_SIZE; j++) {
2153b82db9a3c0a1b96d8eb5d0d78aecaf0ab331431aBrian Paul            const float ima = -0.5F / fabsf(p[j]);
2154c72a3b4f2ffe0673e753ad144d1b5557a42c670fBrian Paul            ssss[j] = sign * -s[j] * ima + 0.5F;
2155c72a3b4f2ffe0673e753ad144d1b5557a42c670fBrian Paul            tttt[j] =         t[j] * ima + 0.5F;
2156c72a3b4f2ffe0673e753ad144d1b5557a42c670fBrian Paul            samp->faces[j] = face;
21574fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         }
21584fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      }
215985425b3b609c480cd024b217b1efd0b9153bed58Brian Paul   }
216085425b3b609c480cd024b217b1efd0b9153bed58Brian Paul
21614fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* In our little pipeline, the compare stage is next.  If compare
21624fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell    * is not active, this will point somewhere deeper into the
21634fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell    * pipeline, eg. to mip_filter or even img_filter.
21646142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell    */
2165fbe3fa74e5cdaf02f3738da7d6052e1f1fd7bbf2Olivier Galibert   samp->compare(tgsi_sampler, ssss, tttt, pppp, c0, control, rgba);
21664fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
2167612cfb749c3526eeb446bbc631bf24716522f373Brian
2168b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul
2169b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paulstatic void
2170b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Pauldo_swizzling(const struct sp_sampler_variant *samp,
2171b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul             float in[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE],
2172b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul             float out[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
2173c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul{
2174e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie   int j;
2175c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   const unsigned swizzle_r = samp->key.bits.swizzle_r;
2176c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   const unsigned swizzle_g = samp->key.bits.swizzle_g;
2177c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   const unsigned swizzle_b = samp->key.bits.swizzle_b;
2178c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   const unsigned swizzle_a = samp->key.bits.swizzle_a;
2179c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul
2180c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   switch (swizzle_r) {
2181c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   case PIPE_SWIZZLE_ZERO:
2182c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2183e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[0][j] = 0.0f;
2184c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      break;
2185c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   case PIPE_SWIZZLE_ONE:
2186c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2187e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[0][j] = 1.0f;
2188c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      break;
2189c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   default:
2190c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      assert(swizzle_r < 4);
2191c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2192e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[0][j] = in[swizzle_r][j];
2193c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   }
2194c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul
2195c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   switch (swizzle_g) {
2196c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   case PIPE_SWIZZLE_ZERO:
2197c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2198e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[1][j] = 0.0f;
2199c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      break;
2200c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   case PIPE_SWIZZLE_ONE:
2201c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2202e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[1][j] = 1.0f;
2203c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      break;
2204c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   default:
2205c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      assert(swizzle_g < 4);
2206c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2207e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[1][j] = in[swizzle_g][j];
2208c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   }
2209c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul
2210c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   switch (swizzle_b) {
2211c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   case PIPE_SWIZZLE_ZERO:
2212c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2213e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[2][j] = 0.0f;
2214c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      break;
2215c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   case PIPE_SWIZZLE_ONE:
2216c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2217e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[2][j] = 1.0f;
2218c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      break;
2219c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   default:
2220c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      assert(swizzle_b < 4);
2221c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2222e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[2][j] = in[swizzle_b][j];
2223c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   }
2224c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul
2225c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   switch (swizzle_a) {
2226c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   case PIPE_SWIZZLE_ZERO:
2227c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2228e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[3][j] = 0.0f;
2229c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      break;
2230c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   case PIPE_SWIZZLE_ONE:
2231c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2232e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[3][j] = 1.0f;
2233c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      break;
2234c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   default:
2235c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      assert(swizzle_a < 4);
2236c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2237e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[3][j] = in[swizzle_a][j];
2238c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   }
2239c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul}
2240c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul
2241b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul
2242e809b7a6787e40f974883104606550fb3d53ba47Dave Airliestatic void
2243e809b7a6787e40f974883104606550fb3d53ba47Dave Airliesample_swizzle(struct tgsi_sampler *tgsi_sampler,
22446b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard               const float s[TGSI_QUAD_SIZE],
22456b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard               const float t[TGSI_QUAD_SIZE],
22466b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard               const float p[TGSI_QUAD_SIZE],
22476b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard               const float c0[TGSI_QUAD_SIZE],
2248e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie               enum tgsi_sampler_control control,
22496b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard               float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
2250e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie{
2251e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie   struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
22526b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float rgba_temp[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
2253e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie
2254e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie   samp->sample_target(tgsi_sampler, s, t, p, c0, control, rgba_temp);
2255e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie
2256e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie   do_swizzling(samp, rgba_temp, rgba);
2257e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie}
2258e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie
22593d8c05f7320151898dd224c1daaf3118e1f7ea34Brian
2260e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paulstatic wrap_nearest_func
2261e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paulget_nearest_unorm_wrap(unsigned mode)
22624fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
22634fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   switch (mode) {
22644fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP:
22654fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_unorm_clamp;
22664fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
2267b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul      return wrap_nearest_unorm_clamp_to_edge;
22684fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
22694fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_unorm_clamp_to_border;
22700dc4eea64f56cc93e5359372b08b99a2d600273cBrian   default:
22710dc4eea64f56cc93e5359372b08b99a2d600273cBrian      assert(0);
22724fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_unorm_clamp;
22730dc4eea64f56cc93e5359372b08b99a2d600273cBrian   }
22740dc4eea64f56cc93e5359372b08b99a2d600273cBrian}
227534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
227634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
2277e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paulstatic wrap_nearest_func
2278e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paulget_nearest_wrap(unsigned mode)
2279a34b8594b7b2d00404bb639621ec1ce918ba0786Brian{
22804fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   switch (mode) {
22814fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_REPEAT:
22824fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_repeat;
22834fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP:
22844fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_clamp;
22854fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
22864fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_clamp_to_edge;
22874fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
22884fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_clamp_to_border;
22894fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_MIRROR_REPEAT:
22904fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_mirror_repeat;
22914fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_MIRROR_CLAMP:
22924fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_mirror_clamp;
22934fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
22944fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_mirror_clamp_to_edge;
22954fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
22964fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_mirror_clamp_to_border;
22974fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   default:
22984fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      assert(0);
22994fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_repeat;
23004fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   }
2301a34b8594b7b2d00404bb639621ec1ce918ba0786Brian}
2302a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
2303e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
2304e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paulstatic wrap_linear_func
2305e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paulget_linear_unorm_wrap(unsigned mode)
2306a34b8594b7b2d00404bb639621ec1ce918ba0786Brian{
23074fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   switch (mode) {
23084fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP:
23094fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_unorm_clamp;
23104fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
2311b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul      return wrap_linear_unorm_clamp_to_edge;
23124fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
23134fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_unorm_clamp_to_border;
23144fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   default:
23154fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      assert(0);
23164fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_unorm_clamp;
23174fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   }
2318a34b8594b7b2d00404bb639621ec1ce918ba0786Brian}
2319a34b8594b7b2d00404bb639621ec1ce918ba0786Brian
2320e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
2321e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paulstatic wrap_linear_func
2322e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paulget_linear_wrap(unsigned mode)
232334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
23244fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   switch (mode) {
23254fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_REPEAT:
23264fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_repeat;
23274fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP:
23284fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_clamp;
23294fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
23304fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_clamp_to_edge;
23314fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
23324fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_clamp_to_border;
23334fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_MIRROR_REPEAT:
23344fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_mirror_repeat;
23354fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_MIRROR_CLAMP:
23364fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_mirror_clamp;
23374fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
23384fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_mirror_clamp_to_edge;
23394fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
23404fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_mirror_clamp_to_border;
23413d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   default:
23423d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian      assert(0);
23434fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_repeat;
23443d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian   }
234534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
234634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
2347e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
234807f5dabc01e9a85073ffd333c37549ec5ae75c7aBrian Paul/**
234907f5dabc01e9a85073ffd333c37549ec5ae75c7aBrian Paul * Is swizzling needed for the given state key?
235007f5dabc01e9a85073ffd333c37549ec5ae75c7aBrian Paul */
235107f5dabc01e9a85073ffd333c37549ec5ae75c7aBrian Paulstatic INLINE bool
235207f5dabc01e9a85073ffd333c37549ec5ae75c7aBrian Paulany_swizzle(union sp_sampler_key key)
235307f5dabc01e9a85073ffd333c37549ec5ae75c7aBrian Paul{
235407f5dabc01e9a85073ffd333c37549ec5ae75c7aBrian Paul   return (key.bits.swizzle_r != PIPE_SWIZZLE_RED ||
235507f5dabc01e9a85073ffd333c37549ec5ae75c7aBrian Paul           key.bits.swizzle_g != PIPE_SWIZZLE_GREEN ||
235607f5dabc01e9a85073ffd333c37549ec5ae75c7aBrian Paul           key.bits.swizzle_b != PIPE_SWIZZLE_BLUE ||
235707f5dabc01e9a85073ffd333c37549ec5ae75c7aBrian Paul           key.bits.swizzle_a != PIPE_SWIZZLE_ALPHA);
235807f5dabc01e9a85073ffd333c37549ec5ae75c7aBrian Paul}
235907f5dabc01e9a85073ffd333c37549ec5ae75c7aBrian Paul
236007f5dabc01e9a85073ffd333c37549ec5ae75c7aBrian Paul
2361e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paulstatic compute_lambda_func
2362e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paulget_lambda_func(const union sp_sampler_key key)
236334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
23644fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   if (key.bits.processor == TGSI_PROCESSOR_VERTEX)
23654fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return compute_lambda_vert;
23664fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
23674fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   switch (key.bits.target) {
23684fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEXTURE_1D:
2369779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   case PIPE_TEXTURE_1D_ARRAY:
23704fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return compute_lambda_1d;
23714fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEXTURE_2D:
2372779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   case PIPE_TEXTURE_2D_ARRAY:
2373ae0ef6f69f351cacdc7eaa9b21097a7c1b414e44Luca Barbieri   case PIPE_TEXTURE_RECT:
237487ec83afd58536c31bf02c307f1d5488abc84861Brian Paul   case PIPE_TEXTURE_CUBE:
23754fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return compute_lambda_2d;
23764fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEXTURE_3D:
23774fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return compute_lambda_3d;
23784fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   default:
23794fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      assert(0);
23804fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return compute_lambda_1d;
2381b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian   }
238234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
238334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian
2384e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
2385229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertstatic img_filter_func
2386e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paulget_img_filter(const union sp_sampler_key key,
2387e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul               unsigned filter,
2388e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul               const struct pipe_sampler_state *sampler)
2389b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{
23904fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   switch (key.bits.target) {
23914fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEXTURE_1D:
23924fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      if (filter == PIPE_TEX_FILTER_NEAREST)
23934fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         return img_filter_1d_nearest;
23944fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      else
23954fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         return img_filter_1d_linear;
2396b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      break;
2397779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   case PIPE_TEXTURE_1D_ARRAY:
2398779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul      if (filter == PIPE_TEX_FILTER_NEAREST)
2399779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul         return img_filter_1d_array_nearest;
2400779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul      else
2401779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul         return img_filter_1d_array_linear;
2402779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul      break;
24034fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEXTURE_2D:
2404ae0ef6f69f351cacdc7eaa9b21097a7c1b414e44Luca Barbieri   case PIPE_TEXTURE_RECT:
24054fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      /* Try for fast path:
24064fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell       */
24074fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      if (key.bits.is_pot &&
24084fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell          sampler->wrap_s == sampler->wrap_t &&
24094fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell          sampler->normalized_coords)
241038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian      {
24114fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         switch (sampler->wrap_s) {
24124fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         case PIPE_TEX_WRAP_REPEAT:
24134fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell            switch (filter) {
24146142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell            case PIPE_TEX_FILTER_NEAREST:
24154fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell               return img_filter_2d_nearest_repeat_POT;
24166142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell            case PIPE_TEX_FILTER_LINEAR:
24174fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell               return img_filter_2d_linear_repeat_POT;
24186142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell            default:
24196142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell               break;
242038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            }
24214fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell            break;
24224fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         case PIPE_TEX_WRAP_CLAMP:
24234fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell            switch (filter) {
24246142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell            case PIPE_TEX_FILTER_NEAREST:
24254fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell               return img_filter_2d_nearest_clamp_POT;
24266142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell            default:
24276142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell               break;
242838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian            }
2429b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian         }
2430b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      }
243160adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell      /* Otherwise use default versions:
24324fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell       */
24334fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      if (filter == PIPE_TEX_FILTER_NEAREST)
24344fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         return img_filter_2d_nearest;
24354fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      else
24364fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         return img_filter_2d_linear;
24374fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      break;
2438779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   case PIPE_TEXTURE_2D_ARRAY:
2439779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul      if (filter == PIPE_TEX_FILTER_NEAREST)
2440779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul         return img_filter_2d_array_nearest;
2441779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul      else
2442779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul         return img_filter_2d_array_linear;
2443779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul      break;
244460adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell   case PIPE_TEXTURE_CUBE:
244560adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell      if (filter == PIPE_TEX_FILTER_NEAREST)
244660adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell         return img_filter_cube_nearest;
244760adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell      else
244860adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell         return img_filter_cube_linear;
244960adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell      break;
24504fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEXTURE_3D:
24514fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      if (filter == PIPE_TEX_FILTER_NEAREST)
24524fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         return img_filter_3d_nearest;
24534fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      else
24544fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         return img_filter_3d_linear;
2455b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      break;
2456b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   default:
2457b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      assert(0);
24584fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return img_filter_1d_nearest;
2459b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian   }
2460b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian}
2461b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
2462b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian
2463a34b8594b7b2d00404bb639621ec1ce918ba0786Brian/**
2464f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paul * Bind the given texture object and texture cache to the sampler variant.
2465a34b8594b7b2d00404bb639621ec1ce918ba0786Brian */
24664fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellvoid
246721148e6a8806736b4487da41b01e2d3c01cbc743Henri Verbeetsp_sampler_variant_bind_view( struct sp_sampler_variant *samp,
246821148e6a8806736b4487da41b01e2d3c01cbc743Henri Verbeet                              struct softpipe_tex_tile_cache *tex_cache,
246921148e6a8806736b4487da41b01e2d3c01cbc743Henri Verbeet                              const struct pipe_sampler_view *view )
247034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{
247121148e6a8806736b4487da41b01e2d3c01cbc743Henri Verbeet   const struct pipe_resource *texture = view->texture;
24724fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
247321148e6a8806736b4487da41b01e2d3c01cbc743Henri Verbeet   samp->view = view;
24744fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   samp->cache = tex_cache;
2475c5ac8a8aa2a9fe751453c1fcc8539b7dae5d473cMatt Turner   samp->xpot = util_logbase2( texture->width0 );
2476c5ac8a8aa2a9fe751453c1fcc8539b7dae5d473cMatt Turner   samp->ypot = util_logbase2( texture->height0 );
24774fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
24780b9e96fae9493d5d58f046e01c983a3c4267090eBrian
24794f23468bd0d14b8ed687a641003d587b91ad39a7Brian
2480ecfa8be150ed276af816467b467e76e026f5b541Keith Whitwellvoid
2481f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paulsp_sampler_variant_destroy( struct sp_sampler_variant *samp )
2482ecfa8be150ed276af816467b467e76e026f5b541Keith Whitwell{
2483ecfa8be150ed276af816467b467e76e026f5b541Keith Whitwell   FREE(samp);
2484ecfa8be150ed276af816467b467e76e026f5b541Keith Whitwell}
2485ecfa8be150ed276af816467b467e76e026f5b541Keith Whitwell
2486b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul
2487461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airliestatic void
2488461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airliesample_get_dims(struct tgsi_sampler *tgsi_sampler, int level,
2489461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie		int dims[4])
2490461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie{
2491461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie    struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
2492461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie    const struct pipe_sampler_view *view = samp->view;
2493461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie    const struct pipe_resource *texture = view->texture;
2494461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie
2495461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie    /* undefined according to EXT_gpu_program */
2496461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie    level += view->u.tex.first_level;
2497461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie    if (level > view->u.tex.last_level)
2498461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie	return;
2499461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie
2500461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie    dims[0] = u_minify(texture->width0, level);
2501461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie
2502461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie    switch(texture->target) {
2503461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie    case PIPE_TEXTURE_1D_ARRAY:
2504461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie       dims[1] = texture->array_size;
2505461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie       /* fallthrough */
2506461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie    case PIPE_TEXTURE_1D:
2507461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie    case PIPE_BUFFER:
2508461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie       return;
2509461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie    case PIPE_TEXTURE_2D_ARRAY:
2510461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie       dims[2] = texture->array_size;
2511461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie       /* fallthrough */
2512461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie    case PIPE_TEXTURE_2D:
2513461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie    case PIPE_TEXTURE_CUBE:
2514461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie    case PIPE_TEXTURE_RECT:
2515461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie       dims[1] = u_minify(texture->height0, level);
2516461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie       return;
2517461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie    case PIPE_TEXTURE_3D:
2518461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie       dims[1] = u_minify(texture->height0, level);
2519461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie       dims[2] = u_minify(texture->depth0, level);
2520461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie       return;
2521461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie    default:
2522461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie       assert(!"unexpected texture target in sample_get_dims()");
2523461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie       return;
2524461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie    }
2525461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie}
2526ecfa8be150ed276af816467b467e76e026f5b541Keith Whitwell
252792d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul/**
252892d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul * This function is only used for getting unfiltered texels via the
252992d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul * TXF opcode.  The GL spec says that out-of-bounds texel fetches
253092d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul * produce undefined results.  Instead of crashing, lets just clamp
253192d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul * coords to the texture image size.
253292d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul */
253362ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airliestatic void
253462ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airliesample_get_texels(struct tgsi_sampler *tgsi_sampler,
2535b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul                  const int v_i[TGSI_QUAD_SIZE],
2536b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul                  const int v_j[TGSI_QUAD_SIZE],
2537b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul                  const int v_k[TGSI_QUAD_SIZE],
2538b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul                  const int lod[TGSI_QUAD_SIZE],
2539b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul                  const int8_t offset[3],
2540b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul                  float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
254162ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie{
254262ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
254362ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   union tex_tile_address addr;
254462ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   const struct pipe_resource *texture = samp->view->texture;
254562ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   int j, c;
2546e3a7cb4a6c94efe250c0212f062930e2026a861dBrian Paul   const float *tx;
254707f5dabc01e9a85073ffd333c37549ec5ae75c7aBrian Paul   const bool need_swizzle = any_swizzle(samp->key);
254892d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul   int width, height, depth, layers;
254962ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie
255062ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   addr.value = 0;
255162ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   /* TODO write a better test for LOD */
255262ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   addr.bits.level = lod[0];
255362ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie
255492d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul   width = u_minify(texture->width0, addr.bits.level);
255592d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul   height = u_minify(texture->height0, addr.bits.level);
255692d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul   depth = u_minify(texture->depth0, addr.bits.level);
255792d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul   layers = texture->array_size;
255892d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul
255962ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   switch(texture->target) {
256062ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   case PIPE_TEXTURE_1D:
25616b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
256292d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul         int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
256392d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul	 tx = get_texel_2d(samp, addr, x, 0);
256462ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie	 for (c = 0; c < 4; c++) {
256562ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie	    rgba[c][j] = tx[c];
256662ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie	 }
256762ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      }
256862ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      break;
256962ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   case PIPE_TEXTURE_1D_ARRAY:
25706b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
257192d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul         int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
2572cfc5b3094163bc5c945594903d90f21873bb5d66Olivier Galibert         int y = CLAMP(v_j[j], 0, layers - 1);
257392d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul	 tx = get_texel_1d_array(samp, addr, x, y);
257462ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie	 for (c = 0; c < 4; c++) {
257562ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie	    rgba[c][j] = tx[c];
257662ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie	 }
257762ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      }
257862ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      break;
257962ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   case PIPE_TEXTURE_2D:
258062ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   case PIPE_TEXTURE_RECT:
25816b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
258292d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul         int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
258392d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul         int y = CLAMP(v_j[j] + offset[1], 0, height - 1);
258492d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul	 tx = get_texel_2d(samp, addr, x, y);
258562ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie	 for (c = 0; c < 4; c++) {
258662ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie	    rgba[c][j] = tx[c];
258762ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie	 }
258862ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      }
258962ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      break;
259062ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   case PIPE_TEXTURE_2D_ARRAY:
25916b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
259292d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul         int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
259392d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul         int y = CLAMP(v_j[j] + offset[1], 0, height - 1);
2594cfc5b3094163bc5c945594903d90f21873bb5d66Olivier Galibert         int layer = CLAMP(v_k[j], 0, layers - 1);
259592d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul	 tx = get_texel_2d_array(samp, addr, x, y, layer);
259662ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie	 for (c = 0; c < 4; c++) {
259762ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie	    rgba[c][j] = tx[c];
259862ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie	 }
259962ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      }
260062ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      break;
260162ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   case PIPE_TEXTURE_3D:
26026b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
260392d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul         int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
260492d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul         int y = CLAMP(v_j[j] + offset[1], 0, height - 1);
260592d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul         int z = CLAMP(v_k[j] + offset[2], 0, depth - 1);
260692d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul
260792d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul	 tx = get_texel_3d(samp, addr, x, y, z);
260862ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie	 for (c = 0; c < 4; c++) {
260962ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie	    rgba[c][j] = tx[c];
261062ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie	 }
261162ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      }
261262ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      break;
261362ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   case PIPE_TEXTURE_CUBE: /* TXF can't work on CUBE according to spec */
261462ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   default:
261562ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      assert(!"Unknown or CUBE texture type in TXF processing\n");
261662ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      break;
261762ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   }
2618e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie
2619e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie   if (need_swizzle) {
26206b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard      float rgba_temp[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
2621e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie      memcpy(rgba_temp, rgba, sizeof(rgba_temp));
2622e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie      do_swizzling(samp, rgba_temp, rgba);
2623e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie   }
262462ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie}
2625b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul
2626b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul
2627e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul/**
2628f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paul * Create a sampler variant for a given set of non-orthogonal state.
26294fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell */
2630f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paulstruct sp_sampler_variant *
2631f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paulsp_create_sampler_variant( const struct pipe_sampler_state *sampler,
26324fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell                           const union sp_sampler_key key )
26334fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
2634f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paul   struct sp_sampler_variant *samp = CALLOC_STRUCT(sp_sampler_variant);
26354fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   if (!samp)
26364fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return NULL;
26374fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
26384fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   samp->sampler = sampler;
26394fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   samp->key = key;
26404fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
26414fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* Note that (for instance) linear_texcoord_s and
26424fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell    * nearest_texcoord_s may be active at the same time, if the
26434fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell    * sampler min_img_filter differs from its mag_img_filter.
26444fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell    */
26454fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   if (sampler->normalized_coords) {
26464fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->linear_texcoord_s = get_linear_wrap( sampler->wrap_s );
26474fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->linear_texcoord_t = get_linear_wrap( sampler->wrap_t );
26484fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->linear_texcoord_p = get_linear_wrap( sampler->wrap_r );
26494fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
26504fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->nearest_texcoord_s = get_nearest_wrap( sampler->wrap_s );
26514fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->nearest_texcoord_t = get_nearest_wrap( sampler->wrap_t );
26524fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->nearest_texcoord_p = get_nearest_wrap( sampler->wrap_r );
26534fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   }
26544fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   else {
26554fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->linear_texcoord_s = get_linear_unorm_wrap( sampler->wrap_s );
26564fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->linear_texcoord_t = get_linear_unorm_wrap( sampler->wrap_t );
26574fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->linear_texcoord_p = get_linear_unorm_wrap( sampler->wrap_r );
26584fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
26594fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->nearest_texcoord_s = get_nearest_unorm_wrap( sampler->wrap_s );
26604fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->nearest_texcoord_t = get_nearest_unorm_wrap( sampler->wrap_t );
26614fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->nearest_texcoord_p = get_nearest_unorm_wrap( sampler->wrap_r );
26624fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   }
26634fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
26644fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   samp->compute_lambda = get_lambda_func( key );
26654fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
26664fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   samp->min_img_filter = get_img_filter(key, sampler->min_img_filter, sampler);
266741483627f0fd3dc9df2cc55dfd5f3e5987fcfd22Brian Paul   samp->mag_img_filter = get_img_filter(key, sampler->mag_img_filter, sampler);
26684fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
26694fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   switch (sampler->min_mip_filter) {
26704fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_MIPFILTER_NONE:
26714fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      if (sampler->min_img_filter == sampler->mag_img_filter)
2672229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         samp->mip_filter = mip_filter_none_no_filter_select;
2673b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian      else
26744fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         samp->mip_filter = mip_filter_none;
267534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
26764fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
26774fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_MIPFILTER_NEAREST:
26784fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->mip_filter = mip_filter_nearest;
267934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
26804fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
26814fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_MIPFILTER_LINEAR:
26824fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      if (key.bits.is_pot &&
268371e3ee38aca50b6954cc7e341aa082797741f02dRoland Scheidegger          key.bits.target == PIPE_TEXTURE_2D &&
26844fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell          sampler->min_img_filter == sampler->mag_img_filter &&
26854fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell          sampler->normalized_coords &&
26864fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell          sampler->wrap_s == PIPE_TEX_WRAP_REPEAT &&
2687cf102b031e7ef33c8e3ffce2f9dcd064f44e8190Brian Paul          sampler->wrap_t == PIPE_TEX_WRAP_REPEAT &&
2688f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger          sampler->min_img_filter == PIPE_TEX_FILTER_LINEAR) {
26894fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         samp->mip_filter = mip_filter_linear_2d_linear_repeat_POT;
26904fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      }
2691f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      else {
26924fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         samp->mip_filter = mip_filter_linear;
26936142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      }
2694f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
2695f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      /* Anisotropic filtering extension. */
2696f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      if (sampler->max_anisotropy > 1) {
2697f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      	samp->mip_filter = mip_filter_linear_aniso;
2698f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
2699f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      	/* Override min_img_filter:
2700f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      	 * min_img_filter needs to be set to NEAREST since we need to access
2701f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      	 * each texture pixel as it is and weight it later; using linear
2702f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      	 * filters will have incorrect results.
2703f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      	 * By setting the filter to NEAREST here, we can avoid calling the
2704f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      	 * generic img_filter_2d_nearest in the anisotropic filter function,
2705f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      	 * making it possible to use one of the accelerated implementations
2706f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      	 */
2707f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      	samp->min_img_filter = get_img_filter(key, PIPE_TEX_FILTER_NEAREST, sampler);
2708f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
2709f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      	/* on first access create the lookup table containing the filter weights. */
2710f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger        if (!weightLut) {
2711f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger           create_filter_table();
2712f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger        }
2713f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger      }
2714f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Faenger
271534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian      break;
271634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian   }
27173d53d38d5e35386de4793162b9dd32e171927059Brian Paul
27184e014c0a148ba3ac015d0e83dcf975ca6e814e1fMichal Krol   if (sampler->compare_mode != PIPE_TEX_COMPARE_NONE) {
27194fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->compare = sample_compare;
27203d53d38d5e35386de4793162b9dd32e171927059Brian Paul   }
27214fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   else {
27224fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      /* Skip compare operation by promoting the mip_filter function
27234fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell       * pointer:
27244fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell       */
27254fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->compare = samp->mip_filter;
27264fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   }
27274fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
27284fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   if (key.bits.target == PIPE_TEXTURE_CUBE) {
2729c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      samp->sample_target = sample_cube;
27304fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   }
27314fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   else {
27324fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->faces[0] = 0;
27334fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->faces[1] = 0;
27344fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->faces[2] = 0;
27354fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->faces[3] = 0;
27364fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
27374fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      /* Skip cube face determination by promoting the compare
27384fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell       * function pointer:
27394fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell       */
2740c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      samp->sample_target = samp->compare;
2741c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   }
2742c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul
274307f5dabc01e9a85073ffd333c37549ec5ae75c7aBrian Paul   if (any_swizzle(key)) {
2744c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      samp->base.get_samples = sample_swizzle;
2745c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   }
2746c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   else {
2747c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      samp->base.get_samples = samp->sample_target;
27486142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   }
27496142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
2750461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie   samp->base.get_dims = sample_get_dims;
275162ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   samp->base.get_texel = sample_get_texels;
27524fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   return samp;
275334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian}
2754