sp_tex_sample.c revision 3f5c67d6510fe0210079ddecc0d30227a6cc4111
10dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul/**************************************************************************
20dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul *
3877128505431adaf817dc8069172ebe4a1cdf5d8José Fonseca * Copyright 2007 VMware, Inc.
40dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * All Rights Reserved.
54bfe1c955fe679547c8a03119d1681e33593c768Michal Krol * Copyright 2008-2010 VMware, Inc.  All rights reserved.
60dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul *
70dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * Permission is hereby granted, free of charge, to any person obtaining a
80dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * copy of this software and associated documentation files (the
90dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * "Software"), to deal in the Software without restriction, including
100dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * without limitation the rights to use, copy, modify, merge, publish,
110dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * distribute, sub license, and/or sell copies of the Software, and to
120dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * permit persons to whom the Software is furnished to do so, subject to
130dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * the following conditions:
140dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul *
150dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * The above copyright notice and this permission notice (including the
160dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * next paragraph) shall be included in all copies or substantial portions
170dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * of the Software.
180dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul *
190dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
200dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
210dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22877128505431adaf817dc8069172ebe4a1cdf5d8José Fonseca * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
230dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
240dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
250dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
260dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul *
270dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul **************************************************************************/
280dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul
290dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul/**
300dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * Texture sampling
310dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul *
320dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * Authors:
330dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul *   Brian Paul
344fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell *   Keith Whitwell
350dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul */
360dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul
370dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul#include "pipe/p_context.h"
380dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul#include "pipe/p_defines.h"
3900c835918259f8d41c3f74eca679a972713b11b2Keith Whitwell#include "pipe/p_shader_tokens.h"
401a46dcc8a927dfb38ca1381e7b3dafb789f8257cBrian Paul#include "util/u_math.h"
41a6256f1e678cf72a2c0cb407a2118afa92bd1b20Dave Airlie#include "util/u_format.h"
424f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h"
43ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger#include "util/u_inlines.h"
44d204659c8c725c02212ad4a49275c7447f2d02a6Brian Paul#include "sp_quad.h"   /* only for #define QUAD_* tokens */
45d204659c8c725c02212ad4a49275c7447f2d02a6Brian Paul#include "sp_tex_sample.h"
46ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger#include "sp_texture.h"
477670102468a55de50cf0cfa0b938d36aaf212f1fKeith Whitwell#include "sp_tex_tile_cache.h"
480dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul
490dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul
504250882ccf8326ba9074c671110370534489caa6Brian Paul/** Set to one to help debug texture sampling */
514250882ccf8326ba9074c671110370534489caa6Brian Paul#define DEBUG_TEX 0
524250882ccf8326ba9074c671110370534489caa6Brian Paul
533ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul
5408f33a025100dea2d951e6d628891fe294b18082Brian Paul/*
55b4a40d10524a4be6a59805589ee4209ebdb1de4fBrian Paul * Return fractional part of 'f'.  Used for computing interpolation weights.
56b4a40d10524a4be6a59805589ee4209ebdb1de4fBrian Paul * Need to be careful with negative values.
57b4a40d10524a4be6a59805589ee4209ebdb1de4fBrian Paul * Note, if this function isn't perfect you'll sometimes see 1-pixel bands
58b4a40d10524a4be6a59805589ee4209ebdb1de4fBrian Paul * of improperly weighted linear-filtered textures.
5908f33a025100dea2d951e6d628891fe294b18082Brian Paul * The tests/texwrap.c demo is a good test.
6008f33a025100dea2d951e6d628891fe294b18082Brian Paul */
61b4a40d10524a4be6a59805589ee4209ebdb1de4fBrian Paulstatic INLINE float
62b4a40d10524a4be6a59805589ee4209ebdb1de4fBrian Paulfrac(float f)
63b4a40d10524a4be6a59805589ee4209ebdb1de4fBrian Paul{
64b37c54150058c07ab2d3db2d7e5891a457b51e76Brian Paul   return f - floorf(f);
65b4a40d10524a4be6a59805589ee4209ebdb1de4fBrian Paul}
66b4a40d10524a4be6a59805589ee4209ebdb1de4fBrian Paul
6708f33a025100dea2d951e6d628891fe294b18082Brian Paul
6808f33a025100dea2d951e6d628891fe294b18082Brian Paul
6908f33a025100dea2d951e6d628891fe294b18082Brian Paul/**
7008f33a025100dea2d951e6d628891fe294b18082Brian Paul * Linear interpolation macro
7108f33a025100dea2d951e6d628891fe294b18082Brian Paul */
7238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paulstatic INLINE float
7338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paullerp(float a, float v0, float v1)
7438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul{
7538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul   return v0 + a * (v1 - v0);
7638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul}
770dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul
780dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul
790dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul/**
80fd60bf8e33bbcba7b7749ae5a4285bad60769b9bBrian Paul * Do 2D/bilinear interpolation of float values.
810dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * v00, v10, v01 and v11 are typically four texture samples in a square/box.
820dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * a and b are the horizontal and vertical interpolants.
830dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * It's important that this function is inlined when compiled with
840dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * optimization!  If we find that's not true on some systems, convert
850dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * to a macro.
860dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul */
87b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paulstatic INLINE float
88b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paullerp_2d(float a, float b,
89b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul        float v00, float v10, float v01, float v11)
900dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul{
9138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul   const float temp0 = lerp(a, v00, v10);
9238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul   const float temp1 = lerp(a, v01, v11);
9338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul   return lerp(b, temp0, temp1);
9438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul}
9538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul
9638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul
9738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul/**
9838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul * As above, but 3D interpolation of 8 values.
9938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul */
10038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paulstatic INLINE float
10138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paullerp_3d(float a, float b, float c,
10238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul        float v000, float v100, float v010, float v110,
10338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul        float v001, float v101, float v011, float v111)
10438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul{
10538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul   const float temp0 = lerp_2d(a, b, v000, v100, v010, v110);
10638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul   const float temp1 = lerp_2d(a, b, v001, v101, v011, v111);
10738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul   return lerp(c, temp0, temp1);
1080dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul}
1090dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul
1100dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul
11138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul
1120dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul/**
113b4a40d10524a4be6a59805589ee4209ebdb1de4fBrian Paul * Compute coord % size for repeat wrap modes.
114e31f0f996537046228602a251706613ca4163209Brian Paul * Note that if coord is negative, coord % size doesn't give the right
115e31f0f996537046228602a251706613ca4163209Brian Paul * value.  To avoid that problem we add a large multiple of the size
116e31f0f996537046228602a251706613ca4163209Brian Paul * (rather than using a conditional).
1170dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul */
118b4a40d10524a4be6a59805589ee4209ebdb1de4fBrian Paulstatic INLINE int
119b4a40d10524a4be6a59805589ee4209ebdb1de4fBrian Paulrepeat(int coord, unsigned size)
120b4a40d10524a4be6a59805589ee4209ebdb1de4fBrian Paul{
121e31f0f996537046228602a251706613ca4163209Brian Paul   return (coord + size * 1024) % size;
122b4a40d10524a4be6a59805589ee4209ebdb1de4fBrian Paul}
12308f33a025100dea2d951e6d628891fe294b18082Brian Paul
12408f33a025100dea2d951e6d628891fe294b18082Brian Paul
12508f33a025100dea2d951e6d628891fe294b18082Brian Paul/**
12638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul * Apply texture coord wrapping mode and return integer texture indexes
12738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul * for a vector of four texcoords (S or T or P).
12808f33a025100dea2d951e6d628891fe294b18082Brian Paul * \param wrapMode  PIPE_TEX_WRAP_x
12938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul * \param s  the incoming texcoords
13008f33a025100dea2d951e6d628891fe294b18082Brian Paul * \param size  the texture image size
13138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul * \param icoord  returns the integer texcoords
13208f33a025100dea2d951e6d628891fe294b18082Brian Paul */
1334fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
1343f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_nearest_repeat(float s, unsigned size, int offset, int *icoord)
1354fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
1364fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* s limited to [0,1) */
1374fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* i limited to [0,size-1] */
138229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int i = util_ifloor(s * size);
1393f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   *icoord = repeat(i + offset, size);
1404fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
1414fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1424fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1434fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
1443f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_nearest_clamp(float s, unsigned size, int offset, int *icoord)
1450dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul{
1464fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* s limited to [0,1] */
1474fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* i limited to [0,size-1] */
148229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (s <= 0.0F)
149229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = 0;
150229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else if (s >= 1.0F)
151229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = size - 1;
152229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else
153229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = util_ifloor(s * size);
1543f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   if (offset)
1553f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      *icoord = CLAMP(*icoord + offset, 0, size - 1);
1564fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
1574fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1584fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1594fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
1603f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_nearest_clamp_to_edge(float s, unsigned size, int offset, int *icoord)
1614fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
1624fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* s limited to [min,max] */
1634fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* i limited to [0, size-1] */
1644fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float min = 1.0F / (2.0F * size);
1654fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float max = 1.0F - min;
1663f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie
167229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (s < min)
168229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = 0;
169229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else if (s > max)
170229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = size - 1;
171229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else
172229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = util_ifloor(s * size);
1733f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   if (offset)
1743f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      *icoord = CLAMP(*icoord + offset, 0, size - 1);
1754fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
1764fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1774fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1784fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
1793f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_nearest_clamp_to_border(float s, unsigned size, int offset, int *icoord)
1804fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
1814fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* s limited to [min,max] */
1824fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* i limited to [-1, size] */
1834fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float min = -1.0F / (2.0F * size);
1844fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float max = 1.0F - min;
185229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (s <= min)
186229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = -1;
187229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else if (s >= max)
188229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = size;
189229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else
190229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = util_ifloor(s * size);
1913f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   if (offset)
1923f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      *icoord = CLAMP(*icoord + offset, 0, size - 1);
1934fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
1944fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
195e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
1964fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
1973f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_nearest_mirror_repeat(float s, unsigned size, int offset, int *icoord)
1984fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
1994fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float min = 1.0F / (2.0F * size);
2004fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float max = 1.0F - min;
201229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const int flr = util_ifloor(s);
202229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float u = frac(s);
203229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (flr & 1)
204229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      u = 1.0F - u;
205229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (u < min)
206229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = 0;
207229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else if (u > max)
208229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = size - 1;
209229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else
210229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = util_ifloor(u * size);
2113f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   if (offset)
2123f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      *icoord = CLAMP(*icoord + offset, 0, size - 1);
2134fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
2144fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
215e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
2164fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
2173f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_nearest_mirror_clamp(float s, unsigned size, int offset, int *icoord)
218229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
219229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   /* s limited to [0,1] */
220229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   /* i limited to [0,size-1] */
221229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float u = fabsf(s);
222229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (u <= 0.0F)
223229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = 0;
224229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else if (u >= 1.0F)
225229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = size - 1;
226229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else
227229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = util_ifloor(u * size);
2283f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   if (offset)
2293f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      *icoord = CLAMP(*icoord + offset, 0, size - 1);
2304fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
2314fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
232e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
2334fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
2343f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_nearest_mirror_clamp_to_edge(float s, unsigned size, int offset, int *icoord)
2354fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
2364fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* s limited to [min,max] */
2374fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* i limited to [0, size-1] */
2384fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float min = 1.0F / (2.0F * size);
2394fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float max = 1.0F - min;
240229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float u = fabsf(s);
241229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (u < min)
242229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = 0;
243229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else if (u > max)
244229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = size - 1;
245229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else
246229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = util_ifloor(u * size);
2473f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   if (offset)
2483f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      *icoord = CLAMP(*icoord + offset, 0, size - 1);
2494fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
2504fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
2514fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
2524fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
2533f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_nearest_mirror_clamp_to_border(float s, unsigned size, int offset, int *icoord)
2544fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
2554fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* s limited to [min,max] */
2564fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* i limited to [0, size-1] */
2574fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float min = -1.0F / (2.0F * size);
2584fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float max = 1.0F - min;
259229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float u = fabsf(s);
260229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (u < min)
261229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = -1;
262229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else if (u > max)
263229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = size;
264229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else
265229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = util_ifloor(u * size);
2663f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   if (offset)
2673f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      *icoord = CLAMP(*icoord + offset, 0, size - 1);
2680dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul}
2690dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul
27008f33a025100dea2d951e6d628891fe294b18082Brian Paul
27108f33a025100dea2d951e6d628891fe294b18082Brian Paul/**
272229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert * Used to compute texel locations for linear sampling
27308f33a025100dea2d951e6d628891fe294b18082Brian Paul * \param wrapMode  PIPE_TEX_WRAP_x
274229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert * \param s  the texcoord
27508f33a025100dea2d951e6d628891fe294b18082Brian Paul * \param size  the texture image size
276229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert * \param icoord0  returns first texture index
277229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert * \param icoord1  returns second texture index (usually icoord0 + 1)
278229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert * \param w  returns blend factor/weight between texture indices
279229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert * \param icoord  returns the computed integer texture coord
28008f33a025100dea2d951e6d628891fe294b18082Brian Paul */
2814fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
2823f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_linear_repeat(float s, unsigned size, int offset,
283229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                   int *icoord0, int *icoord1, float *w)
284229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
285229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float u = s * size - 0.5F;
2863f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   *icoord0 = repeat(util_ifloor(u) + offset, size);
287229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = repeat(*icoord0 + 1, size);
288229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
2894fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
2904fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
291e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
2924fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
2933f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_linear_clamp(float s, unsigned size, int offset,
294229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                  int *icoord0, int *icoord1, float *w)
295229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
296229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float u = CLAMP(s, 0.0F, 1.0F);
297229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   u = u * size - 0.5f;
298229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
299229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
3003f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   if (offset) {
3013f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      *icoord0 = CLAMP(*icoord0 + offset, 0, size - 1);
3023f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      *icoord1 = CLAMP(*icoord1 + offset, 0, size - 1);
3033f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   }
304229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
3054fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
30638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul
307e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
3084fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
3093f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_linear_clamp_to_edge(float s, unsigned size, int offset,
310229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                          int *icoord0, int *icoord1, float *w)
311229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
312229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float u = CLAMP(s, 0.0F, 1.0F);
313229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   u = u * size - 0.5f;
314229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
315229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
316229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (*icoord0 < 0)
317229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord0 = 0;
318229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (*icoord1 >= (int) size)
319229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord1 = size - 1;
3203f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   if (offset) {
3213f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      *icoord0 = CLAMP(*icoord0 + offset, 0, size - 1);
3223f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      *icoord1 = CLAMP(*icoord1 + offset, 0, size - 1);
3233f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   }
324229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
3254fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
3264fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
327e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
3284fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
3293f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_linear_clamp_to_border(float s, unsigned size, int offset,
330229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                            int *icoord0, int *icoord1, float *w)
3314fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
3324fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float min = -1.0F / (2.0F * size);
3334fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float max = 1.0F - min;
334229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float u = CLAMP(s, min, max);
335229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   u = u * size - 0.5f;
336229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
337229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
338229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
3394fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
3404fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
3414fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
3424fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
3433f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_linear_mirror_repeat(float s, unsigned size, int offset,
344229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                          int *icoord0, int *icoord1, float *w)
345229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
346229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const int flr = util_ifloor(s);
347229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float u = frac(s);
348229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (flr & 1)
349229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      u = 1.0F - u;
350229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   u = u * size - 0.5F;
351229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
352229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
353229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (*icoord0 < 0)
354229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord0 = 0;
355229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (*icoord1 >= (int) size)
356229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord1 = size - 1;
357229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
3584fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
3594fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
360e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
3614fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
3623f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_linear_mirror_clamp(float s, unsigned size, int offset,
363229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                         int *icoord0, int *icoord1, float *w)
364229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
365229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float u = fabsf(s);
366229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (u >= 1.0F)
367229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      u = (float) size;
368229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else
369229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      u *= size;
370229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   u -= 0.5F;
371229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
372229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
373229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
3744fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
3754fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
376e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
3774fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
3783f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_linear_mirror_clamp_to_edge(float s, unsigned size, int offset,
379229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                 int *icoord0, int *icoord1, float *w)
380229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
381229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float u = fabsf(s);
382229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (u >= 1.0F)
383229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      u = (float) size;
384229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else
385229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      u *= size;
386229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   u -= 0.5F;
387229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
388229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
389229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (*icoord0 < 0)
390229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord0 = 0;
391229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (*icoord1 >= (int) size)
392229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord1 = size - 1;
393229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
3944fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
3954fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
396e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
3974fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
3983f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_linear_mirror_clamp_to_border(float s, unsigned size, int offset,
399229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                   int *icoord0, int *icoord1, float *w)
4004fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
4014fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float min = -1.0F / (2.0F * size);
4024fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float max = 1.0F - min;
403229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float u = fabsf(s);
404229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (u <= min)
405229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      u = min * size;
406229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else if (u >= max)
407229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      u = max * size;
408229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else
409229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      u *= size;
410229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   u -= 0.5F;
411229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
412229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
413229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
4140dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul}
4150dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul
4160dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul
417b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul/**
418b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul * PIPE_TEX_WRAP_CLAMP for nearest sampling, unnormalized coords.
419b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul */
4204fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
4213f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_nearest_unorm_clamp(float s, unsigned size, int offset, int *icoord)
422b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul{
423229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int i = util_ifloor(s);
4243f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   *icoord = CLAMP(i + offset, 0, (int) size-1);
4254fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
4264fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
427e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
428e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul/**
429b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul * PIPE_TEX_WRAP_CLAMP_TO_BORDER for nearest sampling, unnormalized coords.
4304fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell */
4314fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
4323f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_nearest_unorm_clamp_to_border(float s, unsigned size, int offset, int *icoord)
4334fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
4343f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   *icoord = util_ifloor( CLAMP(s + offset, -0.5F, (float) size + 0.5F) );
435b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul}
436b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul
437b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul
438b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul/**
439b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul * PIPE_TEX_WRAP_CLAMP_TO_EDGE for nearest sampling, unnormalized coords.
440b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul */
441b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paulstatic void
4423f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_nearest_unorm_clamp_to_edge(float s, unsigned size, int offset, int *icoord)
443b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul{
4443f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   *icoord = util_ifloor( CLAMP(s + offset, 0.5F, (float) size - 0.5F) );
445b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul}
446b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul
447b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul
448b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul/**
449b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul * PIPE_TEX_WRAP_CLAMP for linear sampling, unnormalized coords.
450b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul */
4514fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
4523f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_linear_unorm_clamp(float s, unsigned size, int offset,
453229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                        int *icoord0, int *icoord1, float *w)
454229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
455229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   /* Not exactly what the spec says, but it matches NVIDIA output */
4563f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   float u = CLAMP(s + offset - 0.5F, 0.0f, (float) size - 1.0f);
457229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
458229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
459229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
460b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul}
461b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul
462e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
463b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul/**
464b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul * PIPE_TEX_WRAP_CLAMP_TO_BORDER for linear sampling, unnormalized coords.
465b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul */
4664fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
4673f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_linear_unorm_clamp_to_border(float s, unsigned size, int offset,
468229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                  int *icoord0, int *icoord1, float *w)
469229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
4703f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   float u = CLAMP(s + offset, -0.5F, (float) size + 0.5F);
471229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   u -= 0.5F;
472229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
473229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
474229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (*icoord1 > (int) size - 1)
475229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord1 = size - 1;
476229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
477b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul}
478b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul
479b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul
480b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul/**
481b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul * PIPE_TEX_WRAP_CLAMP_TO_EDGE for linear sampling, unnormalized coords.
482b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul */
483b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paulstatic void
4843f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_linear_unorm_clamp_to_edge(float s, unsigned size, int offset,
485229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                int *icoord0, int *icoord1, float *w)
486229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
4873f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   float u = CLAMP(s + offset, +0.5F, (float) size - 0.5F);
488229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   u -= 0.5F;
489229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
490229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
491229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (*icoord1 > (int) size - 1)
492229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord1 = size - 1;
493229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
4944fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
4954fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
49634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul
497779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul/**
498779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul * Do coordinate to array index conversion.  For array textures.
499779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul */
500adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheideggerstatic INLINE int
501adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheideggercoord_to_layer(float coord, unsigned first_layer, unsigned last_layer)
502779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul{
503229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c = util_ifloor(coord + 0.5F);
504adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   return CLAMP(c, (int)first_layer, (int)last_layer);
505779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul}
506779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
50734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul
508b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul/**
509b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul * Examine the quad's texture coordinates to compute the partial
510b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul * derivatives w.r.t X and Y, then compute lambda (level of detail).
511b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul */
512b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paulstatic float
513ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggercompute_lambda_1d(const struct sp_sampler_view *sview,
5146b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float s[TGSI_QUAD_SIZE],
5156b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float t[TGSI_QUAD_SIZE],
5166b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float p[TGSI_QUAD_SIZE])
517b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul{
518ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sview->base.texture;
5194fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]);
5204fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   float dsdy = fabsf(s[QUAD_TOP_LEFT]     - s[QUAD_BOTTOM_LEFT]);
521ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   float rho = MAX2(dsdx, dsdy) * u_minify(texture->width0, sview->base.u.tex.first_level);
522b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul
5234bfe1c955fe679547c8a03119d1681e33593c768Michal Krol   return util_fast_log2(rho);
524b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul}
525b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul
526e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
5274fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic float
528ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggercompute_lambda_2d(const struct sp_sampler_view *sview,
5296b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float s[TGSI_QUAD_SIZE],
5306b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float t[TGSI_QUAD_SIZE],
5316b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float p[TGSI_QUAD_SIZE])
53209a1b912605ff48c8782dcc5aae55ac77e27037bBrian Paul{
533ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sview->base.texture;
5344fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]);
5354fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   float dsdy = fabsf(s[QUAD_TOP_LEFT]     - s[QUAD_BOTTOM_LEFT]);
5364fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   float dtdx = fabsf(t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]);
5374fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   float dtdy = fabsf(t[QUAD_TOP_LEFT]     - t[QUAD_BOTTOM_LEFT]);
538ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   float maxx = MAX2(dsdx, dsdy) * u_minify(texture->width0, sview->base.u.tex.first_level);
539ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   float maxy = MAX2(dtdx, dtdy) * u_minify(texture->height0, sview->base.u.tex.first_level);
5404fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   float rho  = MAX2(maxx, maxy);
541c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul
5424bfe1c955fe679547c8a03119d1681e33593c768Michal Krol   return util_fast_log2(rho);
54309a1b912605ff48c8782dcc5aae55ac77e27037bBrian Paul}
54409a1b912605ff48c8782dcc5aae55ac77e27037bBrian Paul
54508f33a025100dea2d951e6d628891fe294b18082Brian Paul
5464fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic float
547ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggercompute_lambda_3d(const struct sp_sampler_view *sview,
5486b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float s[TGSI_QUAD_SIZE],
5496b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float t[TGSI_QUAD_SIZE],
5506b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float p[TGSI_QUAD_SIZE])
55109a1b912605ff48c8782dcc5aae55ac77e27037bBrian Paul{
552ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sview->base.texture;
5534fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]);
5544fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   float dsdy = fabsf(s[QUAD_TOP_LEFT]     - s[QUAD_BOTTOM_LEFT]);
5554fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   float dtdx = fabsf(t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]);
5564fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   float dtdy = fabsf(t[QUAD_TOP_LEFT]     - t[QUAD_BOTTOM_LEFT]);
5574fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   float dpdx = fabsf(p[QUAD_BOTTOM_RIGHT] - p[QUAD_BOTTOM_LEFT]);
5584fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   float dpdy = fabsf(p[QUAD_TOP_LEFT]     - p[QUAD_BOTTOM_LEFT]);
559ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   float maxx = MAX2(dsdx, dsdy) * u_minify(texture->width0, sview->base.u.tex.first_level);
560ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   float maxy = MAX2(dtdx, dtdy) * u_minify(texture->height0, sview->base.u.tex.first_level);
561ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   float maxz = MAX2(dpdx, dpdy) * u_minify(texture->depth0, sview->base.u.tex.first_level);
5624bfe1c955fe679547c8a03119d1681e33593c768Michal Krol   float rho;
56300c835918259f8d41c3f74eca679a972713b11b2Keith Whitwell
5644fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   rho = MAX2(maxx, maxy);
5654fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   rho = MAX2(rho, maxz);
566c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul
5674bfe1c955fe679547c8a03119d1681e33593c768Michal Krol   return util_fast_log2(rho);
56809a1b912605ff48c8782dcc5aae55ac77e27037bBrian Paul}
56909a1b912605ff48c8782dcc5aae55ac77e27037bBrian Paul
57008f33a025100dea2d951e6d628891fe294b18082Brian Paul
571e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul/**
572e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul * Compute lambda for a vertex texture sampler.
5734bfe1c955fe679547c8a03119d1681e33593c768Michal Krol * Since there aren't derivatives to use, just return 0.
574e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul */
5754fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic float
576ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggercompute_lambda_vert(const struct sp_sampler_view *sview,
5776b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                    const float s[TGSI_QUAD_SIZE],
5786b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                    const float t[TGSI_QUAD_SIZE],
5796b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                    const float p[TGSI_QUAD_SIZE])
5804fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
5814bfe1c955fe679547c8a03119d1681e33593c768Michal Krol   return 0.0f;
5824fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
5834fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
5844fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
5854fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
5864fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell/**
5874fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell * Get a texel from a texture, using the texture tile cache.
5884fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell *
58981601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell * \param addr  the template tex address containing cube, z, face info.
5904fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell * \param x  the x coord of texel within 2D image
591b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul * \param y  the y coord of texel within 2D image
592b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul * \param rgba  the quad to put the texel/color into
59370eb7996f265f3634dabda078f13d1be3533cc65Brian Paul *
59480c78472ad43f4288c9ef5076074ba9d31a39885Keith Whitwell * XXX maybe move this into sp_tex_tile_cache.c and merge with the
595229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert * sp_get_cached_tile_tex() function.
596b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul */
59781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
59881601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
59981601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
60081601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
60181601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwellstatic INLINE const float *
602ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerget_texel_2d_no_border(const struct sp_sampler_view *sp_sview,
603ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                       union tex_tile_address addr, int x, int y)
604b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul{
60581601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   const struct softpipe_tex_cached_tile *tile;
6062f567fb7b50e39aef20f0a0cd9b2eba184ed6441Roland Scheidegger   addr.bits.x = x / TEX_TILE_SIZE;
6072f567fb7b50e39aef20f0a0cd9b2eba184ed6441Roland Scheidegger   addr.bits.y = y / TEX_TILE_SIZE;
6082f567fb7b50e39aef20f0a0cd9b2eba184ed6441Roland Scheidegger   y %= TEX_TILE_SIZE;
6092f567fb7b50e39aef20f0a0cd9b2eba184ed6441Roland Scheidegger   x %= TEX_TILE_SIZE;
61081601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
611ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tile = sp_get_cached_tile_tex(sp_sview->cache, addr);
61281601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
61381601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   return &tile->data.color[y][x][0];
61481601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell}
61581601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
61681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
61781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwellstatic INLINE const float *
618ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerget_texel_2d(const struct sp_sampler_view *sp_sview,
619ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger             const struct sp_sampler *sp_samp,
620ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger             union tex_tile_address addr, int x, int y)
62181601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell{
622ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
62381601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   unsigned level = addr.bits.level;
62481601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
625683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell   if (x < 0 || x >= (int) u_minify(texture->width0, level) ||
626683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell       y < 0 || y >= (int) u_minify(texture->height0, level)) {
627ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return sp_samp->base.border_color.f;
62881601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   }
62981601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   else {
630ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return get_texel_2d_no_border( sp_sview, addr, x, y );
63181601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   }
63281601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell}
6336142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
6347681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger
6357681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger/*
6367681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * Here's the complete logic (HOLY CRAP) for finding next face and doing the
6377681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * corresponding coord wrapping, implemented by get_next_face,
6387681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * get_next_xcoord, get_next_ycoord.
6397681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * Read like that (first line):
6407681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * If face is +x and s coord is below zero, then
6417681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * new face is +z, new s is max , new t is old t
6427681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * (max is always cube size - 1).
6437681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger *
6447681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * +x s- -> +z: s = max,   t = t
6457681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * +x s+ -> -z: s = 0,     t = t
6467681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * +x t- -> +y: s = max,   t = max-s
6477681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * +x t+ -> -y: s = max,   t = s
6487681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger *
6497681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * -x s- -> -z: s = max,   t = t
6507681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * -x s+ -> +z: s = 0,     t = t
6517681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * -x t- -> +y: s = 0,     t = s
6527681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * -x t+ -> -y: s = 0,     t = max-s
6537681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger *
6547681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * +y s- -> -x: s = t,     t = 0
6557681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * +y s+ -> +x: s = max-t, t = 0
6567681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * +y t- -> -z: s = max-s, t = 0
6577681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * +y t+ -> +z: s = s,     t = 0
6587681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger *
6597681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * -y s- -> -x: s = max-t, t = max
6607681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * -y s+ -> +x: s = t,     t = max
6617681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * -y t- -> +z: s = s,     t = max
6627681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * -y t+ -> -z: s = max-s, t = max
6637681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger
6647681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * +z s- -> -x: s = max,   t = t
6657681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * +z s+ -> +x: s = 0,     t = t
6667681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * +z t- -> +y: s = s,     t = max
6677681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * +z t+ -> -y: s = s,     t = 0
6687681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger
6697681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * -z s- -> +x: s = max,   t = t
6707681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * -z s+ -> -x: s = 0,     t = t
6717681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * -z t- -> +y: s = max-s, t = 0
6727681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * -z t+ -> -y: s = max-s, t = max
6737681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger */
6747681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger
6757681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger
676621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie/*
677621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie * seamless cubemap neighbour array.
678621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie * this array is used to find the adjacent face in each of 4 directions,
679621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie * left, right, up, down. (or -x, +x, -y, +y).
680621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie */
681621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airliestatic const unsigned face_array[PIPE_TEX_FACE_MAX][4] = {
682621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   /* pos X first then neg X is Z different, Y the same */
683621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   /* PIPE_TEX_FACE_POS_X,*/
684621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   { PIPE_TEX_FACE_POS_Z, PIPE_TEX_FACE_NEG_Z,
6857681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger     PIPE_TEX_FACE_POS_Y, PIPE_TEX_FACE_NEG_Y },
686621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   /* PIPE_TEX_FACE_NEG_X */
687621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   { PIPE_TEX_FACE_NEG_Z, PIPE_TEX_FACE_POS_Z,
6887681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger     PIPE_TEX_FACE_POS_Y, PIPE_TEX_FACE_NEG_Y },
689621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie
690621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   /* pos Y first then neg Y is X different, X the same */
691621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   /* PIPE_TEX_FACE_POS_Y */
692621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   { PIPE_TEX_FACE_NEG_X, PIPE_TEX_FACE_POS_X,
6937681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger     PIPE_TEX_FACE_NEG_Z, PIPE_TEX_FACE_POS_Z },
694621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie
695621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   /* PIPE_TEX_FACE_NEG_Y */
696621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   { PIPE_TEX_FACE_NEG_X, PIPE_TEX_FACE_POS_X,
6977681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger     PIPE_TEX_FACE_POS_Z, PIPE_TEX_FACE_NEG_Z },
698621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie
699621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   /* pos Z first then neg Y is X different, X the same */
700621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   /* PIPE_TEX_FACE_POS_Z */
701621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   { PIPE_TEX_FACE_NEG_X, PIPE_TEX_FACE_POS_X,
7027681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger     PIPE_TEX_FACE_POS_Y, PIPE_TEX_FACE_NEG_Y },
703621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie
704621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   /* PIPE_TEX_FACE_NEG_Z */
705621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   { PIPE_TEX_FACE_POS_X, PIPE_TEX_FACE_NEG_X,
7067681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger     PIPE_TEX_FACE_POS_Y, PIPE_TEX_FACE_NEG_Y }
707621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie};
708621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie
709621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airliestatic INLINE unsigned
7107681beedd19cf437252fbc1041b19328ad773ea5Roland Scheideggerget_next_face(unsigned face, int idx)
711621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie{
7127681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   return face_array[face][idx];
7137681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger}
714621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie
7157681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger/*
7167681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * return a new xcoord based on old face, old coords, cube size
7177681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * and fall_off_index (0 for x-, 1 for x+, 2 for y-, 3 for y+)
7187681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger */
7197681beedd19cf437252fbc1041b19328ad773ea5Roland Scheideggerstatic INLINE int
7207681beedd19cf437252fbc1041b19328ad773ea5Roland Scheideggerget_next_xcoord(unsigned face, unsigned fall_off_index, int max, int xc, int yc)
7217681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger{
7227681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   if ((face == 0 && fall_off_index != 1) ||
7237681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 1 && fall_off_index == 0) ||
7247681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 4 && fall_off_index == 0) ||
7257681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 5 && fall_off_index == 0)) {
7267681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger      return max;
7277681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   }
7287681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   if ((face == 1 && fall_off_index != 0) ||
7297681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 0 && fall_off_index == 1) ||
7307681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 4 && fall_off_index == 1) ||
7317681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 5 && fall_off_index == 1)) {
7327681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger      return 0;
7337681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   }
7347681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   if ((face == 4 && fall_off_index >= 2) ||
7357681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 2 && fall_off_index == 3) ||
7367681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 3 && fall_off_index == 2)) {
7377681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger      return xc;
7387681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   }
7397681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   if ((face == 5 && fall_off_index >= 2) ||
7407681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 2 && fall_off_index == 2) ||
7417681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 3 && fall_off_index == 3)) {
7427681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger      return max - xc;
7437681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   }
7447681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   if ((face == 2 && fall_off_index == 0) ||
7457681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 3 && fall_off_index == 1)) {
7467681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger      return yc;
7477681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   }
7487681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   /* (face == 2 && fall_off_index == 1) ||
7497681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger      (face == 3 && fall_off_index == 0)) */
7507681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   return max - yc;
7517681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger}
752621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie
7537681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger/*
7547681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * return a new ycoord based on old face, old coords, cube size
7557681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * and fall_off_index (0 for x-, 1 for x+, 2 for y-, 3 for y+)
7567681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger */
7577681beedd19cf437252fbc1041b19328ad773ea5Roland Scheideggerstatic INLINE int
7587681beedd19cf437252fbc1041b19328ad773ea5Roland Scheideggerget_next_ycoord(unsigned face, unsigned fall_off_index, int max, int xc, int yc)
7597681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger{
7607681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   if ((fall_off_index <= 1) && (face <= 1 || face >= 4)) {
7617681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger      return yc;
7627681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   }
7637681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   if (face == 2 ||
7647681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 4 && fall_off_index == 3) ||
7657681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 5 && fall_off_index == 2)) {
7667681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger      return 0;
7677681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   }
7687681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   if (face == 3 ||
7697681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 4 && fall_off_index == 2) ||
7707681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 5 && fall_off_index == 3)) {
7717681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger      return max;
7727681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   }
7737681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   if ((face == 0 && fall_off_index == 3) ||
7747681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 1 && fall_off_index == 2)) {
7757681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger      return xc;
7767681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   }
7777681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   /* (face == 0 && fall_off_index == 2) ||
7787681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger      (face == 1 && fall_off_index == 3) */
7797681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   return max - xc;
780621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie}
781621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie
7827681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger
78381601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell/* Gather a quad of adjacent texels within a tile:
78481601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell */
78581601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwellstatic INLINE void
786ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerget_texel_quad_2d_no_border_single_tile(const struct sp_sampler_view *sp_sview,
787ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                                        union tex_tile_address addr,
788ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                                        unsigned x, unsigned y,
789ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                                        const float *out[4])
79081601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell{
791ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger    const struct softpipe_tex_cached_tile *tile;
79281601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
7932f567fb7b50e39aef20f0a0cd9b2eba184ed6441Roland Scheidegger   addr.bits.x = x / TEX_TILE_SIZE;
7942f567fb7b50e39aef20f0a0cd9b2eba184ed6441Roland Scheidegger   addr.bits.y = y / TEX_TILE_SIZE;
7952f567fb7b50e39aef20f0a0cd9b2eba184ed6441Roland Scheidegger   y %= TEX_TILE_SIZE;
7962f567fb7b50e39aef20f0a0cd9b2eba184ed6441Roland Scheidegger   x %= TEX_TILE_SIZE;
79781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
798ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tile = sp_get_cached_tile_tex(sp_sview->cache, addr);
7996142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
8006142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   out[0] = &tile->data.color[y  ][x  ][0];
8016142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   out[1] = &tile->data.color[y  ][x+1][0];
8026142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   out[2] = &tile->data.color[y+1][x  ][0];
8036142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   out[3] = &tile->data.color[y+1][x+1][0];
8046142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell}
8056142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
80681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
80781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell/* Gather a quad of potentially non-adjacent texels:
80881601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell */
80981601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwellstatic INLINE void
810ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerget_texel_quad_2d_no_border(const struct sp_sampler_view *sp_sview,
811ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                            union tex_tile_address addr,
812ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                            int x0, int y0,
813ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                            int x1, int y1,
814ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                            const float *out[4])
81581601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell{
816ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   out[0] = get_texel_2d_no_border( sp_sview, addr, x0, y0 );
817ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   out[1] = get_texel_2d_no_border( sp_sview, addr, x1, y0 );
818ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   out[2] = get_texel_2d_no_border( sp_sview, addr, x0, y1 );
819ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   out[3] = get_texel_2d_no_border( sp_sview, addr, x1, y1 );
82081601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell}
82181601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
82281601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell/* Can involve a lot of unnecessary checks for border color:
82381601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell */
82481601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwellstatic INLINE void
825ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerget_texel_quad_2d(const struct sp_sampler_view *sp_sview,
826ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                  const struct sp_sampler *sp_samp,
827ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                  union tex_tile_address addr,
828ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                  int x0, int y0,
829ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                  int x1, int y1,
830ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                  const float *out[4])
83181601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell{
832ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   out[0] = get_texel_2d( sp_sview, sp_samp, addr, x0, y0 );
833ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   out[1] = get_texel_2d( sp_sview, sp_samp, addr, x1, y0 );
834ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   out[3] = get_texel_2d( sp_sview, sp_samp, addr, x1, y1 );
835ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   out[2] = get_texel_2d( sp_sview, sp_samp, addr, x0, y1 );
83681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell}
83781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
83881601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
83981601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
840f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paul/* 3d variants:
84181601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell */
8426142de393fe34ff0866f8489f1292eb473276f11Keith Whitwellstatic INLINE const float *
843ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerget_texel_3d_no_border(const struct sp_sampler_view *sp_sview,
844e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul                       union tex_tile_address addr, int x, int y, int z)
8456142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell{
846153e474d22d1b440bb6bd7b04dabf244d7455582Keith Whitwell   const struct softpipe_tex_cached_tile *tile;
8476142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
8482f567fb7b50e39aef20f0a0cd9b2eba184ed6441Roland Scheidegger   addr.bits.x = x / TEX_TILE_SIZE;
8492f567fb7b50e39aef20f0a0cd9b2eba184ed6441Roland Scheidegger   addr.bits.y = y / TEX_TILE_SIZE;
85081601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   addr.bits.z = z;
8512f567fb7b50e39aef20f0a0cd9b2eba184ed6441Roland Scheidegger   y %= TEX_TILE_SIZE;
8522f567fb7b50e39aef20f0a0cd9b2eba184ed6441Roland Scheidegger   x %= TEX_TILE_SIZE;
8536142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
854ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tile = sp_get_cached_tile_tex(sp_sview->cache, addr);
855153e474d22d1b440bb6bd7b04dabf244d7455582Keith Whitwell
8566142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   return &tile->data.color[y][x][0];
8576142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell}
8586142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
8596142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
86081601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwellstatic INLINE const float *
861ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerget_texel_3d(const struct sp_sampler_view *sp_sview,
862ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger             const struct sp_sampler *sp_samp,
863ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger             union tex_tile_address addr, int x, int y, int z)
864b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul{
865ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
86681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   unsigned level = addr.bits.level;
8670b9e96fae9493d5d58f046e01c983a3c4267090eBrian Paul
868683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell   if (x < 0 || x >= (int) u_minify(texture->width0, level) ||
869683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell       y < 0 || y >= (int) u_minify(texture->height0, level) ||
870683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell       z < 0 || z >= (int) u_minify(texture->depth0, level)) {
871ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return sp_samp->base.border_color.f;
872ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul   }
873ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul   else {
874ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return get_texel_3d_no_border( sp_sview, addr, x, y, z );
875ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul   }
876b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul}
877b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul
878b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul
87980777743b7b6238f034b8cb81d8d907d74929334Brian Paul/* Get texel pointer for 1D array texture */
88080777743b7b6238f034b8cb81d8d907d74929334Brian Paulstatic INLINE const float *
881ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerget_texel_1d_array(const struct sp_sampler_view *sp_sview,
882ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                   const struct sp_sampler *sp_samp,
88380777743b7b6238f034b8cb81d8d907d74929334Brian Paul                   union tex_tile_address addr, int x, int y)
88480777743b7b6238f034b8cb81d8d907d74929334Brian Paul{
885ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
88680777743b7b6238f034b8cb81d8d907d74929334Brian Paul   unsigned level = addr.bits.level;
88780777743b7b6238f034b8cb81d8d907d74929334Brian Paul
88880777743b7b6238f034b8cb81d8d907d74929334Brian Paul   if (x < 0 || x >= (int) u_minify(texture->width0, level)) {
889ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return sp_samp->base.border_color.f;
89080777743b7b6238f034b8cb81d8d907d74929334Brian Paul   }
89180777743b7b6238f034b8cb81d8d907d74929334Brian Paul   else {
892ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return get_texel_2d_no_border(sp_sview, addr, x, y);
89380777743b7b6238f034b8cb81d8d907d74929334Brian Paul   }
89480777743b7b6238f034b8cb81d8d907d74929334Brian Paul}
89580777743b7b6238f034b8cb81d8d907d74929334Brian Paul
89680777743b7b6238f034b8cb81d8d907d74929334Brian Paul
89780777743b7b6238f034b8cb81d8d907d74929334Brian Paul/* Get texel pointer for 2D array texture */
89880777743b7b6238f034b8cb81d8d907d74929334Brian Paulstatic INLINE const float *
899ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerget_texel_2d_array(const struct sp_sampler_view *sp_sview,
900ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                   const struct sp_sampler *sp_samp,
90180777743b7b6238f034b8cb81d8d907d74929334Brian Paul                   union tex_tile_address addr, int x, int y, int layer)
90280777743b7b6238f034b8cb81d8d907d74929334Brian Paul{
903ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
90480777743b7b6238f034b8cb81d8d907d74929334Brian Paul   unsigned level = addr.bits.level;
90580777743b7b6238f034b8cb81d8d907d74929334Brian Paul
90692d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul   assert(layer < (int) texture->array_size);
90792d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul   assert(layer >= 0);
90880777743b7b6238f034b8cb81d8d907d74929334Brian Paul
90980777743b7b6238f034b8cb81d8d907d74929334Brian Paul   if (x < 0 || x >= (int) u_minify(texture->width0, level) ||
91080777743b7b6238f034b8cb81d8d907d74929334Brian Paul       y < 0 || y >= (int) u_minify(texture->height0, level)) {
911ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return sp_samp->base.border_color.f;
91280777743b7b6238f034b8cb81d8d907d74929334Brian Paul   }
91380777743b7b6238f034b8cb81d8d907d74929334Brian Paul   else {
914ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return get_texel_3d_no_border(sp_sview, addr, x, y, layer);
91580777743b7b6238f034b8cb81d8d907d74929334Brian Paul   }
91680777743b7b6238f034b8cb81d8d907d74929334Brian Paul}
91780777743b7b6238f034b8cb81d8d907d74929334Brian Paul
91880777743b7b6238f034b8cb81d8d907d74929334Brian Paul
919adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheideggerstatic INLINE const float *
920adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheideggerget_texel_cube_seamless(const struct sp_sampler_view *sp_sview,
921adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                        union tex_tile_address addr, int x, int y,
922adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                        float *corner, int layer, unsigned face)
923adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger{
924adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
925adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   unsigned level = addr.bits.level;
926adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   int new_x, new_y, max_x;
927adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger
928adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   max_x = (int) u_minify(texture->width0, level);
929adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger
930adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   assert(texture->width0 == texture->height0);
931adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   new_x = x;
932adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   new_y = y;
933adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger
934adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   /* change the face */
935adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   if (x < 0) {
936adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      /*
937adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger       * Cheat with corners. They are difficult and I believe because we don't get
938adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger       * per-pixel faces we can actually have multiple corner texels per pixel,
939adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger       * which screws things up majorly in any case (as the per spec behavior is
940adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger       * to average the 3 remaining texels, which we might not have).
941adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger       * Hence just make sure that the 2nd coord is clamped, will simply pick the
942adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger       * sample which would have fallen off the x coord, but not y coord.
943adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger       * So the filter weight of the samples will be wrong, but at least this
944adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger       * ensures that only valid texels near the corner are used.
945adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger       */
946adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      if (y < 0 || y >= max_x) {
947adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger         y = CLAMP(y, 0, max_x - 1);
948adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      }
949adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      new_x = get_next_xcoord(face, 0, max_x -1, x, y);
950adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      new_y = get_next_ycoord(face, 0, max_x -1, x, y);
951adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      face = get_next_face(face, 0);
952adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   } else if (x >= max_x) {
953adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      if (y < 0 || y >= max_x) {
954adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger         y = CLAMP(y, 0, max_x - 1);
955adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      }
956adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      new_x = get_next_xcoord(face, 1, max_x -1, x, y);
957adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      new_y = get_next_ycoord(face, 1, max_x -1, x, y);
958adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      face = get_next_face(face, 1);
959adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   } else if (y < 0) {
960adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      new_x = get_next_xcoord(face, 2, max_x -1, x, y);
961adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      new_y = get_next_ycoord(face, 2, max_x -1, x, y);
962adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      face = get_next_face(face, 2);
963adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   } else if (y >= max_x) {
964adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      new_x = get_next_xcoord(face, 3, max_x -1, x, y);
965adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      new_y = get_next_ycoord(face, 3, max_x -1, x, y);
966adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      face = get_next_face(face, 3);
967adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   }
968adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger
969adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   return get_texel_3d_no_border(sp_sview, addr, new_x, new_y, layer + face);
970adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger}
971adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger
972adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger
973309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie/* Get texel pointer for cube array texture */
974309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airliestatic INLINE const float *
975ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerget_texel_cube_array(const struct sp_sampler_view *sp_sview,
976ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                     const struct sp_sampler *sp_samp,
977309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie                     union tex_tile_address addr, int x, int y, int layer)
978309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie{
979ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
980309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   unsigned level = addr.bits.level;
981309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie
982309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   assert(layer < (int) texture->array_size);
983309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   assert(layer >= 0);
984309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie
985309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   if (x < 0 || x >= (int) u_minify(texture->width0, level) ||
986309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie       y < 0 || y >= (int) u_minify(texture->height0, level)) {
987ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return sp_samp->base.border_color.f;
988309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   }
989309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   else {
990ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return get_texel_3d_no_border(sp_sview, addr, x, y, layer);
991309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   }
992309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie}
99375276ea316610a5737f2115326482024aa09d02aBrian Paul/**
99475276ea316610a5737f2115326482024aa09d02aBrian Paul * Given the logbase2 of a mipmap's base level size and a mipmap level,
99575276ea316610a5737f2115326482024aa09d02aBrian Paul * return the size (in texels) of that mipmap level.
99675276ea316610a5737f2115326482024aa09d02aBrian Paul * For example, if level[0].width = 256 then base_pot will be 8.
99775276ea316610a5737f2115326482024aa09d02aBrian Paul * If level = 2, then we'll return 64 (the width at level=2).
99875276ea316610a5737f2115326482024aa09d02aBrian Paul * Return 1 if level > base_pot.
99975276ea316610a5737f2115326482024aa09d02aBrian Paul */
100075276ea316610a5737f2115326482024aa09d02aBrian Paulstatic INLINE unsigned
100175276ea316610a5737f2115326482024aa09d02aBrian Paulpot_level_size(unsigned base_pot, unsigned level)
100275276ea316610a5737f2115326482024aa09d02aBrian Paul{
100375276ea316610a5737f2115326482024aa09d02aBrian Paul   return (base_pot >= level) ? (1 << (base_pot - level)) : 1;
100475276ea316610a5737f2115326482024aa09d02aBrian Paul}
100575276ea316610a5737f2115326482024aa09d02aBrian Paul
100675276ea316610a5737f2115326482024aa09d02aBrian Paul
10074250882ccf8326ba9074c671110370534489caa6Brian Paulstatic void
1008229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertprint_sample(const char *function, const float *rgba)
1009229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
1010229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   debug_printf("%s %g %g %g %g\n",
1011229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                function,
1012229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                rgba[0], rgba[TGSI_NUM_CHANNELS], rgba[2*TGSI_NUM_CHANNELS], rgba[3*TGSI_NUM_CHANNELS]);
1013229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert}
1014229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert
1015229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert
1016229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertstatic void
1017229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertprint_sample_4(const char *function, float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
10184250882ccf8326ba9074c671110370534489caa6Brian Paul{
10194250882ccf8326ba9074c671110370534489caa6Brian Paul   debug_printf("%s %g %g %g %g, %g %g %g %g, %g %g %g %g, %g %g %g %g\n",
10204250882ccf8326ba9074c671110370534489caa6Brian Paul                function,
10214250882ccf8326ba9074c671110370534489caa6Brian Paul                rgba[0][0], rgba[1][0], rgba[2][0], rgba[3][0],
10224250882ccf8326ba9074c671110370534489caa6Brian Paul                rgba[0][1], rgba[1][1], rgba[2][1], rgba[3][1],
10234250882ccf8326ba9074c671110370534489caa6Brian Paul                rgba[0][2], rgba[1][2], rgba[2][2], rgba[3][2],
10244250882ccf8326ba9074c671110370534489caa6Brian Paul                rgba[0][3], rgba[1][3], rgba[2][3], rgba[3][3]);
10254250882ccf8326ba9074c671110370534489caa6Brian Paul}
10264250882ccf8326ba9074c671110370534489caa6Brian Paul
1027ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
102881601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell/* Some image-filter fastpaths:
102981601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell */
1030efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paulstatic INLINE void
1031ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerimg_filter_2d_linear_repeat_POT(struct sp_sampler_view *sp_sview,
1032ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                                struct sp_sampler *sp_samp,
103399e583120cde8820aae94eb0f8beb723509398fcDave Airlie                                const struct img_filter_args *args,
1034229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                float *rgba)
10356142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell{
103699e583120cde8820aae94eb0f8beb723509398fcDave Airlie   unsigned xpot = pot_level_size(sp_sview->xpot, args->level);
103799e583120cde8820aae94eb0f8beb723509398fcDave Airlie   unsigned ypot = pot_level_size(sp_sview->ypot, args->level);
1038919236f3a28adfb04403e3f0db458afb9a897fd4Brian Paul   int xmax = (xpot - 1) & (TEX_TILE_SIZE - 1); /* MIN2(TEX_TILE_SIZE, xpot) - 1; */
1039919236f3a28adfb04403e3f0db458afb9a897fd4Brian Paul   int ymax = (ypot - 1) & (TEX_TILE_SIZE - 1); /* MIN2(TEX_TILE_SIZE, ypot) - 1; */
1040153e474d22d1b440bb6bd7b04dabf244d7455582Keith Whitwell   union tex_tile_address addr;
1041229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
1042153e474d22d1b440bb6bd7b04dabf244d7455582Keith Whitwell
104399e583120cde8820aae94eb0f8beb723509398fcDave Airlie   float u = args->s * xpot - 0.5F;
104499e583120cde8820aae94eb0f8beb723509398fcDave Airlie   float v = args->t * ypot - 0.5F;
10456142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
1046229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int uflr = util_ifloor(u);
1047229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int vflr = util_ifloor(v);
10486142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
1049229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float xw = u - (float)uflr;
1050229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float yw = v - (float)vflr;
10516142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
1052229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x0 = uflr & (xpot - 1);
1053229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int y0 = vflr & (ypot - 1);
10546142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
1055229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *tx[4];
10566142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
1057229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   addr.value = 0;
105899e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
10596142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
1060229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   /* Can we fetch all four at once:
1061229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert    */
1062229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (x0 < xmax && y0 < ymax) {
1063ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      get_texel_quad_2d_no_border_single_tile(sp_sview, addr, x0, y0, tx);
1064229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   }
1065229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else {
1066229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      unsigned x1 = (x0 + 1) & (xpot - 1);
1067229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      unsigned y1 = (y0 + 1) & (ypot - 1);
1068ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      get_texel_quad_2d_no_border(sp_sview, addr, x0, y0, x1, y1, tx);
1069229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   }
1070229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert
1071229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   /* interpolate R, G, B, A */
1072229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++) {
1073229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw,
1074229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                       tx[0][c], tx[1][c],
1075229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                       tx[2][c], tx[3][c]);
10766142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   }
10774250882ccf8326ba9074c671110370534489caa6Brian Paul
10784250882ccf8326ba9074c671110370534489caa6Brian Paul   if (DEBUG_TEX) {
10794250882ccf8326ba9074c671110370534489caa6Brian Paul      print_sample(__FUNCTION__, rgba);
10804250882ccf8326ba9074c671110370534489caa6Brian Paul   }
10816142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell}
10826142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
10836142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
10844fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic INLINE void
1085ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerimg_filter_2d_nearest_repeat_POT(struct sp_sampler_view *sp_sview,
1086ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                                 struct sp_sampler *sp_samp,
108799e583120cde8820aae94eb0f8beb723509398fcDave Airlie                                 const struct img_filter_args *args,
1088229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                 float rgba[TGSI_QUAD_SIZE])
10896142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell{
109099e583120cde8820aae94eb0f8beb723509398fcDave Airlie   unsigned xpot = pot_level_size(sp_sview->xpot, args->level);
109199e583120cde8820aae94eb0f8beb723509398fcDave Airlie   unsigned ypot = pot_level_size(sp_sview->ypot, args->level);
1092229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *out;
1093153e474d22d1b440bb6bd7b04dabf244d7455582Keith Whitwell   union tex_tile_address addr;
1094229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
1095153e474d22d1b440bb6bd7b04dabf244d7455582Keith Whitwell
109699e583120cde8820aae94eb0f8beb723509398fcDave Airlie   float u = args->s * xpot;
109799e583120cde8820aae94eb0f8beb723509398fcDave Airlie   float v = args->t * ypot;
10986142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
1099229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int uflr = util_ifloor(u);
1100229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int vflr = util_ifloor(v);
11016142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
1102229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x0 = uflr & (xpot - 1);
1103229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int y0 = vflr & (ypot - 1);
11046142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
1105229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   addr.value = 0;
110699e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
11076142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
1108ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   out = get_texel_2d_no_border(sp_sview, addr, x0, y0);
1109229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++)
1110229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = out[c];
11114250882ccf8326ba9074c671110370534489caa6Brian Paul
11124250882ccf8326ba9074c671110370534489caa6Brian Paul   if (DEBUG_TEX) {
11134250882ccf8326ba9074c671110370534489caa6Brian Paul      print_sample(__FUNCTION__, rgba);
11144250882ccf8326ba9074c671110370534489caa6Brian Paul   }
11156142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell}
11166142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
11176142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
11184fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic INLINE void
1119ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerimg_filter_2d_nearest_clamp_POT(struct sp_sampler_view *sp_sview,
1120ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                                struct sp_sampler *sp_samp,
112199e583120cde8820aae94eb0f8beb723509398fcDave Airlie                                const struct img_filter_args *args,
1122229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                float rgba[TGSI_QUAD_SIZE])
11236142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell{
112499e583120cde8820aae94eb0f8beb723509398fcDave Airlie   unsigned xpot = pot_level_size(sp_sview->xpot, args->level);
112599e583120cde8820aae94eb0f8beb723509398fcDave Airlie   unsigned ypot = pot_level_size(sp_sview->ypot, args->level);
1126153e474d22d1b440bb6bd7b04dabf244d7455582Keith Whitwell   union tex_tile_address addr;
1127229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
1128153e474d22d1b440bb6bd7b04dabf244d7455582Keith Whitwell
112999e583120cde8820aae94eb0f8beb723509398fcDave Airlie   float u = args->s * xpot;
113099e583120cde8820aae94eb0f8beb723509398fcDave Airlie   float v = args->t * ypot;
11316142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
1132229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x0, y0;
1133229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *out;
11346142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
1135229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   addr.value = 0;
113699e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
1137229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert
1138229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   x0 = util_ifloor(u);
1139229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (x0 < 0)
1140229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      x0 = 0;
1141919236f3a28adfb04403e3f0db458afb9a897fd4Brian Paul   else if (x0 > (int) xpot - 1)
1142229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      x0 = xpot - 1;
1143229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert
1144229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   y0 = util_ifloor(v);
1145229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (y0 < 0)
1146229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      y0 = 0;
1147919236f3a28adfb04403e3f0db458afb9a897fd4Brian Paul   else if (y0 > (int) ypot - 1)
1148229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      y0 = ypot - 1;
1149229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert
1150ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   out = get_texel_2d_no_border(sp_sview, addr, x0, y0);
1151229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++)
1152229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = out[c];
11534250882ccf8326ba9074c671110370534489caa6Brian Paul
11544250882ccf8326ba9074c671110370534489caa6Brian Paul   if (DEBUG_TEX) {
11554250882ccf8326ba9074c671110370534489caa6Brian Paul      print_sample(__FUNCTION__, rgba);
11564250882ccf8326ba9074c671110370534489caa6Brian Paul   }
11576142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell}
11586142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
1159e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
11606142de393fe34ff0866f8489f1292eb473276f11Keith Whitwellstatic void
1161ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerimg_filter_1d_nearest(struct sp_sampler_view *sp_sview,
1162ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                      struct sp_sampler *sp_samp,
116399e583120cde8820aae94eb0f8beb723509398fcDave Airlie                      const struct img_filter_args *args,
1164229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                      float rgba[TGSI_QUAD_SIZE])
11656142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell{
1166ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
11674fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   int width;
1168229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x;
116981601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   union tex_tile_address addr;
1170229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *out;
1171229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
11726142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
117399e583120cde8820aae94eb0f8beb723509398fcDave Airlie   width = u_minify(texture->width0, args->level);
11746142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
11754fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   assert(width > 0);
11764f409da3456070946eda2d8ff5153b3b4306bb46Keith Whitwell
117781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   addr.value = 0;
117899e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
117981601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
11803f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x);
11814f409da3456070946eda2d8ff5153b3b4306bb46Keith Whitwell
1182ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   out = get_texel_2d(sp_sview, sp_samp, addr, x, 0);
1183229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++)
1184229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = out[c];
11854250882ccf8326ba9074c671110370534489caa6Brian Paul
11864250882ccf8326ba9074c671110370534489caa6Brian Paul   if (DEBUG_TEX) {
11874250882ccf8326ba9074c671110370534489caa6Brian Paul      print_sample(__FUNCTION__, rgba);
11884250882ccf8326ba9074c671110370534489caa6Brian Paul   }
11896142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell}
11906142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
11914fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
119260adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwellstatic void
1193ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerimg_filter_1d_array_nearest(struct sp_sampler_view *sp_sview,
1194ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                            struct sp_sampler *sp_samp,
119599e583120cde8820aae94eb0f8beb723509398fcDave Airlie                            const struct img_filter_args *args,
1196229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                            float *rgba)
1197779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul{
1198ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
1199779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   int width;
1200229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x, layer;
1201779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   union tex_tile_address addr;
1202229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *out;
1203229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
1204779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
120599e583120cde8820aae94eb0f8beb723509398fcDave Airlie   width = u_minify(texture->width0, args->level);
1206779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1207779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   assert(width > 0);
1208779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1209779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   addr.value = 0;
121099e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
1211779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
12123f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x);
121399e583120cde8820aae94eb0f8beb723509398fcDave Airlie   layer = coord_to_layer(args->t, sp_sview->base.u.tex.first_layer,
1214adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                          sp_sview->base.u.tex.last_layer);
1215779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1216ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   out = get_texel_1d_array(sp_sview, sp_samp, addr, x, layer);
1217229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++)
1218229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = out[c];
1219779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1220779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   if (DEBUG_TEX) {
1221779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul      print_sample(__FUNCTION__, rgba);
1222779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   }
1223779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul}
1224779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1225779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1226779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paulstatic void
1227ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerimg_filter_2d_nearest(struct sp_sampler_view *sp_sview,
1228ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                      struct sp_sampler *sp_samp,
122999e583120cde8820aae94eb0f8beb723509398fcDave Airlie                      const struct img_filter_args *args,
1230229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                      float *rgba)
123160adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell{
1232ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
123360adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell   int width, height;
1234229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x, y;
123560adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell   union tex_tile_address addr;
1236229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *out;
1237229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
123881601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
123999e583120cde8820aae94eb0f8beb723509398fcDave Airlie   width = u_minify(texture->width0, args->level);
124099e583120cde8820aae94eb0f8beb723509398fcDave Airlie   height = u_minify(texture->height0, args->level);
124160adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
124260adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell   assert(width > 0);
12435dbedf3d7e99efe35fad308d382670e44cd60e25Brian Paul   assert(height > 0);
124460adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
124560adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell   addr.value = 0;
124699e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
124760adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
12483f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x);
12493f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->nearest_texcoord_t(args->t, height, args->offset[1], &y);
125060adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
1251ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   out = get_texel_2d(sp_sview, sp_samp, addr, x, y);
1252229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++)
1253229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = out[c];
12544250882ccf8326ba9074c671110370534489caa6Brian Paul
12554250882ccf8326ba9074c671110370534489caa6Brian Paul   if (DEBUG_TEX) {
12564250882ccf8326ba9074c671110370534489caa6Brian Paul      print_sample(__FUNCTION__, rgba);
12574250882ccf8326ba9074c671110370534489caa6Brian Paul   }
125860adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell}
125960adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
1260e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
1261779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paulstatic void
1262ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerimg_filter_2d_array_nearest(struct sp_sampler_view *sp_sview,
1263ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                            struct sp_sampler *sp_samp,
126499e583120cde8820aae94eb0f8beb723509398fcDave Airlie                            const struct img_filter_args *args,
1265229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                            float *rgba)
1266779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul{
1267ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
1268779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   int width, height;
1269229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x, y, layer;
1270779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   union tex_tile_address addr;
1271229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *out;
1272229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
1273779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
127499e583120cde8820aae94eb0f8beb723509398fcDave Airlie   width = u_minify(texture->width0, args->level);
127599e583120cde8820aae94eb0f8beb723509398fcDave Airlie   height = u_minify(texture->height0, args->level);
1276779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1277779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   assert(width > 0);
1278779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   assert(height > 0);
1279779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1280779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   addr.value = 0;
128199e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
1282779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
12833f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x);
12843f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->nearest_texcoord_t(args->t, height, args->offset[1], &y);
128599e583120cde8820aae94eb0f8beb723509398fcDave Airlie   layer = coord_to_layer(args->p, sp_sview->base.u.tex.first_layer,
1286adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                          sp_sview->base.u.tex.last_layer);
1287779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1288ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   out = get_texel_2d_array(sp_sview, sp_samp, addr, x, y, layer);
1289229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++)
1290229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = out[c];
1291779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1292779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   if (DEBUG_TEX) {
1293779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul      print_sample(__FUNCTION__, rgba);
1294779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   }
1295779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul}
1296779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1297779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1298e12810d92ffb3547680b227bf88937c03018112bBrian Paulstatic void
1299ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerimg_filter_cube_nearest(struct sp_sampler_view *sp_sview,
1300ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                        struct sp_sampler *sp_samp,
130199e583120cde8820aae94eb0f8beb723509398fcDave Airlie                        const struct img_filter_args *args,
1302229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                        float *rgba)
13030dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul{
1304ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
1305f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul   int width, height;
1306adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   int x, y, layerface;
130781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   union tex_tile_address addr;
1308229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *out;
1309229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
131081601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
131199e583120cde8820aae94eb0f8beb723509398fcDave Airlie   width = u_minify(texture->width0, args->level);
131299e583120cde8820aae94eb0f8beb723509398fcDave Airlie   height = u_minify(texture->height0, args->level);
131309a1b912605ff48c8782dcc5aae55ac77e27037bBrian Paul
1314b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul   assert(width > 0);
13155dbedf3d7e99efe35fad308d382670e44cd60e25Brian Paul   assert(height > 0);
131681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
131781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   addr.value = 0;
131899e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
1319612cfb749c3526eeb446bbc631bf24716522f373Brian Paul
1320621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   /*
1321621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie    * If NEAREST filtering is done within a miplevel, always apply wrap
1322621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie    * mode CLAMP_TO_EDGE.
1323621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie    */
1324ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   if (sp_samp->base.seamless_cube_map) {
13253f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      wrap_nearest_clamp_to_edge(args->s, width, args->offset[0], &x);
13263f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      wrap_nearest_clamp_to_edge(args->t, height, args->offset[1], &y);
1327621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   } else {
13287681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger      /* Would probably make sense to ignore mode and just do edge clamp */
13293f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x);
13303f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      sp_samp->nearest_texcoord_t(args->t, height, args->offset[1], &y);
1331621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   }
1332f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul
133399e583120cde8820aae94eb0f8beb723509398fcDave Airlie   layerface = args->face_id + sp_sview->base.u.tex.first_layer;
1334adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   out = get_texel_cube_array(sp_sview, sp_samp, addr, x, y, layerface);
1335229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++)
1336229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = out[c];
13374250882ccf8326ba9074c671110370534489caa6Brian Paul
13384250882ccf8326ba9074c671110370534489caa6Brian Paul   if (DEBUG_TEX) {
13394250882ccf8326ba9074c671110370534489caa6Brian Paul      print_sample(__FUNCTION__, rgba);
13404250882ccf8326ba9074c671110370534489caa6Brian Paul   }
13410dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul}
134234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul
1343309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airliestatic void
1344ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerimg_filter_cube_array_nearest(struct sp_sampler_view *sp_sview,
1345ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                              struct sp_sampler *sp_samp,
134699e583120cde8820aae94eb0f8beb723509398fcDave Airlie                              const struct img_filter_args *args,
1347ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                              float *rgba)
1348ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger{
1349ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
1350309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   int width, height;
1351adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   int x, y, layerface;
1352309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   union tex_tile_address addr;
1353309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   const float *out;
1354309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   int c;
1355309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie
135699e583120cde8820aae94eb0f8beb723509398fcDave Airlie   width = u_minify(texture->width0, args->level);
135799e583120cde8820aae94eb0f8beb723509398fcDave Airlie   height = u_minify(texture->height0, args->level);
1358309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie
1359309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   assert(width > 0);
1360309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   assert(height > 0);
1361309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie
1362309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   addr.value = 0;
136399e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
1364309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie
13653f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x);
13663f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->nearest_texcoord_t(args->t, height, args->offset[1], &y);
136799e583120cde8820aae94eb0f8beb723509398fcDave Airlie   layerface = coord_to_layer(6 * args->p + sp_sview->base.u.tex.first_layer,
1368adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                              sp_sview->base.u.tex.first_layer,
136999e583120cde8820aae94eb0f8beb723509398fcDave Airlie                              sp_sview->base.u.tex.last_layer - 5) + args->face_id;
1370309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie
1371adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   out = get_texel_cube_array(sp_sview, sp_samp, addr, x, y, layerface);
1372309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   for (c = 0; c < TGSI_QUAD_SIZE; c++)
1373309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie      rgba[TGSI_NUM_CHANNELS*c] = out[c];
1374309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie
1375309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   if (DEBUG_TEX) {
1376309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie      print_sample(__FUNCTION__, rgba);
1377309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   }
1378309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie}
137934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul
13804fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
1381ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerimg_filter_3d_nearest(struct sp_sampler_view *sp_sview,
1382ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                      struct sp_sampler *sp_samp,
138399e583120cde8820aae94eb0f8beb723509398fcDave Airlie                      const struct img_filter_args *args,
1384229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                      float *rgba)
138534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul{
1386ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
13873d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul   int width, height, depth;
1388229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x, y, z;
138981601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   union tex_tile_address addr;
1390229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *out;
1391229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
1392b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul
139399e583120cde8820aae94eb0f8beb723509398fcDave Airlie   width = u_minify(texture->width0, args->level);
139499e583120cde8820aae94eb0f8beb723509398fcDave Airlie   height = u_minify(texture->height0, args->level);
139599e583120cde8820aae94eb0f8beb723509398fcDave Airlie   depth = u_minify(texture->depth0, args->level);
13963d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul
13973d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul   assert(width > 0);
13983d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul   assert(height > 0);
13993d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul   assert(depth > 0);
14003d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul
14013f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->nearest_texcoord_s(args->s, width,  args->offset[0], &x);
14023f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->nearest_texcoord_t(args->t, height, args->offset[1], &y);
14033f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->nearest_texcoord_p(args->p, depth,  args->offset[2], &z);
14043d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul
140581601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   addr.value = 0;
140699e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
140781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
1408ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   out = get_texel_3d(sp_sview, sp_samp, addr, x, y, z);
1409229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++)
1410229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = out[c];
141134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul}
141234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul
141334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul
141434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paulstatic void
1415ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerimg_filter_1d_linear(struct sp_sampler_view *sp_sview,
1416ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                     struct sp_sampler *sp_samp,
141799e583120cde8820aae94eb0f8beb723509398fcDave Airlie                     const struct img_filter_args *args,
1418229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                     float *rgba)
141934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul{
1420ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
14214fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   int width;
1422229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x0, x1;
1423229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float xw; /* weights */
142481601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   union tex_tile_address addr;
1425229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *tx0, *tx1;
1426229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
14274fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
142899e583120cde8820aae94eb0f8beb723509398fcDave Airlie   width = u_minify(texture->width0, args->level);
14294fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
14304fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   assert(width > 0);
14314fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
143281601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   addr.value = 0;
143399e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
143481601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
14353f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->linear_texcoord_s(args->s, width, args->offset[0], &x0, &x1, &xw);
14364fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1437ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx0 = get_texel_2d(sp_sview, sp_samp, addr, x0, 0);
1438ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx1 = get_texel_2d(sp_sview, sp_samp, addr, x1, 0);
14394fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1440229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   /* interpolate R, G, B, A */
1441229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++)
1442229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = lerp(xw, tx0[c], tx1[c]);
144334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul}
144434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul
144581601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
144660adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwellstatic void
1447ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerimg_filter_1d_array_linear(struct sp_sampler_view *sp_sview,
1448ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                           struct sp_sampler *sp_samp,
144999e583120cde8820aae94eb0f8beb723509398fcDave Airlie                           const struct img_filter_args *args,
1450229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                           float *rgba)
1451779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul{
1452ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
1453779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   int width;
1454229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x0, x1, layer;
1455229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float xw; /* weights */
1456779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   union tex_tile_address addr;
1457229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *tx0, *tx1;
1458229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
1459779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
146099e583120cde8820aae94eb0f8beb723509398fcDave Airlie   width = u_minify(texture->width0, args->level);
1461779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1462779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   assert(width > 0);
1463779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1464779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   addr.value = 0;
146599e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
1466779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
14673f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->linear_texcoord_s(args->s, width, args->offset[0], &x0, &x1, &xw);
146899e583120cde8820aae94eb0f8beb723509398fcDave Airlie   layer = coord_to_layer(args->t, sp_sview->base.u.tex.first_layer,
1469adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                          sp_sview->base.u.tex.last_layer);
1470779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1471ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx0 = get_texel_1d_array(sp_sview, sp_samp, addr, x0, layer);
1472ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx1 = get_texel_1d_array(sp_sview, sp_samp, addr, x1, layer);
1473779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1474229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   /* interpolate R, G, B, A */
1475229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++)
1476229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = lerp(xw, tx0[c], tx1[c]);
1477779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul}
1478779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1479779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1480779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paulstatic void
1481ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerimg_filter_2d_linear(struct sp_sampler_view *sp_sview,
1482ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                     struct sp_sampler *sp_samp,
148399e583120cde8820aae94eb0f8beb723509398fcDave Airlie                     const struct img_filter_args *args,
1484229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                     float *rgba)
148560adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell{
1486ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
148760adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell   int width, height;
1488229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x0, y0, x1, y1;
1489229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float xw, yw; /* weights */
149060adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell   union tex_tile_address addr;
1491229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *tx0, *tx1, *tx2, *tx3;
1492229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
149360adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
149499e583120cde8820aae94eb0f8beb723509398fcDave Airlie   width = u_minify(texture->width0, args->level);
149599e583120cde8820aae94eb0f8beb723509398fcDave Airlie   height = u_minify(texture->height0, args->level);
149660adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
149760adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell   assert(width > 0);
14985dbedf3d7e99efe35fad308d382670e44cd60e25Brian Paul   assert(height > 0);
149960adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
150060adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell   addr.value = 0;
150199e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
150260adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
15033f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->linear_texcoord_s(args->s, width,  args->offset[0], &x0, &x1, &xw);
15043f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->linear_texcoord_t(args->t, height, args->offset[1], &y0, &y1, &yw);
150560adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
1506ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx0 = get_texel_2d(sp_sview, sp_samp, addr, x0, y0);
1507ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx1 = get_texel_2d(sp_sview, sp_samp, addr, x1, y0);
1508ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx2 = get_texel_2d(sp_sview, sp_samp, addr, x0, y1);
1509ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx3 = get_texel_2d(sp_sview, sp_samp, addr, x1, y1);
151060adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
1511229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   /* interpolate R, G, B, A */
1512229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++)
1513229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw,
1514229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                          tx0[c], tx1[c],
1515229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                          tx2[c], tx3[c]);
151660adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell}
151781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
151881601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
1519b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paulstatic void
1520ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerimg_filter_2d_array_linear(struct sp_sampler_view *sp_sview,
1521ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                           struct sp_sampler *sp_samp,
152299e583120cde8820aae94eb0f8beb723509398fcDave Airlie                           const struct img_filter_args *args,
1523229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                           float *rgba)
1524779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul{
1525ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
1526779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   int width, height;
1527229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x0, y0, x1, y1, layer;
1528229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float xw, yw; /* weights */
1529779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   union tex_tile_address addr;
1530229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *tx0, *tx1, *tx2, *tx3;
1531229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
1532779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
153399e583120cde8820aae94eb0f8beb723509398fcDave Airlie   width = u_minify(texture->width0, args->level);
153499e583120cde8820aae94eb0f8beb723509398fcDave Airlie   height = u_minify(texture->height0, args->level);
1535779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1536779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   assert(width > 0);
1537779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   assert(height > 0);
1538779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1539779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   addr.value = 0;
154099e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
1541779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
15423f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->linear_texcoord_s(args->s, width,  args->offset[0], &x0, &x1, &xw);
15433f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->linear_texcoord_t(args->t, height, args->offset[1], &y0, &y1, &yw);
154499e583120cde8820aae94eb0f8beb723509398fcDave Airlie   layer = coord_to_layer(args->p, sp_sview->base.u.tex.first_layer,
1545adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                          sp_sview->base.u.tex.last_layer);
1546779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1547ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx0 = get_texel_2d_array(sp_sview, sp_samp, addr, x0, y0, layer);
1548ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx1 = get_texel_2d_array(sp_sview, sp_samp, addr, x1, y0, layer);
1549ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx2 = get_texel_2d_array(sp_sview, sp_samp, addr, x0, y1, layer);
1550ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx3 = get_texel_2d_array(sp_sview, sp_samp, addr, x1, y1, layer);
1551779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1552229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   /* interpolate R, G, B, A */
1553229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++)
1554229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw,
1555229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                          tx0[c], tx1[c],
1556229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                          tx2[c], tx3[c]);
1557779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul}
1558779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1559779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1560779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paulstatic void
1561ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerimg_filter_cube_linear(struct sp_sampler_view *sp_sview,
1562ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                       struct sp_sampler *sp_samp,
156399e583120cde8820aae94eb0f8beb723509398fcDave Airlie                       const struct img_filter_args *args,
1564229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                       float *rgba)
1565b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul{
1566ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
1567b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul   int width, height;
1568adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   int x0, y0, x1, y1, layer;
1569229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float xw, yw; /* weights */
1570adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   union tex_tile_address addr;
1571229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *tx0, *tx1, *tx2, *tx3;
1572ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   float corner0[TGSI_QUAD_SIZE], corner1[TGSI_QUAD_SIZE],
1573ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         corner2[TGSI_QUAD_SIZE], corner3[TGSI_QUAD_SIZE];
1574229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
1575b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul
157699e583120cde8820aae94eb0f8beb723509398fcDave Airlie   width = u_minify(texture->width0, args->level);
157799e583120cde8820aae94eb0f8beb723509398fcDave Airlie   height = u_minify(texture->height0, args->level);
1578b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul
1579b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul   assert(width > 0);
15805dbedf3d7e99efe35fad308d382670e44cd60e25Brian Paul   assert(height > 0);
1581b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul
158281601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   addr.value = 0;
158399e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
158481601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
1585621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   /*
1586621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie    * For seamless if LINEAR filtering is done within a miplevel,
1587621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie    * always apply wrap mode CLAMP_TO_BORDER.
1588621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie    */
1589ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   if (sp_samp->base.seamless_cube_map) {
15907681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger      /* Note this is a bit overkill, actual clamping is not required */
15913f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      wrap_linear_clamp_to_border(args->s, width, args->offset[0], &x0, &x1, &xw);
15923f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      wrap_linear_clamp_to_border(args->t, height, args->offset[1], &y0, &y1, &yw);
1593621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   } else {
15947681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger      /* Would probably make sense to ignore mode and just do edge clamp */
15953f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      sp_samp->linear_texcoord_s(args->s, width,  args->offset[0], &x0, &x1, &xw);
15963f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      sp_samp->linear_texcoord_t(args->t, height, args->offset[1], &y0, &y1, &yw);
1597621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   }
15984fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1599adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   layer = sp_sview->base.u.tex.first_layer;
16004fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1601ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   if (sp_samp->base.seamless_cube_map) {
160299e583120cde8820aae94eb0f8beb723509398fcDave Airlie      tx0 = get_texel_cube_seamless(sp_sview, addr, x0, y0, corner0, layer, args->face_id);
160399e583120cde8820aae94eb0f8beb723509398fcDave Airlie      tx1 = get_texel_cube_seamless(sp_sview, addr, x1, y0, corner1, layer, args->face_id);
160499e583120cde8820aae94eb0f8beb723509398fcDave Airlie      tx2 = get_texel_cube_seamless(sp_sview, addr, x0, y1, corner2, layer, args->face_id);
160599e583120cde8820aae94eb0f8beb723509398fcDave Airlie      tx3 = get_texel_cube_seamless(sp_sview, addr, x1, y1, corner3, layer, args->face_id);
1606621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   } else {
160799e583120cde8820aae94eb0f8beb723509398fcDave Airlie      tx0 = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y0, layer + args->face_id);
160899e583120cde8820aae94eb0f8beb723509398fcDave Airlie      tx1 = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y0, layer + args->face_id);
160999e583120cde8820aae94eb0f8beb723509398fcDave Airlie      tx2 = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y1, layer + args->face_id);
161099e583120cde8820aae94eb0f8beb723509398fcDave Airlie      tx3 = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y1, layer + args->face_id);
1611621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   }
1612adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger
1613229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   /* interpolate R, G, B, A */
1614229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++)
1615229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw,
1616229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                          tx0[c], tx1[c],
1617229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                          tx2[c], tx3[c]);
16184fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
16194fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
16204fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
16214fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
1622ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerimg_filter_cube_array_linear(struct sp_sampler_view *sp_sview,
1623ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                             struct sp_sampler *sp_samp,
162499e583120cde8820aae94eb0f8beb723509398fcDave Airlie                             const struct img_filter_args *args,
1625309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie                             float *rgba)
1626309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie{
1627ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
1628309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   int width, height;
1629309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   int x0, y0, x1, y1, layer;
1630309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   float xw, yw; /* weights */
1631aafdc5bda424c2b04f23a54480b402dd64333555Dave Airlie   union tex_tile_address addr;
1632309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   const float *tx0, *tx1, *tx2, *tx3;
1633adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   float corner0[TGSI_QUAD_SIZE], corner1[TGSI_QUAD_SIZE],
1634adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger         corner2[TGSI_QUAD_SIZE], corner3[TGSI_QUAD_SIZE];
1635309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   int c;
1636309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie
163799e583120cde8820aae94eb0f8beb723509398fcDave Airlie   width = u_minify(texture->width0, args->level);
163899e583120cde8820aae94eb0f8beb723509398fcDave Airlie   height = u_minify(texture->height0, args->level);
1639309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie
1640309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   assert(width > 0);
1641309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   assert(height > 0);
1642309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie
1643309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   addr.value = 0;
164499e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
1645309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie
1646adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   /*
1647adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger    * For seamless if LINEAR filtering is done within a miplevel,
1648adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger    * always apply wrap mode CLAMP_TO_BORDER.
1649adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger    */
1650adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   if (sp_samp->base.seamless_cube_map) {
1651adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      /* Note this is a bit overkill, actual clamping is not required */
16523f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      wrap_linear_clamp_to_border(args->s, width, args->offset[0], &x0, &x1, &xw);
16533f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      wrap_linear_clamp_to_border(args->t, height, args->offset[1], &y0, &y1, &yw);
1654adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   } else {
1655adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      /* Would probably make sense to ignore mode and just do edge clamp */
16563f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      sp_samp->linear_texcoord_s(args->s, width,  args->offset[0], &x0, &x1, &xw);
16573f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      sp_samp->linear_texcoord_t(args->t, height, args->offset[1], &y0, &y1, &yw);
1658adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   }
1659adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger
166099e583120cde8820aae94eb0f8beb723509398fcDave Airlie   layer = coord_to_layer(6 * args->p + sp_sview->base.u.tex.first_layer,
1661adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                          sp_sview->base.u.tex.first_layer,
1662adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                          sp_sview->base.u.tex.last_layer - 5);
1663309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie
1664adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   if (sp_samp->base.seamless_cube_map) {
166599e583120cde8820aae94eb0f8beb723509398fcDave Airlie      tx0 = get_texel_cube_seamless(sp_sview, addr, x0, y0, corner0, layer, args->face_id);
166699e583120cde8820aae94eb0f8beb723509398fcDave Airlie      tx1 = get_texel_cube_seamless(sp_sview, addr, x1, y0, corner1, layer, args->face_id);
166799e583120cde8820aae94eb0f8beb723509398fcDave Airlie      tx2 = get_texel_cube_seamless(sp_sview, addr, x0, y1, corner2, layer, args->face_id);
166899e583120cde8820aae94eb0f8beb723509398fcDave Airlie      tx3 = get_texel_cube_seamless(sp_sview, addr, x1, y1, corner3, layer, args->face_id);
1669adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   } else {
167099e583120cde8820aae94eb0f8beb723509398fcDave Airlie      tx0 = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y0, layer + args->face_id);
167199e583120cde8820aae94eb0f8beb723509398fcDave Airlie      tx1 = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y0, layer + args->face_id);
167299e583120cde8820aae94eb0f8beb723509398fcDave Airlie      tx2 = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y1, layer + args->face_id);
167399e583120cde8820aae94eb0f8beb723509398fcDave Airlie      tx3 = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y1, layer + args->face_id);
1674adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   }
1675309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie
1676309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   /* interpolate R, G, B, A */
1677309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   for (c = 0; c < TGSI_QUAD_SIZE; c++)
1678309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie      rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw,
1679309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie                                          tx0[c], tx1[c],
1680309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie                                          tx2[c], tx3[c]);
1681309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie}
1682309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie
1683309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airliestatic void
1684ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerimg_filter_3d_linear(struct sp_sampler_view *sp_sview,
1685ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                     struct sp_sampler *sp_samp,
168699e583120cde8820aae94eb0f8beb723509398fcDave Airlie                     const struct img_filter_args *args,
1687229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                     float *rgba)
16884fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
1689ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
16904fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   int width, height, depth;
1691229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x0, x1, y0, y1, z0, z1;
1692229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float xw, yw, zw; /* interpolation weights */
169381601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   union tex_tile_address addr;
1694229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *tx00, *tx01, *tx02, *tx03, *tx10, *tx11, *tx12, *tx13;
1695229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
16964fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
169799e583120cde8820aae94eb0f8beb723509398fcDave Airlie   width = u_minify(texture->width0, args->level);
169899e583120cde8820aae94eb0f8beb723509398fcDave Airlie   height = u_minify(texture->height0, args->level);
169999e583120cde8820aae94eb0f8beb723509398fcDave Airlie   depth = u_minify(texture->depth0, args->level);
17004fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
170181601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   addr.value = 0;
170299e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
170381601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
17044fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   assert(width > 0);
17054fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   assert(height > 0);
17064fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   assert(depth > 0);
17074fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
17083f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->linear_texcoord_s(args->s, width,  args->offset[0], &x0, &x1, &xw);
17093f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->linear_texcoord_t(args->t, height, args->offset[1], &y0, &y1, &yw);
17103f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->linear_texcoord_p(args->p, depth,  args->offset[2], &z0, &z1, &zw);
17114fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1712ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx00 = get_texel_3d(sp_sview, sp_samp, addr, x0, y0, z0);
1713ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx01 = get_texel_3d(sp_sview, sp_samp, addr, x1, y0, z0);
1714ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx02 = get_texel_3d(sp_sview, sp_samp, addr, x0, y1, z0);
1715ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx03 = get_texel_3d(sp_sview, sp_samp, addr, x1, y1, z0);
171681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
1717ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx10 = get_texel_3d(sp_sview, sp_samp, addr, x0, y0, z1);
1718ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx11 = get_texel_3d(sp_sview, sp_samp, addr, x1, y0, z1);
1719ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx12 = get_texel_3d(sp_sview, sp_samp, addr, x0, y1, z1);
1720ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx13 = get_texel_3d(sp_sview, sp_samp, addr, x1, y1, z1);
172181601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
17224fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      /* interpolate R, G, B, A */
1723229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (c = 0; c < TGSI_QUAD_SIZE; c++)
1724229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] =  lerp_3d(xw, yw, zw,
1725229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                           tx00[c], tx01[c],
1726229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                           tx02[c], tx03[c],
1727229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                           tx10[c], tx11[c],
1728229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                           tx12[c], tx13[c]);
17294fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
17304fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
17314fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
173275d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger/* Calculate level of detail for every fragment,
173375d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger * with lambda already computed.
17344bfe1c955fe679547c8a03119d1681e33593c768Michal Krol * Note that lambda has already been biased by global LOD bias.
173575d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger * \param biased_lambda per-quad lambda.
173675d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger * \param lod_in per-fragment lod_bias or explicit_lod.
173775d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger * \param lod returns the per-fragment lod.
17384bfe1c955fe679547c8a03119d1681e33593c768Michal Krol */
17394bfe1c955fe679547c8a03119d1681e33593c768Michal Krolstatic INLINE void
17404bfe1c955fe679547c8a03119d1681e33593c768Michal Krolcompute_lod(const struct pipe_sampler_state *sampler,
174175d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger            enum tgsi_sampler_control control,
17424bfe1c955fe679547c8a03119d1681e33593c768Michal Krol            const float biased_lambda,
174375d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger            const float lod_in[TGSI_QUAD_SIZE],
17446b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard            float lod[TGSI_QUAD_SIZE])
17454bfe1c955fe679547c8a03119d1681e33593c768Michal Krol{
174675d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger   float min_lod = sampler->min_lod;
174775d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger   float max_lod = sampler->max_lod;
17484bfe1c955fe679547c8a03119d1681e33593c768Michal Krol   uint i;
17494bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
175075d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger   switch (control) {
175175d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger   case tgsi_sampler_lod_none:
175275d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger   case tgsi_sampler_lod_zero:
17536ace2e41da7dded630d932d03bacb7e14a93d47aRoland Scheidegger   /* XXX FIXME */
17546ace2e41da7dded630d932d03bacb7e14a93d47aRoland Scheidegger   case tgsi_sampler_derivs_explicit:
175575d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      lod[0] = lod[1] = lod[2] = lod[3] = CLAMP(biased_lambda, min_lod, max_lod);
175675d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      break;
175775d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger   case tgsi_sampler_lod_bias:
175875d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      for (i = 0; i < TGSI_QUAD_SIZE; i++) {
175975d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger         lod[i] = biased_lambda + lod_in[i];
176075d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger         lod[i] = CLAMP(lod[i], min_lod, max_lod);
176175d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      }
176275d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      break;
176375d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger   case tgsi_sampler_lod_explicit:
176475d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      for (i = 0; i < TGSI_QUAD_SIZE; i++) {
176575d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger         lod[i] = CLAMP(lod_in[i], min_lod, max_lod);
176675d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      }
176775d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      break;
176875d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger   default:
176975d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      assert(0);
177075d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      lod[0] = lod[1] = lod[2] = lod[3] = 0.0f;
177175d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger   }
177275d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger}
177375d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger
177475d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger
177575d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger/* Calculate level of detail for every fragment.
177675d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger * \param lod_in per-fragment lod_bias or explicit_lod.
177775d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger * \param lod results per-fragment lod.
177875d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger */
177975d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheideggerstatic INLINE void
1780ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggercompute_lambda_lod(struct sp_sampler_view *sp_sview,
1781ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                   struct sp_sampler *sp_samp,
178275d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger                   const float s[TGSI_QUAD_SIZE],
178375d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger                   const float t[TGSI_QUAD_SIZE],
178475d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger                   const float p[TGSI_QUAD_SIZE],
178575d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger                   const float lod_in[TGSI_QUAD_SIZE],
178675d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger                   enum tgsi_sampler_control control,
178775d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger                   float lod[TGSI_QUAD_SIZE])
178875d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger{
1789ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_sampler_state *sampler = &sp_samp->base;
179075d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger   float lod_bias = sampler->lod_bias;
179175d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger   float min_lod = sampler->min_lod;
179275d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger   float max_lod = sampler->max_lod;
179375d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger   float lambda;
179475d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger   uint i;
179575d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger
179675d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger   switch (control) {
179775d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger   case tgsi_sampler_lod_none:
17986ace2e41da7dded630d932d03bacb7e14a93d47aRoland Scheidegger      /* XXX FIXME */
17996ace2e41da7dded630d932d03bacb7e14a93d47aRoland Scheidegger   case tgsi_sampler_derivs_explicit:
1800ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      lambda = sp_sview->compute_lambda(sp_sview, s, t, p) + lod_bias;
180175d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      lod[0] = lod[1] = lod[2] = lod[3] = CLAMP(lambda, min_lod, max_lod);
180275d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      break;
180375d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger   case tgsi_sampler_lod_bias:
1804ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      lambda = sp_sview->compute_lambda(sp_sview, s, t, p) + lod_bias;
180575d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      for (i = 0; i < TGSI_QUAD_SIZE; i++) {
180675d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger         lod[i] = lambda + lod_in[i];
180775d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger         lod[i] = CLAMP(lod[i], min_lod, max_lod);
180875d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      }
180975d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      break;
181075d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger   case tgsi_sampler_lod_explicit:
181175d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      for (i = 0; i < TGSI_QUAD_SIZE; i++) {
181275d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger         lod[i] = CLAMP(lod_in[i], min_lod, max_lod);
181375d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      }
181475d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      break;
181575d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger   case tgsi_sampler_lod_zero:
181675d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      /* this is all static state in the sampler really need clamp here? */
181775d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      lod[0] = lod[1] = lod[2] = lod[3] = CLAMP(lod_bias, min_lod, max_lod);
181875d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      break;
181975d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger   default:
182075d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      assert(0);
182175d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      lod[0] = lod[1] = lod[2] = lod[3] = 0.0f;
18224bfe1c955fe679547c8a03119d1681e33593c768Michal Krol   }
18234bfe1c955fe679547c8a03119d1681e33593c768Michal Krol}
18244bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
18254bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
18264fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
1827ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggermip_filter_linear(struct sp_sampler_view *sp_sview,
1828ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                  struct sp_sampler *sp_samp,
1829ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                  img_filter_func min_filter,
1830ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                  img_filter_func mag_filter,
18316b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float s[TGSI_QUAD_SIZE],
18326b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float t[TGSI_QUAD_SIZE],
18336b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float p[TGSI_QUAD_SIZE],
18346b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float c0[TGSI_QUAD_SIZE],
183575d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger                  const float lod_in[TGSI_QUAD_SIZE],
18368bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie                  const struct filter_args *filt_args,
18376b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
18384fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
1839b1c1c7d31b3ad625243616597028e7d599eb8190Roland Scheidegger   const struct pipe_sampler_view *psview = &sp_sview->base;
1840229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int j;
18416b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float lod[TGSI_QUAD_SIZE];
184299e583120cde8820aae94eb0f8beb723509398fcDave Airlie   struct img_filter_args args;
18434fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
18448bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie   compute_lambda_lod(sp_sview, sp_samp, s, t, p, lod_in, filt_args->control, lod);
18454bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
18463f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   args.offset = filt_args->offset;
18473f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie
1848229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
1849b1c1c7d31b3ad625243616597028e7d599eb8190Roland Scheidegger      int level0 = psview->u.tex.first_level + (int)lod[j];
18504fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
185199e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.s = s[j];
185299e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.t = t[j];
185399e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.p = p[j];
185499e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.face_id = sp_sview->faces[j];
18554fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
185699e583120cde8820aae94eb0f8beb723509398fcDave Airlie      if (lod[j] < 0.0) {
185799e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.level = psview->u.tex.first_level;
185899e583120cde8820aae94eb0f8beb723509398fcDave Airlie         mag_filter(sp_sview, sp_samp, &args, &rgba[0][j]);
185999e583120cde8820aae94eb0f8beb723509398fcDave Airlie      }
186099e583120cde8820aae94eb0f8beb723509398fcDave Airlie      else if (level0 >= (int) psview->u.tex.last_level) {
186199e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.level = psview->u.tex.last_level;
186299e583120cde8820aae94eb0f8beb723509398fcDave Airlie         min_filter(sp_sview, sp_samp, &args, &rgba[0][j]);
186399e583120cde8820aae94eb0f8beb723509398fcDave Airlie      }
1864229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      else {
1865229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         float levelBlend = frac(lod[j]);
1866229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         float rgbax[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
1867229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         int c;
1868229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert
186999e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.level = level0;
187099e583120cde8820aae94eb0f8beb723509398fcDave Airlie         min_filter(sp_sview, sp_samp, &args, &rgbax[0][0]);
187199e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.level = level0+1;
187299e583120cde8820aae94eb0f8beb723509398fcDave Airlie         min_filter(sp_sview, sp_samp, &args, &rgbax[0][1]);
18734fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
18744fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         for (c = 0; c < 4; c++) {
1875229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert            rgba[c][j] = lerp(levelBlend, rgbax[c][0], rgbax[c][1]);
1876b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul         }
1877b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul      }
1878b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul   }
18794250882ccf8326ba9074c671110370534489caa6Brian Paul
18804250882ccf8326ba9074c671110370534489caa6Brian Paul   if (DEBUG_TEX) {
1881229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      print_sample_4(__FUNCTION__, rgba);
18824250882ccf8326ba9074c671110370534489caa6Brian Paul   }
1883b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul}
1884b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul
1885b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul
188685425b3b609c480cd024b217b1efd0b9153bed58Brian Paul/**
188785425b3b609c480cd024b217b1efd0b9153bed58Brian Paul * Compute nearest mipmap level from texcoords.
188885425b3b609c480cd024b217b1efd0b9153bed58Brian Paul * Then sample the texture level for four elements of a quad.
188985425b3b609c480cd024b217b1efd0b9153bed58Brian Paul * \param c0  the LOD bias factors, or absolute LODs (depending on control)
189085425b3b609c480cd024b217b1efd0b9153bed58Brian Paul */
18914fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
1892ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggermip_filter_nearest(struct sp_sampler_view *sp_sview,
1893ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                   struct sp_sampler *sp_samp,
1894ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                   img_filter_func min_filter,
1895ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                   img_filter_func mag_filter,
18966b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                   const float s[TGSI_QUAD_SIZE],
18976b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                   const float t[TGSI_QUAD_SIZE],
18986b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                   const float p[TGSI_QUAD_SIZE],
18996b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                   const float c0[TGSI_QUAD_SIZE],
190075d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger                   const float lod_in[TGSI_QUAD_SIZE],
19018bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie                   const struct filter_args *filt_args,
19026b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                   float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
19034fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
1904b1c1c7d31b3ad625243616597028e7d599eb8190Roland Scheidegger   const struct pipe_sampler_view *psview = &sp_sview->base;
19056b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float lod[TGSI_QUAD_SIZE];
1906229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int j;
190799e583120cde8820aae94eb0f8beb723509398fcDave Airlie   struct img_filter_args args;
19083f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie
19093f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   args.offset = filt_args->offset;
19108bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie   compute_lambda_lod(sp_sview, sp_samp, s, t, p, lod_in, filt_args->control, lod);
19114bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
1912229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
191399e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.s = s[j];
191499e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.t = t[j];
191599e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.p = p[j];
191699e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.face_id = sp_sview->faces[j];
191799e583120cde8820aae94eb0f8beb723509398fcDave Airlie
191899e583120cde8820aae94eb0f8beb723509398fcDave Airlie      if (lod[j] < 0.0) {
191999e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.level = psview->u.tex.first_level;
192099e583120cde8820aae94eb0f8beb723509398fcDave Airlie         mag_filter(sp_sview, sp_samp, &args, &rgba[0][j]);
192199e583120cde8820aae94eb0f8beb723509398fcDave Airlie      } else {
1922b1c1c7d31b3ad625243616597028e7d599eb8190Roland Scheidegger         int level = psview->u.tex.first_level + (int)(lod[j] + 0.5F);
192399e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.level = MIN2(level, (int)psview->u.tex.last_level);
192499e583120cde8820aae94eb0f8beb723509398fcDave Airlie         min_filter(sp_sview, sp_samp, &args, &rgba[0][j]);
1925229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      }
19264fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   }
192775276ea316610a5737f2115326482024aa09d02aBrian Paul
19284250882ccf8326ba9074c671110370534489caa6Brian Paul   if (DEBUG_TEX) {
1929229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      print_sample_4(__FUNCTION__, rgba);
19304250882ccf8326ba9074c671110370534489caa6Brian Paul   }
19314fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
19324fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
19334fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
19344fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
1935ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggermip_filter_none(struct sp_sampler_view *sp_sview,
1936ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                struct sp_sampler *sp_samp,
1937ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                img_filter_func min_filter,
1938ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                img_filter_func mag_filter,
19396b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                const float s[TGSI_QUAD_SIZE],
19406b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                const float t[TGSI_QUAD_SIZE],
19416b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                const float p[TGSI_QUAD_SIZE],
19426b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                const float c0[TGSI_QUAD_SIZE],
194375d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger                const float lod_in[TGSI_QUAD_SIZE],
19448bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie                const struct filter_args *filt_args,
19456b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
19464fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
19476b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float lod[TGSI_QUAD_SIZE];
1948229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int j;
194999e583120cde8820aae94eb0f8beb723509398fcDave Airlie   struct img_filter_args args;
19504bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
195199e583120cde8820aae94eb0f8beb723509398fcDave Airlie   args.level = sp_sview->base.u.tex.first_level;
19523f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   args.offset = filt_args->offset;
19533f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie
19548bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie   compute_lambda_lod(sp_sview, sp_samp, s, t, p, lod_in, filt_args->control, lod);
19554bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
1956229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
195799e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.s = s[j];
195899e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.t = t[j];
195999e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.p = p[j];
196099e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.face_id = sp_sview->faces[j];
196199e583120cde8820aae94eb0f8beb723509398fcDave Airlie      if (lod[j] < 0.0) {
196299e583120cde8820aae94eb0f8beb723509398fcDave Airlie         mag_filter(sp_sview, sp_samp, &args, &rgba[0][j]);
1963229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      }
1964229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      else {
196599e583120cde8820aae94eb0f8beb723509398fcDave Airlie         min_filter(sp_sview, sp_samp, &args, &rgba[0][j]);
1966229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      }
19674fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   }
19684fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
19694fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
19704fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1971229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertstatic void
1972ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggermip_filter_none_no_filter_select(struct sp_sampler_view *sp_sview,
1973ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                                 struct sp_sampler *sp_samp,
1974ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                                 img_filter_func min_filter,
1975ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                                 img_filter_func mag_filter,
1976ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                                 const float s[TGSI_QUAD_SIZE],
1977ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                                 const float t[TGSI_QUAD_SIZE],
1978ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                                 const float p[TGSI_QUAD_SIZE],
1979ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                                 const float c0[TGSI_QUAD_SIZE],
1980ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                                 const float lod_in[TGSI_QUAD_SIZE],
19818bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie                                 const struct filter_args *filt_args,
1982ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                                 float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
1983229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
1984229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int j;
198599e583120cde8820aae94eb0f8beb723509398fcDave Airlie   struct img_filter_args args;
198699e583120cde8820aae94eb0f8beb723509398fcDave Airlie   args.level = sp_sview->base.u.tex.first_level;
19873f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   args.offset = filt_args->offset;
198899e583120cde8820aae94eb0f8beb723509398fcDave Airlie   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
198999e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.s = s[j];
199099e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.t = t[j];
199199e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.p = p[j];
199299e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.face_id = sp_sview->faces[j];
199399e583120cde8820aae94eb0f8beb723509398fcDave Airlie      mag_filter(sp_sview, sp_samp, &args, &rgba[0][j]);
199499e583120cde8820aae94eb0f8beb723509398fcDave Airlie   }
1995229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert}
1996229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert
1997229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert
1998f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger/* For anisotropic filtering */
1999f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger#define WEIGHT_LUT_SIZE 1024
2000f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2001f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fängerstatic float *weightLut = NULL;
2002f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2003f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger/**
2004f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger * Creates the look-up table used to speed-up EWA sampling
2005f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger */
2006f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fängerstatic void
2007f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fängercreate_filter_table(void)
2008f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger{
2009f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   unsigned i;
2010f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   if (!weightLut) {
2011f32c9c210875b2ce4878f97b84bdd4739bd489f9José Fonseca      weightLut = (float *) MALLOC(WEIGHT_LUT_SIZE * sizeof(float));
2012f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2013f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      for (i = 0; i < WEIGHT_LUT_SIZE; ++i) {
2014f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         float alpha = 2;
2015f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         float r2 = (float) i / (float) (WEIGHT_LUT_SIZE - 1);
2016f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         float weight = (float) exp(-alpha * r2);
2017f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         weightLut[i] = weight;
2018f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      }
2019f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   }
2020f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger}
2021f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2022f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2023f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger/**
2024f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger * Elliptical weighted average (EWA) filter for producing high quality
2025f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger * anisotropic filtered results.
2026229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert * Based on the Higher Quality Elliptical Weighted Average Filter
2027f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger * published by Paul S. Heckbert in his Master's Thesis
2028f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger * "Fundamentals of Texture Mapping and Image Warping" (1989)
2029f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger */
2030f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fängerstatic void
2031ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerimg_filter_2d_ewa(struct sp_sampler_view *sp_sview,
2032ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                  struct sp_sampler *sp_samp,
2033ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                  img_filter_func min_filter,
2034ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                  img_filter_func mag_filter,
20356b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float s[TGSI_QUAD_SIZE],
20366b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float t[TGSI_QUAD_SIZE],
20376b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float p[TGSI_QUAD_SIZE],
2038229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                  unsigned level,
2039f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                  const float dudx, const float dvdx,
2040f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                  const float dudy, const float dvdy,
20416b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
2042f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger{
2043ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
2044f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2045229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   // ??? Won't the image filters blow up if level is negative?
2046229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   unsigned level0 = level > 0 ? level : 0;
204710393038f8d8279aca53df020c608f205e624043Brian Paul   float scaling = 1.0f / (1 << level0);
2048f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   int width = u_minify(texture->width0, level0);
2049f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   int height = u_minify(texture->height0, level0);
205099e583120cde8820aae94eb0f8beb723509398fcDave Airlie   struct img_filter_args args;
2051f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   float ux = dudx * scaling;
2052f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   float vx = dvdx * scaling;
2053f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   float uy = dudy * scaling;
2054f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   float vy = dvdy * scaling;
2055f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2056f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   /* compute ellipse coefficients to bound the region:
2057f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger    * A*x*x + B*x*y + C*y*y = F.
2058f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger    */
2059f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   float A = vx*vx+vy*vy+1;
2060f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   float B = -2*(ux*vx+uy*vy);
2061f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   float C = ux*ux+uy*uy+1;
206210393038f8d8279aca53df020c608f205e624043Brian Paul   float F = A*C-B*B/4.0f;
2063f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2064f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   /* check if it is an ellipse */
2065bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   /* assert(F > 0.0); */
2066f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2067f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   /* Compute the ellipse's (u,v) bounding box in texture space */
206810393038f8d8279aca53df020c608f205e624043Brian Paul   float d = -B*B+4.0f*C*A;
2069919236f3a28adfb04403e3f0db458afb9a897fd4Brian Paul   float box_u = 2.0f / d * sqrtf(d*C*F); /* box_u -> half of bbox with   */
2070919236f3a28adfb04403e3f0db458afb9a897fd4Brian Paul   float box_v = 2.0f / d * sqrtf(A*d*F); /* box_v -> half of bbox height */
2071f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
20726b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float rgba_temp[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
20736b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float s_buffer[TGSI_QUAD_SIZE];
20746b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float t_buffer[TGSI_QUAD_SIZE];
20756b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float weight_buffer[TGSI_QUAD_SIZE];
2076f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   unsigned buffer_next;
2077f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   int j;
2078b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul   float den; /* = 0.0F; */
2079f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   float ddq;
2080b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul   float U; /* = u0 - tex_u; */
2081f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   int v;
2082f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2083f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   /* Scale ellipse formula to directly index the Filter Lookup Table.
2084f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger    * i.e. scale so that F = WEIGHT_LUT_SIZE-1
2085f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger    */
2086f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   double formScale = (double) (WEIGHT_LUT_SIZE - 1) / F;
2087f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   A *= formScale;
2088f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   B *= formScale;
2089f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   C *= formScale;
2090f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   /* F *= formScale; */ /* no need to scale F as we don't use it below here */
2091f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2092f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   /* For each quad, the du and dx values are the same and so the ellipse is
2093f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger    * also the same. Note that texel/image access can only be performed using
2094f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger    * a quad, i.e. it is not possible to get the pixel value for a single
2095f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger    * tex coord. In order to have a better performance, the access is buffered
2096b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul    * using the s_buffer/t_buffer and weight_buffer. Only when the buffer is
2097b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul    * full, then the pixel values are read from the image.
2098f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger    */
2099f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   ddq = 2 * A;
210099e583120cde8820aae94eb0f8beb723509398fcDave Airlie
210199e583120cde8820aae94eb0f8beb723509398fcDave Airlie   args.level = level;
21026b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
2103f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      /* Heckbert MS thesis, p. 59; scan over the bounding box of the ellipse
2104f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger       * and incrementally update the value of Ax^2+Bxy*Cy^2; when this
2105f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger       * value, q, is less than F, we're inside the ellipse
2106f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger       */
2107b82db9a3c0a1b96d8eb5d0d78aecaf0ab331431aBrian Paul      float tex_u = -0.5F + s[j] * texture->width0 * scaling;
2108b82db9a3c0a1b96d8eb5d0d78aecaf0ab331431aBrian Paul      float tex_v = -0.5F + t[j] * texture->height0 * scaling;
2109f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2110b82db9a3c0a1b96d8eb5d0d78aecaf0ab331431aBrian Paul      int u0 = (int) floorf(tex_u - box_u);
2111b82db9a3c0a1b96d8eb5d0d78aecaf0ab331431aBrian Paul      int u1 = (int) ceilf(tex_u + box_u);
2112b82db9a3c0a1b96d8eb5d0d78aecaf0ab331431aBrian Paul      int v0 = (int) floorf(tex_v - box_v);
2113b82db9a3c0a1b96d8eb5d0d78aecaf0ab331431aBrian Paul      int v1 = (int) ceilf(tex_v + box_v);
2114f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2115f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      float num[4] = {0.0F, 0.0F, 0.0F, 0.0F};
2116f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      buffer_next = 0;
2117f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      den = 0;
211899e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.face_id = sp_sview->faces[j];
211999e583120cde8820aae94eb0f8beb723509398fcDave Airlie
2120f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      U = u0 - tex_u;
2121f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      for (v = v0; v <= v1; ++v) {
2122f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         float V = v - tex_v;
2123f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         float dq = A * (2 * U + 1) + B * V;
2124f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         float q = (C * V + B * U) * V + A * U * U;
2125f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2126f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         int u;
2127f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         for (u = u0; u <= u1; ++u) {
2128b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul            /* Note that the ellipse has been pre-scaled so F =
2129b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul             * WEIGHT_LUT_SIZE - 1
2130b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul             */
2131f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger            if (q < WEIGHT_LUT_SIZE) {
2132f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger               /* as a LUT is used, q must never be negative;
2133f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                * should not happen, though
2134f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                */
2135f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger               const int qClamped = q >= 0.0F ? q : 0;
2136f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger               float weight = weightLut[qClamped];
2137f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2138f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger               weight_buffer[buffer_next] = weight;
2139f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger               s_buffer[buffer_next] = u / ((float) width);
2140f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger               t_buffer[buffer_next] = v / ((float) height);
2141f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2142f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger               buffer_next++;
21436b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard               if (buffer_next == TGSI_QUAD_SIZE) {
2144f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                  /* 4 texel coords are in the buffer -> read it now */
2145b82db9a3c0a1b96d8eb5d0d78aecaf0ab331431aBrian Paul                  unsigned jj;
2146f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                  /* it is assumed that samp->min_img_filter is set to
2147f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                   * img_filter_2d_nearest or one of the
2148f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                   * accelerated img_filter_2d_nearest_XXX functions.
2149f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                   */
2150f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                  for (jj = 0; jj < buffer_next; jj++) {
215199e583120cde8820aae94eb0f8beb723509398fcDave Airlie                     args.s = s_buffer[jj];
215299e583120cde8820aae94eb0f8beb723509398fcDave Airlie                     args.t = t_buffer[jj];
215399e583120cde8820aae94eb0f8beb723509398fcDave Airlie                     args.p = p[jj];
215499e583120cde8820aae94eb0f8beb723509398fcDave Airlie                     min_filter(sp_sview, sp_samp, &args, &rgba_temp[0][jj]);
2155f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                     num[0] += weight_buffer[jj] * rgba_temp[0][jj];
2156f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                     num[1] += weight_buffer[jj] * rgba_temp[1][jj];
2157f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                     num[2] += weight_buffer[jj] * rgba_temp[2][jj];
2158f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                     num[3] += weight_buffer[jj] * rgba_temp[3][jj];
2159f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                  }
2160f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2161f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                  buffer_next = 0;
2162f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger               }
2163f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2164f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger               den += weight;
2165f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger            }
2166f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger            q += dq;
2167f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger            dq += ddq;
2168f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         }
2169f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      }
2170f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2171b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul      /* if the tex coord buffer contains unread values, we will read
2172229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert       * them now.
2173f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger       */
2174f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      if (buffer_next > 0) {
2175b82db9a3c0a1b96d8eb5d0d78aecaf0ab331431aBrian Paul         unsigned jj;
2176f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         /* it is assumed that samp->min_img_filter is set to
2177f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger          * img_filter_2d_nearest or one of the
2178f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger          * accelerated img_filter_2d_nearest_XXX functions.
2179f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger          */
2180f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         for (jj = 0; jj < buffer_next; jj++) {
218199e583120cde8820aae94eb0f8beb723509398fcDave Airlie            args.s = s_buffer[jj];
218299e583120cde8820aae94eb0f8beb723509398fcDave Airlie            args.t = t_buffer[jj];
218399e583120cde8820aae94eb0f8beb723509398fcDave Airlie            args.p = p[jj];
218499e583120cde8820aae94eb0f8beb723509398fcDave Airlie            min_filter(sp_sview, sp_samp, &args, &rgba_temp[0][jj]);
2185f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger            num[0] += weight_buffer[jj] * rgba_temp[0][jj];
2186f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger            num[1] += weight_buffer[jj] * rgba_temp[1][jj];
2187f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger            num[2] += weight_buffer[jj] * rgba_temp[2][jj];
2188f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger            num[3] += weight_buffer[jj] * rgba_temp[3][jj];
2189f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         }
2190f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      }
2191f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2192f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      if (den <= 0.0F) {
2193b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul         /* Reaching this place would mean that no pixels intersected
2194b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul          * the ellipse.  This should never happen because the filter
2195b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul          * we use always intersects at least one pixel.
2196f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger          */
2197f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2198f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         /*rgba[0]=0;
2199f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         rgba[1]=0;
2200f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         rgba[2]=0;
2201f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         rgba[3]=0;*/
2202f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         /* not enough pixels in resampling, resort to direct interpolation */
220399e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.s = s[j];
220499e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.t = t[j];
220599e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.p = p[j];
220699e583120cde8820aae94eb0f8beb723509398fcDave Airlie         min_filter(sp_sview, sp_samp, &args, &rgba_temp[0][j]);
2207f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         den = 1;
2208f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         num[0] = rgba_temp[0][j];
2209f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         num[1] = rgba_temp[1][j];
2210f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         num[2] = rgba_temp[2][j];
2211f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         num[3] = rgba_temp[3][j];
2212f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      }
2213f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2214f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      rgba[0][j] = num[0] / den;
2215f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      rgba[1][j] = num[1] / den;
2216f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      rgba[2][j] = num[2] / den;
2217f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      rgba[3][j] = num[3] / den;
2218f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   }
2219f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger}
2220f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2221f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2222f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger/**
2223f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger * Sample 2D texture using an anisotropic filter.
2224f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger */
2225f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fängerstatic void
2226ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggermip_filter_linear_aniso(struct sp_sampler_view *sp_sview,
2227ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                        struct sp_sampler *sp_samp,
2228ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                        img_filter_func min_filter,
2229ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                        img_filter_func mag_filter,
22306b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                        const float s[TGSI_QUAD_SIZE],
22316b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                        const float t[TGSI_QUAD_SIZE],
22326b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                        const float p[TGSI_QUAD_SIZE],
22336b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                        const float c0[TGSI_QUAD_SIZE],
223475d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger                        const float lod_in[TGSI_QUAD_SIZE],
22358bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie                        const struct filter_args *filt_args,
22366b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                        float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
2237f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger{
2238ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
2239b1c1c7d31b3ad625243616597028e7d599eb8190Roland Scheidegger   const struct pipe_sampler_view *psview = &sp_sview->base;
2240f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   int level0;
2241f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   float lambda;
22426b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float lod[TGSI_QUAD_SIZE];
2243f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2244b1c1c7d31b3ad625243616597028e7d599eb8190Roland Scheidegger   float s_to_u = u_minify(texture->width0, psview->u.tex.first_level);
2245b1c1c7d31b3ad625243616597028e7d599eb8190Roland Scheidegger   float t_to_v = u_minify(texture->height0, psview->u.tex.first_level);
2246f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   float dudx = (s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]) * s_to_u;
2247f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   float dudy = (s[QUAD_TOP_LEFT]     - s[QUAD_BOTTOM_LEFT]) * s_to_u;
2248f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   float dvdx = (t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]) * t_to_v;
2249f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   float dvdy = (t[QUAD_TOP_LEFT]     - t[QUAD_BOTTOM_LEFT]) * t_to_v;
225099e583120cde8820aae94eb0f8beb723509398fcDave Airlie   struct img_filter_args args;
225199e583120cde8820aae94eb0f8beb723509398fcDave Airlie
22528bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie   if (filt_args->control == tgsi_sampler_lod_bias ||
22538bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie       filt_args->control == tgsi_sampler_lod_none ||
22546ace2e41da7dded630d932d03bacb7e14a93d47aRoland Scheidegger       /* XXX FIXME */
22558bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie       filt_args->control == tgsi_sampler_derivs_explicit) {
2256f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      /* note: instead of working with Px and Py, we will use the
2257f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger       * squared length instead, to avoid sqrt.
2258f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger       */
2259f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      float Px2 = dudx * dudx + dvdx * dvdx;
2260f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      float Py2 = dudy * dudy + dvdy * dvdy;
2261f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2262f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      float Pmax2;
2263f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      float Pmin2;
2264f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      float e;
2265ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      const float maxEccentricity = sp_samp->base.max_anisotropy * sp_samp->base.max_anisotropy;
2266f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2267f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      if (Px2 < Py2) {
2268f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         Pmax2 = Py2;
2269f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         Pmin2 = Px2;
2270f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      }
2271f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      else {
2272f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         Pmax2 = Px2;
2273f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         Pmin2 = Py2;
2274f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      }
2275f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2276f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      /* if the eccentricity of the ellipse is too big, scale up the shorter
2277f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger       * of the two vectors to limit the maximum amount of work per pixel
2278f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger       */
2279f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      e = Pmax2 / Pmin2;
2280f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      if (e > maxEccentricity) {
2281f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         /* float s=e / maxEccentricity;
2282f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger            minor[0] *= s;
2283f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger            minor[1] *= s;
2284f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger            Pmin2 *= s; */
2285f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         Pmin2 = Pmax2 / maxEccentricity;
2286f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      }
2287f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2288f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      /* note: we need to have Pmin=sqrt(Pmin2) here, but we can avoid
2289f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger       * this since 0.5*log(x) = log(sqrt(x))
2290f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger       */
2291ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      lambda = 0.5F * util_fast_log2(Pmin2) + sp_samp->base.lod_bias;
22928bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie      compute_lod(&sp_samp->base, filt_args->control, lambda, lod_in, lod);
2293f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   }
2294f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   else {
22958bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie      assert(filt_args->control == tgsi_sampler_lod_explicit ||
22968bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie             filt_args->control == tgsi_sampler_lod_zero);
22978bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie      compute_lod(&sp_samp->base, filt_args->control, sp_samp->base.lod_bias, lod_in, lod);
2298f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   }
2299f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2300f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   /* XXX: Take into account all lod values.
2301f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger    */
2302f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   lambda = lod[0];
2303b1c1c7d31b3ad625243616597028e7d599eb8190Roland Scheidegger   level0 = psview->u.tex.first_level + (int)lambda;
2304f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2305f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   /* If the ellipse covers the whole image, we can
2306f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger    * simply return the average of the whole image.
2307f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger    */
2308b1c1c7d31b3ad625243616597028e7d599eb8190Roland Scheidegger   if (level0 >= (int) psview->u.tex.last_level) {
2309229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      int j;
231099e583120cde8820aae94eb0f8beb723509398fcDave Airlie      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
231199e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.s = s[j];
231299e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.t = t[j];
231399e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.p = p[j];
231499e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.level = psview->u.tex.last_level;
231599e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.face_id = sp_sview->faces[j];
231699e583120cde8820aae94eb0f8beb723509398fcDave Airlie         min_filter(sp_sview, sp_samp, &args, &rgba[0][j]);
231799e583120cde8820aae94eb0f8beb723509398fcDave Airlie      }
2318f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   }
2319f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   else {
2320f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      /* don't bother interpolating between multiple LODs; it doesn't
2321f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger       * seem to be worth the extra running time.
2322f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger       */
2323ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      img_filter_2d_ewa(sp_sview, sp_samp, min_filter, mag_filter,
2324ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                        s, t, p, level0,
2325f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                        dudx, dvdx, dudy, dvdy, rgba);
2326f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   }
2327f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2328f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   if (DEBUG_TEX) {
2329229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      print_sample_4(__FUNCTION__, rgba);
2330f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   }
2331f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger}
2332f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2333f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2334e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul/**
2335e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul * Specialized version of mip_filter_linear with hard-wired calls to
23364fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell * 2d lambda calculation and 2d_linear_repeat_POT img filters.
2337a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul */
23384fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
23394fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellmip_filter_linear_2d_linear_repeat_POT(
2340ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   struct sp_sampler_view *sp_sview,
2341ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   struct sp_sampler *sp_samp,
2342ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   img_filter_func min_filter,
2343ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   img_filter_func mag_filter,
23446b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   const float s[TGSI_QUAD_SIZE],
23456b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   const float t[TGSI_QUAD_SIZE],
23466b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   const float p[TGSI_QUAD_SIZE],
23476b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   const float c0[TGSI_QUAD_SIZE],
234875d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger   const float lod_in[TGSI_QUAD_SIZE],
23498bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie   const struct filter_args *filt_args,
23506b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
235100c835918259f8d41c3f74eca679a972713b11b2Keith Whitwell{
2352b1c1c7d31b3ad625243616597028e7d599eb8190Roland Scheidegger   const struct pipe_sampler_view *psview = &sp_sview->base;
2353229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int j;
23546b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float lod[TGSI_QUAD_SIZE];
23554bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
23568bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie   compute_lambda_lod(sp_sview, sp_samp, s, t, p, lod_in, filt_args->control, lod);
23574bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
2358229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
2359b1c1c7d31b3ad625243616597028e7d599eb8190Roland Scheidegger      int level0 = psview->u.tex.first_level + (int)lod[j];
236099e583120cde8820aae94eb0f8beb723509398fcDave Airlie      struct img_filter_args args;
2361229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      /* Catches both negative and large values of level0:
2362229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert       */
236399e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.s = s[j];
236499e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.t = t[j];
236599e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.p = p[j];
236699e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.face_id = sp_sview->faces[j];
2367b1c1c7d31b3ad625243616597028e7d599eb8190Roland Scheidegger      if ((unsigned)level0 >= psview->u.tex.last_level) {
2368229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         if (level0 < 0)
236999e583120cde8820aae94eb0f8beb723509398fcDave Airlie            args.level = psview->u.tex.first_level;
2370229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         else
237199e583120cde8820aae94eb0f8beb723509398fcDave Airlie            args.level = psview->u.tex.last_level;
237299e583120cde8820aae94eb0f8beb723509398fcDave Airlie         img_filter_2d_linear_repeat_POT(sp_sview, sp_samp, &args,
237399e583120cde8820aae94eb0f8beb723509398fcDave Airlie                                         &rgba[0][j]);
23744fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
2375229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      }
2376229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      else {
2377229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         float levelBlend = frac(lod[j]);
2378229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         float rgbax[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
2379229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         int c;
23804fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
238199e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.level = level0;
238299e583120cde8820aae94eb0f8beb723509398fcDave Airlie         img_filter_2d_linear_repeat_POT(sp_sview, sp_samp, &args, &rgbax[0][0]);
238399e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.level = level0+1;
238499e583120cde8820aae94eb0f8beb723509398fcDave Airlie         img_filter_2d_linear_repeat_POT(sp_sview, sp_samp, &args, &rgbax[0][1]);
23854fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
2386229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         for (c = 0; c < TGSI_NUM_CHANNELS; c++)
2387229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert            rgba[c][j] = lerp(levelBlend, rgbax[c][0], rgbax[c][1]);
2388b1ff7dac537947d412bf423a73e7eacd76f90d84Brian Paul      }
2389ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul   }
23904250882ccf8326ba9074c671110370534489caa6Brian Paul
23914250882ccf8326ba9074c671110370534489caa6Brian Paul   if (DEBUG_TEX) {
2392229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      print_sample_4(__FUNCTION__, rgba);
23934250882ccf8326ba9074c671110370534489caa6Brian Paul   }
2394b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul}
2395b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul
2396b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul
2397e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul/**
2398e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul * Do shadow/depth comparisons.
23993d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul */
24004fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
2401ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggersample_compare(struct sp_sampler_view *sp_sview,
2402ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger               struct sp_sampler *sp_samp,
24036b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard               const float s[TGSI_QUAD_SIZE],
24046b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard               const float t[TGSI_QUAD_SIZE],
24056b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard               const float p[TGSI_QUAD_SIZE],
24066b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard               const float c0[TGSI_QUAD_SIZE],
2407309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie               const float c1[TGSI_QUAD_SIZE],
24084440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol               enum tgsi_sampler_control control,
24096b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard               float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
24103d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul{
2411ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_sampler_state *sampler = &sp_samp->base;
2412c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing   int j;
2413c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing   int k[4];
2414c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing   float pc[4];
2415aa84f1ad5537f5b0232eb681147cb3a3882323b8Roland Scheidegger   const struct util_format_description *format_desc;
2416aa84f1ad5537f5b0232eb681147cb3a3882323b8Roland Scheidegger   unsigned chan_type;
24173d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul
24184fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /**
24194fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell    * Compare texcoord 'p' (aka R) against texture value 'rgba[0]'
242097b778efe7949977b4e857413807d1efcad346aaDave Airlie    * for 2D Array texture we need to use the 'c0' (aka Q).
24214fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell    * When we sampled the depth texture, the depth value was put into all
24224fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell    * RGBA channels.  We look at the red channel here.
24234fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell    */
2424efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul
2425adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   if (sp_sview->base.target == PIPE_TEXTURE_2D_ARRAY ||
2426adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger       sp_sview->base.target == PIPE_TEXTURE_CUBE) {
2427c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[0] = c0[0];
2428c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[1] = c0[1];
2429c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[2] = c0[2];
2430c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[3] = c0[3];
2431adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   } else if (sp_sview->base.target == PIPE_TEXTURE_CUBE_ARRAY) {
2432c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[0] = c1[0];
2433c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[1] = c1[1];
2434c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[2] = c1[2];
2435c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[3] = c1[3];
243697b778efe7949977b4e857413807d1efcad346aaDave Airlie   } else {
2437c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[0] = p[0];
2438c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[1] = p[1];
2439c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[2] = p[2];
2440c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[3] = p[3];
244197b778efe7949977b4e857413807d1efcad346aaDave Airlie   }
2442aa84f1ad5537f5b0232eb681147cb3a3882323b8Roland Scheidegger
2443aa84f1ad5537f5b0232eb681147cb3a3882323b8Roland Scheidegger   format_desc = util_format_description(sp_sview->base.format);
2444aa84f1ad5537f5b0232eb681147cb3a3882323b8Roland Scheidegger   /* not entirely sure we couldn't end up with non-valid swizzle here */
2445aa84f1ad5537f5b0232eb681147cb3a3882323b8Roland Scheidegger   chan_type = format_desc->swizzle[0] <= UTIL_FORMAT_SWIZZLE_W ?
2446aa84f1ad5537f5b0232eb681147cb3a3882323b8Roland Scheidegger                  format_desc->channel[format_desc->swizzle[0]].type :
2447aa84f1ad5537f5b0232eb681147cb3a3882323b8Roland Scheidegger                  UTIL_FORMAT_TYPE_FLOAT;
2448aa84f1ad5537f5b0232eb681147cb3a3882323b8Roland Scheidegger   if (chan_type != UTIL_FORMAT_TYPE_FLOAT) {
2449aa84f1ad5537f5b0232eb681147cb3a3882323b8Roland Scheidegger      /*
2450aa84f1ad5537f5b0232eb681147cb3a3882323b8Roland Scheidegger       * clamping is a result of conversion to texture format, hence
2451aa84f1ad5537f5b0232eb681147cb3a3882323b8Roland Scheidegger       * doesn't happen with floats. Technically also should do comparison
2452aa84f1ad5537f5b0232eb681147cb3a3882323b8Roland Scheidegger       * in texture format (quantization!).
2453aa84f1ad5537f5b0232eb681147cb3a3882323b8Roland Scheidegger       */
2454c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[0] = CLAMP(pc[0], 0.0F, 1.0F);
2455c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[1] = CLAMP(pc[1], 0.0F, 1.0F);
2456c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[2] = CLAMP(pc[2], 0.0F, 1.0F);
2457c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[3] = CLAMP(pc[3], 0.0F, 1.0F);
2458aa84f1ad5537f5b0232eb681147cb3a3882323b8Roland Scheidegger   }
2459aa84f1ad5537f5b0232eb681147cb3a3882323b8Roland Scheidegger
2460efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   /* compare four texcoords vs. four texture samples */
2461efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   switch (sampler->compare_func) {
2462efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_LESS:
2463c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      k[0] = pc[0] < rgba[0][0];
2464c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      k[1] = pc[1] < rgba[0][1];
2465c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      k[2] = pc[2] < rgba[0][2];
2466c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      k[3] = pc[3] < rgba[0][3];
2467efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
2468efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_LEQUAL:
2469c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      k[0] = pc[0] <= rgba[0][0];
2470c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      k[1] = pc[1] <= rgba[0][1];
2471c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      k[2] = pc[2] <= rgba[0][2];
2472c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      k[3] = pc[3] <= rgba[0][3];
2473efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
2474efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_GREATER:
2475c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      k[0] = pc[0] > rgba[0][0];
2476c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      k[1] = pc[1] > rgba[0][1];
2477c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      k[2] = pc[2] > rgba[0][2];
2478c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      k[3] = pc[3] > rgba[0][3];
2479efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
2480efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_GEQUAL:
2481c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      k[0] = pc[0] >= rgba[0][0];
2482c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      k[1] = pc[1] >= rgba[0][1];
2483c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      k[2] = pc[2] >= rgba[0][2];
2484c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      k[3] = pc[3] >= rgba[0][3];
2485efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
2486efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_EQUAL:
2487c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      k[0] = pc[0] == rgba[0][0];
2488c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      k[1] = pc[1] == rgba[0][1];
2489c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      k[2] = pc[2] == rgba[0][2];
2490c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      k[3] = pc[3] == rgba[0][3];
2491efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
2492efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_NOTEQUAL:
2493c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      k[0] = pc[0] != rgba[0][0];
2494c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      k[1] = pc[1] != rgba[0][1];
2495c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      k[2] = pc[2] != rgba[0][2];
2496c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      k[3] = pc[3] != rgba[0][3];
2497efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
2498efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_ALWAYS:
2499c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      k[0] = k[1] = k[2] = k[3] = 1;
2500efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
2501efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   case PIPE_FUNC_NEVER:
2502c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      k[0] = k[1] = k[2] = k[3] = 0;
2503efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
2504efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   default:
2505c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      k[0] = k[1] = k[2] = k[3] = 0;
2506efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      assert(0);
2507efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul      break;
2508efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   }
2509efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul
2510c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
2511c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      rgba[0][j] = k[j];
2512c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      rgba[1][j] = k[j];
2513c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      rgba[2][j] = k[j];
2514c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      rgba[3][j] = 1.0F;
2515efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   }
2516efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul}
2517efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul
2518e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
2519e12810d92ffb3547680b227bf88937c03018112bBrian Paulstatic void
2520ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerdo_swizzling(const struct pipe_sampler_view *sview,
2521b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul             float in[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE],
2522b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul             float out[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
2523c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul{
2524e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie   int j;
2525ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const unsigned swizzle_r = sview->swizzle_r;
2526ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const unsigned swizzle_g = sview->swizzle_g;
2527ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const unsigned swizzle_b = sview->swizzle_b;
2528ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const unsigned swizzle_a = sview->swizzle_a;
2529c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul
2530c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   switch (swizzle_r) {
2531c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   case PIPE_SWIZZLE_ZERO:
2532c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2533e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[0][j] = 0.0f;
2534c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      break;
2535c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   case PIPE_SWIZZLE_ONE:
2536c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2537e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[0][j] = 1.0f;
2538c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      break;
2539c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   default:
2540c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      assert(swizzle_r < 4);
2541c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2542e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[0][j] = in[swizzle_r][j];
2543c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   }
2544c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul
2545c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   switch (swizzle_g) {
2546c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   case PIPE_SWIZZLE_ZERO:
2547c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2548e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[1][j] = 0.0f;
2549c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      break;
2550c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   case PIPE_SWIZZLE_ONE:
2551c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2552e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[1][j] = 1.0f;
2553c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      break;
2554c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   default:
2555c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      assert(swizzle_g < 4);
2556c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2557e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[1][j] = in[swizzle_g][j];
2558c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   }
2559c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul
2560c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   switch (swizzle_b) {
2561c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   case PIPE_SWIZZLE_ZERO:
2562c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2563e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[2][j] = 0.0f;
2564c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      break;
2565c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   case PIPE_SWIZZLE_ONE:
2566c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2567e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[2][j] = 1.0f;
2568c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      break;
2569c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   default:
2570c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      assert(swizzle_b < 4);
2571c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2572e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[2][j] = in[swizzle_b][j];
2573c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   }
2574c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul
2575c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   switch (swizzle_a) {
2576c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   case PIPE_SWIZZLE_ZERO:
2577c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2578e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[3][j] = 0.0f;
2579c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      break;
2580c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   case PIPE_SWIZZLE_ONE:
2581c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2582e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[3][j] = 1.0f;
2583c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      break;
2584c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   default:
2585c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      assert(swizzle_a < 4);
2586c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2587e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[3][j] = in[swizzle_a][j];
2588c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   }
2589c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul}
2590c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul
2591b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul
2592e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paulstatic wrap_nearest_func
2593e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paulget_nearest_unorm_wrap(unsigned mode)
25944fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
25954fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   switch (mode) {
25964fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP:
25974fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_unorm_clamp;
25984fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
2599b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul      return wrap_nearest_unorm_clamp_to_edge;
26004fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
26014fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_unorm_clamp_to_border;
26020dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul   default:
2603c9ae5038d564ec10a12658a2440cf49f83f1fab8Roland Scheidegger      debug_printf("illegal wrap mode %d with non-normalized coords\n", mode);
26044fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_unorm_clamp;
26050dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul   }
26060dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul}
260734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul
260834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul
2609e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paulstatic wrap_nearest_func
2610e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paulget_nearest_wrap(unsigned mode)
2611a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul{
26124fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   switch (mode) {
26134fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_REPEAT:
26144fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_repeat;
26154fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP:
26164fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_clamp;
26174fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
26184fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_clamp_to_edge;
26194fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
26204fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_clamp_to_border;
26214fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_MIRROR_REPEAT:
26224fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_mirror_repeat;
26234fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_MIRROR_CLAMP:
26244fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_mirror_clamp;
26254fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
26264fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_mirror_clamp_to_edge;
26274fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
26284fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_mirror_clamp_to_border;
26294fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   default:
26304fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      assert(0);
26314fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_repeat;
26324fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   }
2633a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul}
2634a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul
2635e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
2636e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paulstatic wrap_linear_func
2637e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paulget_linear_unorm_wrap(unsigned mode)
2638a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul{
26394fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   switch (mode) {
26404fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP:
26414fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_unorm_clamp;
26424fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
2643b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul      return wrap_linear_unorm_clamp_to_edge;
26444fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
26454fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_unorm_clamp_to_border;
26464fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   default:
2647c9ae5038d564ec10a12658a2440cf49f83f1fab8Roland Scheidegger      debug_printf("illegal wrap mode %d with non-normalized coords\n", mode);
26484fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_unorm_clamp;
26494fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   }
2650a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul}
2651a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul
2652e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
2653e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paulstatic wrap_linear_func
2654e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paulget_linear_wrap(unsigned mode)
265534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul{
26564fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   switch (mode) {
26574fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_REPEAT:
26584fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_repeat;
26594fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP:
26604fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_clamp;
26614fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
26624fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_clamp_to_edge;
26634fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
26644fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_clamp_to_border;
26654fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_MIRROR_REPEAT:
26664fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_mirror_repeat;
26674fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_MIRROR_CLAMP:
26684fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_mirror_clamp;
26694fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
26704fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_mirror_clamp_to_edge;
26714fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
26724fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_mirror_clamp_to_border;
26733d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul   default:
26743d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul      assert(0);
26754fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_repeat;
26763d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul   }
267734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul}
267834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul
2679e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
268007f5dabc01e9a85073ffd333c37549ec5ae75c7aBrian Paul/**
268107f5dabc01e9a85073ffd333c37549ec5ae75c7aBrian Paul * Is swizzling needed for the given state key?
268207f5dabc01e9a85073ffd333c37549ec5ae75c7aBrian Paul */
268307f5dabc01e9a85073ffd333c37549ec5ae75c7aBrian Paulstatic INLINE bool
2684ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerany_swizzle(const struct pipe_sampler_view *view)
268534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul{
2686ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   return (view->swizzle_r != PIPE_SWIZZLE_RED ||
2687ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger           view->swizzle_g != PIPE_SWIZZLE_GREEN ||
2688ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger           view->swizzle_b != PIPE_SWIZZLE_BLUE ||
2689ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger           view->swizzle_a != PIPE_SWIZZLE_ALPHA);
269034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul}
269134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul
2692e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
2693229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertstatic img_filter_func
2694ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerget_img_filter(const struct sp_sampler_view *sp_sview,
2695ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger               const struct pipe_sampler_state *sampler,
2696ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger               unsigned filter)
2697b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul{
2698adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   switch (sp_sview->base.target) {
2699a6256f1e678cf72a2c0cb407a2118afa92bd1b20Dave Airlie   case PIPE_BUFFER:
27004fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEXTURE_1D:
27014fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      if (filter == PIPE_TEX_FILTER_NEAREST)
27024fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         return img_filter_1d_nearest;
27034fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      else
27044fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         return img_filter_1d_linear;
2705b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul      break;
2706779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   case PIPE_TEXTURE_1D_ARRAY:
2707779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul      if (filter == PIPE_TEX_FILTER_NEAREST)
2708779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul         return img_filter_1d_array_nearest;
2709779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul      else
2710779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul         return img_filter_1d_array_linear;
2711779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul      break;
27124fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEXTURE_2D:
2713ae0ef6f69f351cacdc7eaa9b21097a7c1b414e44Luca Barbieri   case PIPE_TEXTURE_RECT:
27144fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      /* Try for fast path:
27154fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell       */
2716ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      if (sp_sview->pot2d &&
27174fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell          sampler->wrap_s == sampler->wrap_t &&
27184fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell          sampler->normalized_coords)
271938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul      {
27204fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         switch (sampler->wrap_s) {
27214fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         case PIPE_TEX_WRAP_REPEAT:
27224fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell            switch (filter) {
27236142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell            case PIPE_TEX_FILTER_NEAREST:
27244fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell               return img_filter_2d_nearest_repeat_POT;
27256142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell            case PIPE_TEX_FILTER_LINEAR:
27264fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell               return img_filter_2d_linear_repeat_POT;
27276142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell            default:
27286142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell               break;
272938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul            }
27304fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell            break;
27314fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         case PIPE_TEX_WRAP_CLAMP:
27324fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell            switch (filter) {
27336142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell            case PIPE_TEX_FILTER_NEAREST:
27344fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell               return img_filter_2d_nearest_clamp_POT;
27356142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell            default:
27366142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell               break;
273738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul            }
2738b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul         }
2739b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul      }
274060adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell      /* Otherwise use default versions:
27414fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell       */
27424fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      if (filter == PIPE_TEX_FILTER_NEAREST)
27434fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         return img_filter_2d_nearest;
27444fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      else
27454fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         return img_filter_2d_linear;
27464fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      break;
2747779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   case PIPE_TEXTURE_2D_ARRAY:
2748779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul      if (filter == PIPE_TEX_FILTER_NEAREST)
2749779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul         return img_filter_2d_array_nearest;
2750779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul      else
2751779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul         return img_filter_2d_array_linear;
2752779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul      break;
275360adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell   case PIPE_TEXTURE_CUBE:
275460adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell      if (filter == PIPE_TEX_FILTER_NEAREST)
275560adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell         return img_filter_cube_nearest;
275660adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell      else
275760adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell         return img_filter_cube_linear;
275860adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell      break;
2759309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   case PIPE_TEXTURE_CUBE_ARRAY:
2760309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie      if (filter == PIPE_TEX_FILTER_NEAREST)
2761309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie         return img_filter_cube_array_nearest;
2762309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie      else
2763309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie         return img_filter_cube_array_linear;
2764309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie      break;
27654fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEXTURE_3D:
27664fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      if (filter == PIPE_TEX_FILTER_NEAREST)
27674fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         return img_filter_3d_nearest;
27684fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      else
27694fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         return img_filter_3d_linear;
2770b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul      break;
2771b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul   default:
2772b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul      assert(0);
27734fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return img_filter_1d_nearest;
2774b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul   }
2775b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul}
2776b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul
2777b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul
2778ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerstatic void
2779ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggersample_mip(struct sp_sampler_view *sp_sview,
2780ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger           struct sp_sampler *sp_samp,
2781ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger           const float s[TGSI_QUAD_SIZE],
2782ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger           const float t[TGSI_QUAD_SIZE],
2783ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger           const float p[TGSI_QUAD_SIZE],
2784ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger           const float c0[TGSI_QUAD_SIZE],
2785ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger           const float lod[TGSI_QUAD_SIZE],
27868bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie           const struct filter_args *filt_args,
2787ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger           float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
2788ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger{
2789ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   mip_filter_func mip_filter;
2790ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   img_filter_func min_img_filter = NULL;
2791ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   img_filter_func mag_img_filter = NULL;
2792ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
2793ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   if (sp_sview->pot2d & sp_samp->min_mag_equal_repeat_linear) {
2794ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      mip_filter = mip_filter_linear_2d_linear_repeat_POT;
2795ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   }
2796ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   else {
2797ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      mip_filter = sp_samp->mip_filter;
2798ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      min_img_filter = get_img_filter(sp_sview, &sp_samp->base, sp_samp->min_img_filter);
2799ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      if (sp_samp->min_mag_equal) {
2800ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         mag_img_filter = min_img_filter;
2801ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      }
2802ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      else {
2803ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         mag_img_filter = get_img_filter(sp_sview, &sp_samp->base, sp_samp->base.mag_img_filter);
2804ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      }
2805ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   }
2806ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
2807ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   mip_filter(sp_sview, sp_samp, min_img_filter, mag_img_filter,
28088bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie              s, t, p, c0, lod, filt_args, rgba);
2809ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
2810ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   if (sp_samp->base.compare_mode != PIPE_TEX_COMPARE_NONE) {
28118bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie      sample_compare(sp_sview, sp_samp, s, t, p, c0, lod, filt_args->control, rgba);
2812ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   }
2813ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
2814ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   if (sp_sview->need_swizzle) {
2815ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      float rgba_temp[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
2816ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      memcpy(rgba_temp, rgba, sizeof(rgba_temp));
2817ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      do_swizzling(&sp_sview->base, rgba_temp, rgba);
2818ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   }
2819ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
2820ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger}
2821ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
2822ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
2823a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul/**
2824ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger * Use 3D texcoords to choose a cube face, then sample the 2D cube faces.
2825ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger * Put face info into the sampler faces[] array.
2826a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul */
2827ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerstatic void
2828ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggersample_cube(struct sp_sampler_view *sp_sview,
2829ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            struct sp_sampler *sp_samp,
2830ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            const float s[TGSI_QUAD_SIZE],
2831ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            const float t[TGSI_QUAD_SIZE],
2832ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            const float p[TGSI_QUAD_SIZE],
2833ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            const float c0[TGSI_QUAD_SIZE],
2834ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            const float c1[TGSI_QUAD_SIZE],
28358bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie            const struct filter_args *filt_args,
2836ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
283734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul{
2838ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   unsigned j;
2839ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   float ssss[4], tttt[4];
28404fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
2841ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   /* Not actually used, but the intermediate steps that do the
2842ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger    * dereferencing don't know it.
2843ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger    */
2844ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   static float pppp[4] = { 0, 0, 0, 0 };
28450b9e96fae9493d5d58f046e01c983a3c4267090eBrian Paul
2846ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   pppp[0] = c0[0];
2847ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   pppp[1] = c0[1];
2848ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   pppp[2] = c0[2];
2849ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   pppp[3] = c0[3];
2850ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   /*
2851ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger     major axis
2852ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger     direction    target                             sc     tc    ma
2853ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger     ----------   -------------------------------    ---    ---   ---
2854ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger     +rx          TEXTURE_CUBE_MAP_POSITIVE_X_EXT    -rz    -ry   rx
2855ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger     -rx          TEXTURE_CUBE_MAP_NEGATIVE_X_EXT    +rz    -ry   rx
2856ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger     +ry          TEXTURE_CUBE_MAP_POSITIVE_Y_EXT    +rx    +rz   ry
2857ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger     -ry          TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT    +rx    -rz   ry
2858ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger     +rz          TEXTURE_CUBE_MAP_POSITIVE_Z_EXT    +rx    -ry   rz
2859ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger     -rz          TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT    -rx    -ry   rz
2860ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   */
28614f23468bd0d14b8ed687a641003d587b91ad39a7Brian Paul
2862ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   /* Choose the cube face and compute new s/t coords for the 2D face.
2863ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger    *
2864ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger    * Use the same cube face for all four pixels in the quad.
2865ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger    *
2866ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger    * This isn't ideal, but if we want to use a different cube face
2867ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger    * per pixel in the quad, we'd have to also compute the per-face
2868ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger    * LOD here too.  That's because the four post-face-selection
2869ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger    * texcoords are no longer related to each other (they're
2870ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger    * per-face!)  so we can't use subtraction to compute the partial
2871ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger    * deriviates to compute the LOD.  Doing so (near cube edges
2872ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger    * anyway) gives us pretty much random values.
2873ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger    */
2874ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   {
2875ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      /* use the average of the four pixel's texcoords to choose the face */
2876ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      const float rx = 0.25F * (s[0] + s[1] + s[2] + s[3]);
2877ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      const float ry = 0.25F * (t[0] + t[1] + t[2] + t[3]);
2878ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      const float rz = 0.25F * (p[0] + p[1] + p[2] + p[3]);
2879ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz);
2880ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
2881ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      if (arx >= ary && arx >= arz) {
2882ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         float sign = (rx >= 0.0F) ? 1.0F : -1.0F;
2883ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         uint face = (rx >= 0.0F) ? PIPE_TEX_FACE_POS_X : PIPE_TEX_FACE_NEG_X;
2884ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         for (j = 0; j < TGSI_QUAD_SIZE; j++) {
2885ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            const float ima = -0.5F / fabsf(s[j]);
2886ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            ssss[j] = sign *  p[j] * ima + 0.5F;
2887ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            tttt[j] =         t[j] * ima + 0.5F;
2888ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            sp_sview->faces[j] = face;
2889ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         }
2890ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      }
2891ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      else if (ary >= arx && ary >= arz) {
2892ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         float sign = (ry >= 0.0F) ? 1.0F : -1.0F;
2893ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         uint face = (ry >= 0.0F) ? PIPE_TEX_FACE_POS_Y : PIPE_TEX_FACE_NEG_Y;
2894ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         for (j = 0; j < TGSI_QUAD_SIZE; j++) {
2895ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            const float ima = -0.5F / fabsf(t[j]);
2896ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            ssss[j] =        -s[j] * ima + 0.5F;
2897ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            tttt[j] = sign * -p[j] * ima + 0.5F;
2898ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            sp_sview->faces[j] = face;
2899ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         }
2900ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      }
2901ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      else {
2902ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         float sign = (rz >= 0.0F) ? 1.0F : -1.0F;
2903ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         uint face = (rz >= 0.0F) ? PIPE_TEX_FACE_POS_Z : PIPE_TEX_FACE_NEG_Z;
2904ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         for (j = 0; j < TGSI_QUAD_SIZE; j++) {
2905ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            const float ima = -0.5F / fabsf(p[j]);
2906ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            ssss[j] = sign * -s[j] * ima + 0.5F;
2907ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            tttt[j] =         t[j] * ima + 0.5F;
2908ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            sp_sview->faces[j] = face;
2909ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         }
2910ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      }
2911ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   }
2912ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
29138bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie   sample_mip(sp_sview, sp_samp, ssss, tttt, pppp, c0, c1, filt_args, rgba);
2914ecfa8be150ed276af816467b467e76e026f5b541Keith Whitwell}
2915ecfa8be150ed276af816467b467e76e026f5b541Keith Whitwell
2916b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul
2917461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airliestatic void
2918ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggersp_get_dims(struct sp_sampler_view *sp_sview, int level,
2919ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            int dims[4])
2920ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger{
2921ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_sampler_view *view = &sp_sview->base;
2922ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = view->texture;
2923ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
2924adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   if (view->target == PIPE_BUFFER) {
2925c45b9b572159983a20cf771016c3528a423643e1Brian Paul      dims[0] = (view->u.buf.last_element - view->u.buf.first_element) + 1;
2926c45b9b572159983a20cf771016c3528a423643e1Brian Paul      /* the other values are undefined, but let's avoid potential valgrind
2927c45b9b572159983a20cf771016c3528a423643e1Brian Paul       * warnings.
2928c45b9b572159983a20cf771016c3528a423643e1Brian Paul       */
2929c45b9b572159983a20cf771016c3528a423643e1Brian Paul      dims[1] = dims[2] = dims[3] = 0;
2930c45b9b572159983a20cf771016c3528a423643e1Brian Paul      return;
2931c45b9b572159983a20cf771016c3528a423643e1Brian Paul   }
2932c45b9b572159983a20cf771016c3528a423643e1Brian Paul
2933ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   /* undefined according to EXT_gpu_program */
2934ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   level += view->u.tex.first_level;
2935ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   if (level > view->u.tex.last_level)
2936ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return;
2937ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
2938c45b9b572159983a20cf771016c3528a423643e1Brian Paul   dims[3] = view->u.tex.last_level - view->u.tex.first_level + 1;
2939ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   dims[0] = u_minify(texture->width0, level);
2940ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
2941adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   switch (view->target) {
2942ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_1D_ARRAY:
2943ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      dims[1] = view->u.tex.last_layer - view->u.tex.first_layer + 1;
2944ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      /* fallthrough */
2945ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_1D:
2946ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return;
2947ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_2D_ARRAY:
2948ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      dims[2] = view->u.tex.last_layer - view->u.tex.first_layer + 1;
2949ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      /* fallthrough */
2950ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_2D:
2951ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_CUBE:
2952ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_RECT:
2953ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      dims[1] = u_minify(texture->height0, level);
2954ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return;
2955ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_3D:
2956ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      dims[1] = u_minify(texture->height0, level);
2957ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      dims[2] = u_minify(texture->depth0, level);
2958ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return;
2959ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_CUBE_ARRAY:
2960ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      dims[1] = u_minify(texture->height0, level);
2961ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      dims[2] = (view->u.tex.last_layer - view->u.tex.first_layer + 1) / 6;
2962ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      break;
2963ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   default:
2964ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      assert(!"unexpected texture target in sp_get_dims()");
2965ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return;
2966ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   }
2967461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie}
2968ecfa8be150ed276af816467b467e76e026f5b541Keith Whitwell
296992d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul/**
297092d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul * This function is only used for getting unfiltered texels via the
297192d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul * TXF opcode.  The GL spec says that out-of-bounds texel fetches
297292d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul * produce undefined results.  Instead of crashing, lets just clamp
297392d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul * coords to the texture image size.
297492d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul */
297562ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airliestatic void
2976ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggersp_get_texels(struct sp_sampler_view *sp_sview,
2977ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger              const int v_i[TGSI_QUAD_SIZE],
2978ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger              const int v_j[TGSI_QUAD_SIZE],
2979ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger              const int v_k[TGSI_QUAD_SIZE],
2980ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger              const int lod[TGSI_QUAD_SIZE],
2981ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger              const int8_t offset[3],
2982ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger              float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
298362ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie{
298462ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   union tex_tile_address addr;
2985ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
298662ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   int j, c;
2987e3a7cb4a6c94efe250c0212f062930e2026a861dBrian Paul   const float *tx;
2988ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   int width, height, depth;
298962ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie
299062ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   addr.value = 0;
299162ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   /* TODO write a better test for LOD */
2992adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   addr.bits.level = sp_sview->base.target == PIPE_BUFFER ? 0 :
2993adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                        CLAMP(lod[0] + sp_sview->base.u.tex.first_level,
2994adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                              sp_sview->base.u.tex.first_level,
2995adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                              sp_sview->base.u.tex.last_level);
299662ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie
299792d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul   width = u_minify(texture->width0, addr.bits.level);
299892d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul   height = u_minify(texture->height0, addr.bits.level);
299992d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul   depth = u_minify(texture->depth0, addr.bits.level);
300092d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul
3001adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   switch (sp_sview->base.target) {
3002a6256f1e678cf72a2c0cb407a2118afa92bd1b20Dave Airlie   case PIPE_BUFFER:
300362ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   case PIPE_TEXTURE_1D:
30046b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
300592d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul         int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
3006ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         tx = get_texel_2d_no_border(sp_sview, addr, x, 0);
3007ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         for (c = 0; c < 4; c++) {
3008ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            rgba[c][j] = tx[c];
3009ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         }
301062ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      }
301162ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      break;
301262ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   case PIPE_TEXTURE_1D_ARRAY:
30136b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
301492d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul         int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
3015adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger         int y = CLAMP(v_j[j], sp_sview->base.u.tex.first_layer,
3016adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                       sp_sview->base.u.tex.last_layer);
3017ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         tx = get_texel_2d_no_border(sp_sview, addr, x, y);
3018ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         for (c = 0; c < 4; c++) {
3019ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            rgba[c][j] = tx[c];
3020ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         }
302162ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      }
302262ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      break;
302362ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   case PIPE_TEXTURE_2D:
302462ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   case PIPE_TEXTURE_RECT:
30256b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
302692d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul         int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
302792d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul         int y = CLAMP(v_j[j] + offset[1], 0, height - 1);
3028ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         tx = get_texel_2d_no_border(sp_sview, addr, x, y);
3029ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         for (c = 0; c < 4; c++) {
3030ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            rgba[c][j] = tx[c];
3031ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         }
303262ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      }
303362ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      break;
303462ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   case PIPE_TEXTURE_2D_ARRAY:
30356b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
303692d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul         int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
303792d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul         int y = CLAMP(v_j[j] + offset[1], 0, height - 1);
3038adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger         int layer = CLAMP(v_k[j], sp_sview->base.u.tex.first_layer,
3039adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                           sp_sview->base.u.tex.last_layer);
3040ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         tx = get_texel_3d_no_border(sp_sview, addr, x, y, layer);
3041ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         for (c = 0; c < 4; c++) {
3042ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            rgba[c][j] = tx[c];
3043ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         }
304462ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      }
304562ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      break;
304662ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   case PIPE_TEXTURE_3D:
30476b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
304892d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul         int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
304992d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul         int y = CLAMP(v_j[j] + offset[1], 0, height - 1);
305092d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul         int z = CLAMP(v_k[j] + offset[2], 0, depth - 1);
3051ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         tx = get_texel_3d_no_border(sp_sview, addr, x, y, z);
3052ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         for (c = 0; c < 4; c++) {
3053ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            rgba[c][j] = tx[c];
3054ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         }
305562ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      }
305662ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      break;
305762ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   case PIPE_TEXTURE_CUBE: /* TXF can't work on CUBE according to spec */
305862ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   default:
305962ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      assert(!"Unknown or CUBE texture type in TXF processing\n");
306062ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      break;
306162ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   }
3062e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie
3063ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   if (sp_sview->need_swizzle) {
30646b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard      float rgba_temp[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
3065e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie      memcpy(rgba_temp, rgba, sizeof(rgba_temp));
3066ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      do_swizzling(&sp_sview->base, rgba_temp, rgba);
3067e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie   }
306862ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie}
3069b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul
3070b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul
3071ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggervoid *
3072ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggersoftpipe_create_sampler_state(struct pipe_context *pipe,
3073ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                              const struct pipe_sampler_state *sampler)
30744fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
3075ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   struct sp_sampler *samp = CALLOC_STRUCT(sp_sampler);
30764fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
3077ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   samp->base = *sampler;
30784fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
30794fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* Note that (for instance) linear_texcoord_s and
30804fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell    * nearest_texcoord_s may be active at the same time, if the
30814fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell    * sampler min_img_filter differs from its mag_img_filter.
30824fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell    */
30834fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   if (sampler->normalized_coords) {
30844fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->linear_texcoord_s = get_linear_wrap( sampler->wrap_s );
30854fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->linear_texcoord_t = get_linear_wrap( sampler->wrap_t );
30864fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->linear_texcoord_p = get_linear_wrap( sampler->wrap_r );
3087ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
30884fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->nearest_texcoord_s = get_nearest_wrap( sampler->wrap_s );
30894fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->nearest_texcoord_t = get_nearest_wrap( sampler->wrap_t );
30904fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->nearest_texcoord_p = get_nearest_wrap( sampler->wrap_r );
30914fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   }
30924fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   else {
30934fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->linear_texcoord_s = get_linear_unorm_wrap( sampler->wrap_s );
30944fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->linear_texcoord_t = get_linear_unorm_wrap( sampler->wrap_t );
30954fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->linear_texcoord_p = get_linear_unorm_wrap( sampler->wrap_r );
3096ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
30974fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->nearest_texcoord_s = get_nearest_unorm_wrap( sampler->wrap_s );
30984fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->nearest_texcoord_t = get_nearest_unorm_wrap( sampler->wrap_t );
30994fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->nearest_texcoord_p = get_nearest_unorm_wrap( sampler->wrap_r );
31004fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   }
31014fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
3102ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   samp->min_img_filter = sampler->min_img_filter;
31034fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
31044fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   switch (sampler->min_mip_filter) {
31054fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_MIPFILTER_NONE:
3106ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      if (sampler->min_img_filter == sampler->mag_img_filter)
3107229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         samp->mip_filter = mip_filter_none_no_filter_select;
3108b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul      else
31094fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         samp->mip_filter = mip_filter_none;
311034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul      break;
31114fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
31124fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_MIPFILTER_NEAREST:
31134fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->mip_filter = mip_filter_nearest;
311434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul      break;
31154fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
31164fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_MIPFILTER_LINEAR:
3117ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      if (sampler->min_img_filter == sampler->mag_img_filter &&
31184fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell          sampler->normalized_coords &&
31194fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell          sampler->wrap_s == PIPE_TEX_WRAP_REPEAT &&
3120cf102b031e7ef33c8e3ffce2f9dcd064f44e8190Brian Paul          sampler->wrap_t == PIPE_TEX_WRAP_REPEAT &&
3121ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger          sampler->min_img_filter == PIPE_TEX_FILTER_LINEAR &&
3122ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger          sampler->max_anisotropy <= 1) {
3123ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         samp->min_mag_equal_repeat_linear = TRUE;
31246142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      }
3125ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      samp->mip_filter = mip_filter_linear;
3126ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3127f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      /* Anisotropic filtering extension. */
3128f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      if (sampler->max_anisotropy > 1) {
3129ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         samp->mip_filter = mip_filter_linear_aniso;
3130ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3131ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         /* Override min_img_filter:
3132ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger          * min_img_filter needs to be set to NEAREST since we need to access
3133ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger          * each texture pixel as it is and weight it later; using linear
3134ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger          * filters will have incorrect results.
3135ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger          * By setting the filter to NEAREST here, we can avoid calling the
3136ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger          * generic img_filter_2d_nearest in the anisotropic filter function,
3137ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger          * making it possible to use one of the accelerated implementations
3138ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger          */
3139ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         samp->min_img_filter = PIPE_TEX_FILTER_NEAREST;
3140ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3141ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         /* on first access create the lookup table containing the filter weights. */
3142f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger        if (!weightLut) {
3143f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger           create_filter_table();
3144f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger        }
3145f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      }
314634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul      break;
314734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul   }
3148ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   if (samp->min_img_filter == sampler->mag_img_filter) {
3149ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      samp->min_mag_equal = TRUE;
31504fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   }
31514fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
3152ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   return (void *)samp;
3153ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger}
3154c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul
3155ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3156ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggercompute_lambda_func
3157ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggersoftpipe_get_lambda_func(const struct pipe_sampler_view *view, unsigned shader)
3158ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger{
3159ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   if (shader != PIPE_SHADER_FRAGMENT)
3160ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return compute_lambda_vert;
3161ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3162adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   switch (view->target) {
3163ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_BUFFER:
3164ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_1D:
3165ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_1D_ARRAY:
3166ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return compute_lambda_1d;
3167ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_2D:
3168ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_2D_ARRAY:
3169ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_RECT:
3170ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_CUBE:
3171ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_CUBE_ARRAY:
3172ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return compute_lambda_2d;
3173ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_3D:
3174ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return compute_lambda_3d;
3175ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   default:
3176ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      assert(0);
3177ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return compute_lambda_1d;
3178c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   }
3179ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger}
3180ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3181ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3182ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerstruct pipe_sampler_view *
3183ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggersoftpipe_create_sampler_view(struct pipe_context *pipe,
3184ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                             struct pipe_resource *resource,
3185ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                             const struct pipe_sampler_view *templ)
3186ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger{
3187ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   struct sp_sampler_view *sview = CALLOC_STRUCT(sp_sampler_view);
3188ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   struct softpipe_resource *spr = (struct softpipe_resource *)resource;
3189ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3190ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   if (sview) {
3191ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      struct pipe_sampler_view *view = &sview->base;
3192ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      *view = *templ;
3193ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      view->reference.count = 1;
3194ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      view->texture = NULL;
3195ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      pipe_resource_reference(&view->texture, resource);
3196ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      view->context = pipe;
3197ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3198adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger#ifdef DEBUG
3199adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger     /*
3200adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      * This is possibly too lenient, but the primary reason is just
3201adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      * to catch state trackers which forget to initialize this, so
3202adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      * it only catches clearly impossible view targets.
3203adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      */
3204adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      if (view->target != resource->target) {
3205adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger         if (view->target == PIPE_TEXTURE_1D)
3206adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger            assert(resource->target == PIPE_TEXTURE_1D_ARRAY);
3207adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger         else if (view->target == PIPE_TEXTURE_1D_ARRAY)
3208adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger            assert(resource->target == PIPE_TEXTURE_1D);
3209adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger         else if (view->target == PIPE_TEXTURE_2D)
3210adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger            assert(resource->target == PIPE_TEXTURE_2D_ARRAY ||
3211adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                   resource->target == PIPE_TEXTURE_CUBE ||
3212adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                   resource->target == PIPE_TEXTURE_CUBE_ARRAY);
3213adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger         else if (view->target == PIPE_TEXTURE_2D_ARRAY)
3214adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger            assert(resource->target == PIPE_TEXTURE_2D ||
3215adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                   resource->target == PIPE_TEXTURE_CUBE ||
3216adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                   resource->target == PIPE_TEXTURE_CUBE_ARRAY);
3217adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger         else if (view->target == PIPE_TEXTURE_CUBE)
3218adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger            assert(resource->target == PIPE_TEXTURE_CUBE_ARRAY ||
3219adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                   resource->target == PIPE_TEXTURE_2D_ARRAY);
3220adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger         else if (view->target == PIPE_TEXTURE_CUBE_ARRAY)
3221adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger            assert(resource->target == PIPE_TEXTURE_CUBE ||
3222adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                   resource->target == PIPE_TEXTURE_2D_ARRAY);
3223adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger         else
3224adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger            assert(0);
3225adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      }
3226adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger#endif
3227adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger
3228ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      if (any_swizzle(view)) {
3229ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         sview->need_swizzle = TRUE;
3230ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      }
3231ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3232adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      if (view->target == PIPE_TEXTURE_CUBE ||
3233adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger          view->target == PIPE_TEXTURE_CUBE_ARRAY)
3234ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         sview->get_samples = sample_cube;
3235ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      else {
3236ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         sview->get_samples = sample_mip;
3237ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      }
3238ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      sview->pot2d = spr->pot &&
3239adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                     (view->target == PIPE_TEXTURE_2D ||
3240adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                      view->target == PIPE_TEXTURE_RECT);
3241ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3242ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      sview->xpot = util_logbase2( resource->width0 );
3243ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      sview->ypot = util_logbase2( resource->height0 );
32446142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   }
32456142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
3246ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   return (struct pipe_sampler_view *) sview;
324734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul}
32486b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger
32496b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger
32506b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheideggerstatic void
32516b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheideggersp_tgsi_get_dims(struct tgsi_sampler *tgsi_sampler,
32526b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                 const unsigned sview_index,
32536b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                 int level, int dims[4])
32546b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger{
3255ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   struct sp_tgsi_sampler *sp_samp = (struct sp_tgsi_sampler *)tgsi_sampler;
32566b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger
3257ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   assert(sview_index < PIPE_MAX_SHADER_SAMPLER_VIEWS);
3258bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger   /* always have a view here but texture is NULL if no sampler view was set. */
3259bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger   if (!sp_samp->sp_sview[sview_index].base.texture) {
3260bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger      dims[0] = dims[1] = dims[2] = dims[3] = 0;
3261bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger      return;
3262bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger   }
3263ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   sp_get_dims(&sp_samp->sp_sview[sview_index], level, dims);
32646b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger}
32656b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger
32666b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger
32676b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheideggerstatic void
32686b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheideggersp_tgsi_get_samples(struct tgsi_sampler *tgsi_sampler,
32696b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                    const unsigned sview_index,
32706b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                    const unsigned sampler_index,
32716b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                    const float s[TGSI_QUAD_SIZE],
32726b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                    const float t[TGSI_QUAD_SIZE],
32736b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                    const float p[TGSI_QUAD_SIZE],
32746b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                    const float c0[TGSI_QUAD_SIZE],
32756b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                    const float lod[TGSI_QUAD_SIZE],
32766ace2e41da7dded630d932d03bacb7e14a93d47aRoland Scheidegger                    float derivs[3][2][TGSI_QUAD_SIZE],
32776ace2e41da7dded630d932d03bacb7e14a93d47aRoland Scheidegger                    const int8_t offset[3],
32786b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                    enum tgsi_sampler_control control,
32796b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                    float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
32806b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger{
3281ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   struct sp_tgsi_sampler *sp_samp = (struct sp_tgsi_sampler *)tgsi_sampler;
32828bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie   struct filter_args filt_args;
3283ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   assert(sview_index < PIPE_MAX_SHADER_SAMPLER_VIEWS);
3284ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   assert(sampler_index < PIPE_MAX_SAMPLERS);
32856b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger   assert(sp_samp->sp_sampler[sampler_index]);
3286bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger   /* always have a view here but texture is NULL if no sampler view was set. */
3287bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger   if (!sp_samp->sp_sview[sview_index].base.texture) {
3288bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger      int i, j;
3289bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger      for (j = 0; j < TGSI_NUM_CHANNELS; j++) {
3290bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger         for (i = 0; i < TGSI_QUAD_SIZE; i++) {
3291bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger            rgba[j][i] = 0.0f;
3292bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger         }
3293bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger      }
3294bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger      return;
3295bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger   }
32968bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie
32978bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie   filt_args.control = control;
32983f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   filt_args.offset = offset;
3299ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   sp_samp->sp_sview[sview_index].get_samples(&sp_samp->sp_sview[sview_index],
3300ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                                              sp_samp->sp_sampler[sampler_index],
33018bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie                                              s, t, p, c0, lod, &filt_args, rgba);
33026b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger}
33036b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger
33046b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger
33056b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheideggerstatic void
33066b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheideggersp_tgsi_get_texel(struct tgsi_sampler *tgsi_sampler,
33076b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                  const unsigned sview_index,
33086b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                  const int i[TGSI_QUAD_SIZE],
33096b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                  const int j[TGSI_QUAD_SIZE], const int k[TGSI_QUAD_SIZE],
33106b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                  const int lod[TGSI_QUAD_SIZE], const int8_t offset[3],
33116b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                  float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
33126b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger{
3313ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   struct sp_tgsi_sampler *sp_samp = (struct sp_tgsi_sampler *)tgsi_sampler;
3314ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3315ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   assert(sview_index < PIPE_MAX_SHADER_SAMPLER_VIEWS);
3316bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger   /* always have a view here but texture is NULL if no sampler view was set. */
3317bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger   if (!sp_samp->sp_sview[sview_index].base.texture) {
3318bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger      int i, j;
3319bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger      for (j = 0; j < TGSI_NUM_CHANNELS; j++) {
3320bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger         for (i = 0; i < TGSI_QUAD_SIZE; i++) {
3321bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger            rgba[j][i] = 0.0f;
3322bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger         }
3323bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger      }
3324bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger      return;
3325bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger   }
3326ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   sp_get_texels(&sp_samp->sp_sview[sview_index], i, j, k, lod, offset, rgba);
33276b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger}
33286b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger
33296b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger
33306b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheideggerstruct sp_tgsi_sampler *
33316b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheideggersp_create_tgsi_sampler(void)
33326b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger{
33336b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger   struct sp_tgsi_sampler *samp = CALLOC_STRUCT(sp_tgsi_sampler);
33346b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger   if (!samp)
33356b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger      return NULL;
33366b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger
33376b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger   samp->base.get_dims = sp_tgsi_get_dims;
33386b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger   samp->base.get_samples = sp_tgsi_get_samples;
33396b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger   samp->base.get_texel = sp_tgsi_get_texel;
33406b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger
33416b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger   return samp;
33426b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger}
33436b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger
3344