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 */
61a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic 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 */
72a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic 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 */
87a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic 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 */
100a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic 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 */
118a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic 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] */
1382135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const 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] */
148065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   s *= size;
149065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   s += offset;
150229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (s <= 0.0F)
151229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = 0;
152065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   else if (s >= size)
153229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = size - 1;
154229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else
155065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie      *icoord = util_ifloor(s);
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] */
164065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   const float min = 0.5F;
165065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   const float max = (float)size - 0.5F;
166065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie
167065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   s *= size;
168065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   s += offset;
1693f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie
170229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (s < min)
171229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = 0;
172229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else if (s > max)
173229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = size - 1;
174229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else
175065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie      *icoord = util_ifloor(s);
1764fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
1774fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1784fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1794fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
1803f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_nearest_clamp_to_border(float s, unsigned size, int offset, int *icoord)
1814fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
1824fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* s limited to [min,max] */
1834fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* i limited to [-1, size] */
184065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   const float min = -0.5F;
185065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   const float max = size + 0.5F;
186065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie
187065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   s *= size;
188065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   s += offset;
189229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (s <= min)
190229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = -1;
191229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else if (s >= max)
192229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = size;
193229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else
194065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie      *icoord = util_ifloor(s);
1954fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
1964fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1974fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
1983f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_nearest_mirror_repeat(float s, unsigned size, int offset, int *icoord)
1994fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
2004fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float min = 1.0F / (2.0F * size);
2014fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   const float max = 1.0F - min;
202065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   int flr;
203065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   float u;
204065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie
205065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   s += (float)offset / size;
206065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   flr = util_ifloor(s);
207065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   u = frac(s);
208229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (flr & 1)
209229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      u = 1.0F - u;
210229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (u < min)
211229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = 0;
212229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else if (u > max)
213229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = size - 1;
214229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else
215229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = util_ifloor(u * size);
2164fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
2174fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
218e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
2194fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
2203f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_nearest_mirror_clamp(float s, unsigned size, int offset, int *icoord)
221229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
222229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   /* s limited to [0,1] */
223229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   /* i limited to [0,size-1] */
224065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   const float u = fabsf(s * size + offset);
225229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (u <= 0.0F)
226229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = 0;
227065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   else if (u >= size)
228229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = size - 1;
229229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else
230065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie      *icoord = util_ifloor(u);
2314fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
2324fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
233e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
2344fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
2353f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_nearest_mirror_clamp_to_edge(float s, unsigned size, int offset, int *icoord)
2364fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
2374fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* s limited to [min,max] */
2384fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* i limited to [0, size-1] */
239065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   const float min = 0.5F;
240065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   const float max = (float)size - 0.5F;
241065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   const float u = fabsf(s * size + offset);
242065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie
243229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (u < min)
244229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = 0;
245229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else if (u > max)
246229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = size - 1;
247229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else
248065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie      *icoord = util_ifloor(u);
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{
255065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   /* u limited to [-0.5, size-0.5] */
256065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   const float min = -0.5F;
257065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   const float max = (float)size + 0.5F;
258065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   const float u = fabsf(s * size + offset);
259065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie
260229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (u < min)
261229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = -1;
262229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else if (u > max)
263229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord = size;
264229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else
265065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie      *icoord = util_ifloor(u);
2660dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul}
2670dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul
26808f33a025100dea2d951e6d628891fe294b18082Brian Paul
26908f33a025100dea2d951e6d628891fe294b18082Brian Paul/**
270229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert * Used to compute texel locations for linear sampling
27108f33a025100dea2d951e6d628891fe294b18082Brian Paul * \param wrapMode  PIPE_TEX_WRAP_x
272229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert * \param s  the texcoord
27308f33a025100dea2d951e6d628891fe294b18082Brian Paul * \param size  the texture image size
274229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert * \param icoord0  returns first texture index
275229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert * \param icoord1  returns second texture index (usually icoord0 + 1)
276229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert * \param w  returns blend factor/weight between texture indices
277229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert * \param icoord  returns the computed integer texture coord
27808f33a025100dea2d951e6d628891fe294b18082Brian Paul */
2794fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
2803f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_linear_repeat(float s, unsigned size, int offset,
281229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                   int *icoord0, int *icoord1, float *w)
282229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
2832135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float u = s * size - 0.5F;
2843f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   *icoord0 = repeat(util_ifloor(u) + offset, size);
285229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = repeat(*icoord0 + 1, size);
286229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
2874fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
2884fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
289e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
2904fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
2913f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_linear_clamp(float s, unsigned size, int offset,
292229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                  int *icoord0, int *icoord1, float *w)
293229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
2942135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float u = CLAMP(s * size + offset, 0.0F, (float)size) - 0.5f;
295065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie
296229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
297229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
298229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
2994fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
30038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul
301e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
3024fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
3033f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_linear_clamp_to_edge(float s, unsigned size, int offset,
304229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                          int *icoord0, int *icoord1, float *w)
305229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
3062135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float u = CLAMP(s * size + offset, 0.0F, (float)size) - 0.5f;
307229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
308229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
309229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (*icoord0 < 0)
310229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord0 = 0;
311229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (*icoord1 >= (int) size)
312229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord1 = size - 1;
313229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
3144fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
3154fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
316e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
3174fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
3183f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_linear_clamp_to_border(float s, unsigned size, int offset,
319229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                            int *icoord0, int *icoord1, float *w)
3204fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
321065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   const float min = -0.5F;
322065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   const float max = (float)size + 0.5F;
3232135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float u = CLAMP(s * size + offset, min, max) - 0.5f;
324229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
325229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
326229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
3274fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
3284fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
3294fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
3304fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
3313f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_linear_mirror_repeat(float s, unsigned size, int offset,
332229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                          int *icoord0, int *icoord1, float *w)
333229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
334065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   int flr;
335065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   float u;
336065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie
337065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   s += (float)offset / size;
338065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   flr = util_ifloor(s);
339065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   u = frac(s);
340229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (flr & 1)
341229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      u = 1.0F - u;
342229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   u = u * size - 0.5F;
343229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
344229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
345229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (*icoord0 < 0)
346229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord0 = 0;
347229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (*icoord1 >= (int) size)
348229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord1 = size - 1;
349229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
3504fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
3514fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
352e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
3534fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
3543f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_linear_mirror_clamp(float s, unsigned size, int offset,
355229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                         int *icoord0, int *icoord1, float *w)
356229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
357065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   float u = fabsf(s * size + offset);
358065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   if (u >= size)
359229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      u = (float) size;
360229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   u -= 0.5F;
361229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
362229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
363229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
3644fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
3654fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
366e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
3674fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
3683f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_linear_mirror_clamp_to_edge(float s, unsigned size, int offset,
369229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                 int *icoord0, int *icoord1, float *w)
370229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
371065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   float u = fabsf(s * size + offset);
372065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   if (u >= size)
373229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      u = (float) size;
374229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   u -= 0.5F;
375229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
376229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
377229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (*icoord0 < 0)
378229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord0 = 0;
379229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (*icoord1 >= (int) size)
380229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord1 = size - 1;
381229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
3824fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
3834fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
384e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
3854fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
3863f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_linear_mirror_clamp_to_border(float s, unsigned size, int offset,
387229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                   int *icoord0, int *icoord1, float *w)
3884fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
389065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   const float min = -0.5F;
390065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie   const float max = size + 0.5F;
3912135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float t = fabsf(s * size + offset);
3922135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float u = CLAMP(t, min, max) - 0.5F;
393229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
394229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
395229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
3960dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul}
3970dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul
3980dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul
399b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul/**
400b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul * PIPE_TEX_WRAP_CLAMP for nearest sampling, unnormalized coords.
401b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul */
4024fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
4033f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_nearest_unorm_clamp(float s, unsigned size, int offset, int *icoord)
404b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul{
4052135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int i = util_ifloor(s);
4063f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   *icoord = CLAMP(i + offset, 0, (int) size-1);
4074fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
4084fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
409e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
410e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul/**
411b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul * PIPE_TEX_WRAP_CLAMP_TO_BORDER for nearest sampling, unnormalized coords.
4124fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell */
4134fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
4143f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_nearest_unorm_clamp_to_border(float s, unsigned size, int offset, int *icoord)
4154fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
4163f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   *icoord = util_ifloor( CLAMP(s + offset, -0.5F, (float) size + 0.5F) );
417b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul}
418b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul
419b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul
420b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul/**
421b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul * PIPE_TEX_WRAP_CLAMP_TO_EDGE for nearest sampling, unnormalized coords.
422b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul */
423b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paulstatic void
4243f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_nearest_unorm_clamp_to_edge(float s, unsigned size, int offset, int *icoord)
425b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul{
4263f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   *icoord = util_ifloor( CLAMP(s + offset, 0.5F, (float) size - 0.5F) );
427b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul}
428b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul
429b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul
430b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul/**
431b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul * PIPE_TEX_WRAP_CLAMP for linear sampling, unnormalized coords.
432b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul */
4334fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
4343f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_linear_unorm_clamp(float s, unsigned size, int offset,
435229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                        int *icoord0, int *icoord1, float *w)
436229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
437229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   /* Not exactly what the spec says, but it matches NVIDIA output */
4382135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float u = CLAMP(s + offset - 0.5F, 0.0f, (float) size - 1.0f);
439229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
440229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
441229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
442b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul}
443b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul
444e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
445b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul/**
446b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul * PIPE_TEX_WRAP_CLAMP_TO_BORDER for linear sampling, unnormalized coords.
447b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul */
4484fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
4493f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_linear_unorm_clamp_to_border(float s, unsigned size, int offset,
450229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                  int *icoord0, int *icoord1, float *w)
451229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
4522135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float u = CLAMP(s + offset, -0.5F, (float) size + 0.5F) - 0.5F;
453229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
454229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
455229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (*icoord1 > (int) size - 1)
456229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord1 = size - 1;
457229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
458b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul}
459b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul
460b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul
461b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul/**
462b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul * PIPE_TEX_WRAP_CLAMP_TO_EDGE for linear sampling, unnormalized coords.
463b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul */
464b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paulstatic void
4653f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airliewrap_linear_unorm_clamp_to_edge(float s, unsigned size, int offset,
466229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                int *icoord0, int *icoord1, float *w)
467229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
4682135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float u = CLAMP(s + offset, +0.5F, (float) size - 0.5F) - 0.5F;
469229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord0 = util_ifloor(u);
470229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *icoord1 = *icoord0 + 1;
471229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (*icoord1 > (int) size - 1)
472229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      *icoord1 = size - 1;
473229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   *w = frac(u);
4744fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
4754fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
47634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul
477779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul/**
478779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul * Do coordinate to array index conversion.  For array textures.
479779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul */
480a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline int
481adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheideggercoord_to_layer(float coord, unsigned first_layer, unsigned last_layer)
482779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul{
4832135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int c = util_ifloor(coord + 0.5F);
484adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   return CLAMP(c, (int)first_layer, (int)last_layer);
485779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul}
486779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
48734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul
488b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul/**
489b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul * Examine the quad's texture coordinates to compute the partial
490b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul * derivatives w.r.t X and Y, then compute lambda (level of detail).
491b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul */
492b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paulstatic float
493ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggercompute_lambda_1d(const struct sp_sampler_view *sview,
4946b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float s[TGSI_QUAD_SIZE],
4956b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float t[TGSI_QUAD_SIZE],
4966b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float p[TGSI_QUAD_SIZE])
497b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul{
498ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sview->base.texture;
4992135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]);
5002135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float dsdy = fabsf(s[QUAD_TOP_LEFT]     - s[QUAD_BOTTOM_LEFT]);
5012135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float rho = MAX2(dsdx, dsdy) * u_minify(texture->width0, sview->base.u.tex.first_level);
502b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul
5034bfe1c955fe679547c8a03119d1681e33593c768Michal Krol   return util_fast_log2(rho);
504b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul}
505b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul
506e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
5074fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic float
508ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggercompute_lambda_2d(const struct sp_sampler_view *sview,
5096b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float s[TGSI_QUAD_SIZE],
5106b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float t[TGSI_QUAD_SIZE],
5116b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float p[TGSI_QUAD_SIZE])
51209a1b912605ff48c8782dcc5aae55ac77e27037bBrian Paul{
513ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sview->base.texture;
5142135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]);
5152135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float dsdy = fabsf(s[QUAD_TOP_LEFT]     - s[QUAD_BOTTOM_LEFT]);
5162135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float dtdx = fabsf(t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]);
5172135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float dtdy = fabsf(t[QUAD_TOP_LEFT]     - t[QUAD_BOTTOM_LEFT]);
5182135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float maxx = MAX2(dsdx, dsdy) * u_minify(texture->width0, sview->base.u.tex.first_level);
5192135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float maxy = MAX2(dtdx, dtdy) * u_minify(texture->height0, sview->base.u.tex.first_level);
5202135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float rho  = MAX2(maxx, maxy);
521c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul
5224bfe1c955fe679547c8a03119d1681e33593c768Michal Krol   return util_fast_log2(rho);
52309a1b912605ff48c8782dcc5aae55ac77e27037bBrian Paul}
52409a1b912605ff48c8782dcc5aae55ac77e27037bBrian Paul
52508f33a025100dea2d951e6d628891fe294b18082Brian Paul
5264fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic float
527ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggercompute_lambda_3d(const struct sp_sampler_view *sview,
5286b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float s[TGSI_QUAD_SIZE],
5296b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float t[TGSI_QUAD_SIZE],
5306b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float p[TGSI_QUAD_SIZE])
53109a1b912605ff48c8782dcc5aae55ac77e27037bBrian Paul{
532ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sview->base.texture;
5332135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]);
5342135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float dsdy = fabsf(s[QUAD_TOP_LEFT]     - s[QUAD_BOTTOM_LEFT]);
5352135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float dtdx = fabsf(t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]);
5362135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float dtdy = fabsf(t[QUAD_TOP_LEFT]     - t[QUAD_BOTTOM_LEFT]);
5372135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float dpdx = fabsf(p[QUAD_BOTTOM_RIGHT] - p[QUAD_BOTTOM_LEFT]);
5382135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float dpdy = fabsf(p[QUAD_TOP_LEFT]     - p[QUAD_BOTTOM_LEFT]);
5392135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float maxx = MAX2(dsdx, dsdy) * u_minify(texture->width0, sview->base.u.tex.first_level);
5402135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float maxy = MAX2(dtdx, dtdy) * u_minify(texture->height0, sview->base.u.tex.first_level);
5412135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float maxz = MAX2(dpdx, dpdy) * u_minify(texture->depth0, sview->base.u.tex.first_level);
5422135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float rho = MAX3(maxx, maxy, maxz);
543c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul
5444bfe1c955fe679547c8a03119d1681e33593c768Michal Krol   return util_fast_log2(rho);
54509a1b912605ff48c8782dcc5aae55ac77e27037bBrian Paul}
54609a1b912605ff48c8782dcc5aae55ac77e27037bBrian Paul
54708f33a025100dea2d951e6d628891fe294b18082Brian Paul
548e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul/**
549e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul * Compute lambda for a vertex texture sampler.
5504bfe1c955fe679547c8a03119d1681e33593c768Michal Krol * Since there aren't derivatives to use, just return 0.
551e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul */
5524fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic float
553ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggercompute_lambda_vert(const struct sp_sampler_view *sview,
5546b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                    const float s[TGSI_QUAD_SIZE],
5556b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                    const float t[TGSI_QUAD_SIZE],
5566b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                    const float p[TGSI_QUAD_SIZE])
5574fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
5584bfe1c955fe679547c8a03119d1681e33593c768Michal Krol   return 0.0f;
5594fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
5604fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
5614fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
5624fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
5634fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell/**
5644fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell * Get a texel from a texture, using the texture tile cache.
5654fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell *
56681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell * \param addr  the template tex address containing cube, z, face info.
5674fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell * \param x  the x coord of texel within 2D image
568b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul * \param y  the y coord of texel within 2D image
569b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul * \param rgba  the quad to put the texel/color into
57070eb7996f265f3634dabda078f13d1be3533cc65Brian Paul *
57180c78472ad43f4288c9ef5076074ba9d31a39885Keith Whitwell * XXX maybe move this into sp_tex_tile_cache.c and merge with the
572229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert * sp_get_cached_tile_tex() function.
573b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul */
57481601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
57581601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
57681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
57781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
578a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline const float *
579ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerget_texel_2d_no_border(const struct sp_sampler_view *sp_sview,
580ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                       union tex_tile_address addr, int x, int y)
581b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul{
58281601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   const struct softpipe_tex_cached_tile *tile;
5832f567fb7b50e39aef20f0a0cd9b2eba184ed6441Roland Scheidegger   addr.bits.x = x / TEX_TILE_SIZE;
5842f567fb7b50e39aef20f0a0cd9b2eba184ed6441Roland Scheidegger   addr.bits.y = y / TEX_TILE_SIZE;
5852f567fb7b50e39aef20f0a0cd9b2eba184ed6441Roland Scheidegger   y %= TEX_TILE_SIZE;
5862f567fb7b50e39aef20f0a0cd9b2eba184ed6441Roland Scheidegger   x %= TEX_TILE_SIZE;
58781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
588ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tile = sp_get_cached_tile_tex(sp_sview->cache, addr);
58981601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
59081601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   return &tile->data.color[y][x][0];
59181601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell}
59281601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
59381601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
594a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline const float *
595ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerget_texel_2d(const struct sp_sampler_view *sp_sview,
596ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger             const struct sp_sampler *sp_samp,
597ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger             union tex_tile_address addr, int x, int y)
59881601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell{
599ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
6002135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const unsigned level = addr.bits.level;
60181601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
602683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell   if (x < 0 || x >= (int) u_minify(texture->width0, level) ||
603683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell       y < 0 || y >= (int) u_minify(texture->height0, level)) {
604ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return sp_samp->base.border_color.f;
60581601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   }
60681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   else {
607ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return get_texel_2d_no_border( sp_sview, addr, x, y );
60881601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   }
60981601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell}
6106142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
6117681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger
6127681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger/*
6137681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * Here's the complete logic (HOLY CRAP) for finding next face and doing the
6147681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * corresponding coord wrapping, implemented by get_next_face,
6157681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * get_next_xcoord, get_next_ycoord.
6167681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * Read like that (first line):
6177681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * If face is +x and s coord is below zero, then
6187681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * new face is +z, new s is max , new t is old t
6197681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * (max is always cube size - 1).
6207681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger *
6217681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * +x s- -> +z: s = max,   t = t
6227681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * +x s+ -> -z: s = 0,     t = t
6237681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * +x t- -> +y: s = max,   t = max-s
6247681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * +x t+ -> -y: s = max,   t = s
6257681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger *
6267681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * -x s- -> -z: s = max,   t = t
6277681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * -x s+ -> +z: s = 0,     t = t
6287681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * -x t- -> +y: s = 0,     t = s
6297681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * -x t+ -> -y: s = 0,     t = max-s
6307681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger *
6317681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * +y s- -> -x: s = t,     t = 0
6327681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * +y s+ -> +x: s = max-t, t = 0
6337681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * +y t- -> -z: s = max-s, t = 0
6347681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * +y t+ -> +z: s = s,     t = 0
6357681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger *
6367681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * -y s- -> -x: s = max-t, t = max
6377681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * -y s+ -> +x: s = t,     t = max
6387681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * -y t- -> +z: s = s,     t = max
6397681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * -y t+ -> -z: s = max-s, t = max
6407681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger
6417681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * +z s- -> -x: s = max,   t = t
6427681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * +z s+ -> +x: s = 0,     t = t
6437681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * +z t- -> +y: s = s,     t = max
6447681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * +z t+ -> -y: s = s,     t = 0
6457681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger
6467681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * -z s- -> +x: s = max,   t = t
6477681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * -z s+ -> -x: s = 0,     t = t
6487681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * -z t- -> +y: s = max-s, t = 0
6497681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * -z t+ -> -y: s = max-s, t = max
6507681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger */
6517681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger
6527681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger
653621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie/*
654621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie * seamless cubemap neighbour array.
655621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie * this array is used to find the adjacent face in each of 4 directions,
656621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie * left, right, up, down. (or -x, +x, -y, +y).
657621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie */
658621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airliestatic const unsigned face_array[PIPE_TEX_FACE_MAX][4] = {
659621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   /* pos X first then neg X is Z different, Y the same */
660621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   /* PIPE_TEX_FACE_POS_X,*/
661621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   { PIPE_TEX_FACE_POS_Z, PIPE_TEX_FACE_NEG_Z,
6627681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger     PIPE_TEX_FACE_POS_Y, PIPE_TEX_FACE_NEG_Y },
663621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   /* PIPE_TEX_FACE_NEG_X */
664621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   { PIPE_TEX_FACE_NEG_Z, PIPE_TEX_FACE_POS_Z,
6657681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger     PIPE_TEX_FACE_POS_Y, PIPE_TEX_FACE_NEG_Y },
666621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie
667621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   /* pos Y first then neg Y is X different, X the same */
668621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   /* PIPE_TEX_FACE_POS_Y */
669621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   { PIPE_TEX_FACE_NEG_X, PIPE_TEX_FACE_POS_X,
6707681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger     PIPE_TEX_FACE_NEG_Z, PIPE_TEX_FACE_POS_Z },
671621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie
672621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   /* PIPE_TEX_FACE_NEG_Y */
673621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   { PIPE_TEX_FACE_NEG_X, PIPE_TEX_FACE_POS_X,
6747681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger     PIPE_TEX_FACE_POS_Z, PIPE_TEX_FACE_NEG_Z },
675621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie
676621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   /* pos Z first then neg Y is X different, X the same */
677621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   /* PIPE_TEX_FACE_POS_Z */
678621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   { PIPE_TEX_FACE_NEG_X, PIPE_TEX_FACE_POS_X,
6797681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger     PIPE_TEX_FACE_POS_Y, PIPE_TEX_FACE_NEG_Y },
680621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie
681621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   /* PIPE_TEX_FACE_NEG_Z */
682621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   { PIPE_TEX_FACE_POS_X, PIPE_TEX_FACE_NEG_X,
6837681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger     PIPE_TEX_FACE_POS_Y, PIPE_TEX_FACE_NEG_Y }
684621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie};
685621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie
686a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline unsigned
6877681beedd19cf437252fbc1041b19328ad773ea5Roland Scheideggerget_next_face(unsigned face, int idx)
688621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie{
6897681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   return face_array[face][idx];
6907681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger}
691621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie
6927681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger/*
6937681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * return a new xcoord based on old face, old coords, cube size
6947681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * and fall_off_index (0 for x-, 1 for x+, 2 for y-, 3 for y+)
6957681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger */
696a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline int
6977681beedd19cf437252fbc1041b19328ad773ea5Roland Scheideggerget_next_xcoord(unsigned face, unsigned fall_off_index, int max, int xc, int yc)
6987681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger{
6997681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   if ((face == 0 && fall_off_index != 1) ||
7007681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 1 && fall_off_index == 0) ||
7017681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 4 && fall_off_index == 0) ||
7027681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 5 && fall_off_index == 0)) {
7037681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger      return max;
7047681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   }
7057681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   if ((face == 1 && fall_off_index != 0) ||
7067681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 0 && fall_off_index == 1) ||
7077681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 4 && fall_off_index == 1) ||
7087681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 5 && fall_off_index == 1)) {
7097681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger      return 0;
7107681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   }
7117681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   if ((face == 4 && fall_off_index >= 2) ||
7127681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 2 && fall_off_index == 3) ||
7137681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 3 && fall_off_index == 2)) {
7147681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger      return xc;
7157681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   }
7167681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   if ((face == 5 && fall_off_index >= 2) ||
7177681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 2 && fall_off_index == 2) ||
7187681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 3 && fall_off_index == 3)) {
7197681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger      return max - xc;
7207681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   }
7217681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   if ((face == 2 && fall_off_index == 0) ||
7227681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 3 && fall_off_index == 1)) {
7237681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger      return yc;
7247681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   }
7257681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   /* (face == 2 && fall_off_index == 1) ||
7267681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger      (face == 3 && fall_off_index == 0)) */
7277681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   return max - yc;
7287681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger}
729621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie
7307681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger/*
7317681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * return a new ycoord based on old face, old coords, cube size
7327681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger * and fall_off_index (0 for x-, 1 for x+, 2 for y-, 3 for y+)
7337681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger */
734a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline int
7357681beedd19cf437252fbc1041b19328ad773ea5Roland Scheideggerget_next_ycoord(unsigned face, unsigned fall_off_index, int max, int xc, int yc)
7367681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger{
7377681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   if ((fall_off_index <= 1) && (face <= 1 || face >= 4)) {
7387681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger      return yc;
7397681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   }
7407681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   if (face == 2 ||
7417681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 4 && fall_off_index == 3) ||
7427681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 5 && fall_off_index == 2)) {
7437681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger      return 0;
7447681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   }
7457681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   if (face == 3 ||
7467681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 4 && fall_off_index == 2) ||
7477681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 5 && fall_off_index == 3)) {
7487681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger      return max;
7497681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   }
7507681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   if ((face == 0 && fall_off_index == 3) ||
7517681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger       (face == 1 && fall_off_index == 2)) {
7527681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger      return xc;
7537681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   }
7547681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   /* (face == 0 && fall_off_index == 2) ||
7557681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger      (face == 1 && fall_off_index == 3) */
7567681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger   return max - xc;
757621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie}
758621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie
7597681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger
76081601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell/* Gather a quad of adjacent texels within a tile:
76181601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell */
762a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline void
763ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerget_texel_quad_2d_no_border_single_tile(const struct sp_sampler_view *sp_sview,
764ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                                        union tex_tile_address addr,
765ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                                        unsigned x, unsigned y,
766ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                                        const float *out[4])
76781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell{
768ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger    const struct softpipe_tex_cached_tile *tile;
76981601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
7702f567fb7b50e39aef20f0a0cd9b2eba184ed6441Roland Scheidegger   addr.bits.x = x / TEX_TILE_SIZE;
7712f567fb7b50e39aef20f0a0cd9b2eba184ed6441Roland Scheidegger   addr.bits.y = y / TEX_TILE_SIZE;
7722f567fb7b50e39aef20f0a0cd9b2eba184ed6441Roland Scheidegger   y %= TEX_TILE_SIZE;
7732f567fb7b50e39aef20f0a0cd9b2eba184ed6441Roland Scheidegger   x %= TEX_TILE_SIZE;
77481601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
775ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tile = sp_get_cached_tile_tex(sp_sview->cache, addr);
7766142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
7776142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   out[0] = &tile->data.color[y  ][x  ][0];
7786142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   out[1] = &tile->data.color[y  ][x+1][0];
7796142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   out[2] = &tile->data.color[y+1][x  ][0];
7806142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   out[3] = &tile->data.color[y+1][x+1][0];
7816142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell}
7826142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
78381601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
78481601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell/* Gather a quad of potentially non-adjacent texels:
78581601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell */
786a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline void
787ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerget_texel_quad_2d_no_border(const struct sp_sampler_view *sp_sview,
788ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                            union tex_tile_address addr,
789ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                            int x0, int y0,
790ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                            int x1, int y1,
791ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                            const float *out[4])
79281601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell{
793ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   out[0] = get_texel_2d_no_border( sp_sview, addr, x0, y0 );
794ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   out[1] = get_texel_2d_no_border( sp_sview, addr, x1, y0 );
795ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   out[2] = get_texel_2d_no_border( sp_sview, addr, x0, y1 );
796ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   out[3] = get_texel_2d_no_border( sp_sview, addr, x1, y1 );
79781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell}
79881601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
79981601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell/* Can involve a lot of unnecessary checks for border color:
80081601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell */
801a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline void
802ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerget_texel_quad_2d(const struct sp_sampler_view *sp_sview,
803ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                  const struct sp_sampler *sp_samp,
804ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                  union tex_tile_address addr,
805ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                  int x0, int y0,
806ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                  int x1, int y1,
807ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                  const float *out[4])
80881601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell{
809ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   out[0] = get_texel_2d( sp_sview, sp_samp, addr, x0, y0 );
810ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   out[1] = get_texel_2d( sp_sview, sp_samp, addr, x1, y0 );
811ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   out[3] = get_texel_2d( sp_sview, sp_samp, addr, x1, y1 );
812ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   out[2] = get_texel_2d( sp_sview, sp_samp, addr, x0, y1 );
81381601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell}
81481601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
81581601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
81681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
817f3955f6fcdd1a3106a6538642131ccea5ef1cef0Brian Paul/* 3d variants:
81881601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell */
819a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline const float *
820ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerget_texel_3d_no_border(const struct sp_sampler_view *sp_sview,
821e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul                       union tex_tile_address addr, int x, int y, int z)
8226142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell{
823153e474d22d1b440bb6bd7b04dabf244d7455582Keith Whitwell   const struct softpipe_tex_cached_tile *tile;
8246142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
8252f567fb7b50e39aef20f0a0cd9b2eba184ed6441Roland Scheidegger   addr.bits.x = x / TEX_TILE_SIZE;
8262f567fb7b50e39aef20f0a0cd9b2eba184ed6441Roland Scheidegger   addr.bits.y = y / TEX_TILE_SIZE;
82781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   addr.bits.z = z;
8282f567fb7b50e39aef20f0a0cd9b2eba184ed6441Roland Scheidegger   y %= TEX_TILE_SIZE;
8292f567fb7b50e39aef20f0a0cd9b2eba184ed6441Roland Scheidegger   x %= TEX_TILE_SIZE;
8306142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
831ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tile = sp_get_cached_tile_tex(sp_sview->cache, addr);
832153e474d22d1b440bb6bd7b04dabf244d7455582Keith Whitwell
8336142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   return &tile->data.color[y][x][0];
8346142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell}
8356142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
8366142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
837a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline const float *
838ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerget_texel_3d(const struct sp_sampler_view *sp_sview,
839ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger             const struct sp_sampler *sp_samp,
840ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger             union tex_tile_address addr, int x, int y, int z)
841b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul{
842ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
8432135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const unsigned level = addr.bits.level;
8440b9e96fae9493d5d58f046e01c983a3c4267090eBrian Paul
845683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell   if (x < 0 || x >= (int) u_minify(texture->width0, level) ||
846683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell       y < 0 || y >= (int) u_minify(texture->height0, level) ||
847683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell       z < 0 || z >= (int) u_minify(texture->depth0, level)) {
848ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return sp_samp->base.border_color.f;
849ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul   }
850ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul   else {
851ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return get_texel_3d_no_border( sp_sview, addr, x, y, z );
852ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul   }
853b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul}
854b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul
855b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul
85680777743b7b6238f034b8cb81d8d907d74929334Brian Paul/* Get texel pointer for 1D array texture */
857a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline const float *
858ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerget_texel_1d_array(const struct sp_sampler_view *sp_sview,
859ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                   const struct sp_sampler *sp_samp,
86080777743b7b6238f034b8cb81d8d907d74929334Brian Paul                   union tex_tile_address addr, int x, int y)
86180777743b7b6238f034b8cb81d8d907d74929334Brian Paul{
862ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
8632135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const unsigned level = addr.bits.level;
86480777743b7b6238f034b8cb81d8d907d74929334Brian Paul
86580777743b7b6238f034b8cb81d8d907d74929334Brian Paul   if (x < 0 || x >= (int) u_minify(texture->width0, level)) {
866ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return sp_samp->base.border_color.f;
86780777743b7b6238f034b8cb81d8d907d74929334Brian Paul   }
86880777743b7b6238f034b8cb81d8d907d74929334Brian Paul   else {
869ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return get_texel_2d_no_border(sp_sview, addr, x, y);
87080777743b7b6238f034b8cb81d8d907d74929334Brian Paul   }
87180777743b7b6238f034b8cb81d8d907d74929334Brian Paul}
87280777743b7b6238f034b8cb81d8d907d74929334Brian Paul
87380777743b7b6238f034b8cb81d8d907d74929334Brian Paul
87480777743b7b6238f034b8cb81d8d907d74929334Brian Paul/* Get texel pointer for 2D array texture */
875a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline const float *
876ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerget_texel_2d_array(const struct sp_sampler_view *sp_sview,
877ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                   const struct sp_sampler *sp_samp,
87880777743b7b6238f034b8cb81d8d907d74929334Brian Paul                   union tex_tile_address addr, int x, int y, int layer)
87980777743b7b6238f034b8cb81d8d907d74929334Brian Paul{
880ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
8812135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const unsigned level = addr.bits.level;
88280777743b7b6238f034b8cb81d8d907d74929334Brian Paul
88392d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul   assert(layer < (int) texture->array_size);
88492d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul   assert(layer >= 0);
88580777743b7b6238f034b8cb81d8d907d74929334Brian Paul
88680777743b7b6238f034b8cb81d8d907d74929334Brian Paul   if (x < 0 || x >= (int) u_minify(texture->width0, level) ||
88780777743b7b6238f034b8cb81d8d907d74929334Brian Paul       y < 0 || y >= (int) u_minify(texture->height0, level)) {
888ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return sp_samp->base.border_color.f;
88980777743b7b6238f034b8cb81d8d907d74929334Brian Paul   }
89080777743b7b6238f034b8cb81d8d907d74929334Brian Paul   else {
891ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return get_texel_3d_no_border(sp_sview, addr, x, y, layer);
89280777743b7b6238f034b8cb81d8d907d74929334Brian Paul   }
89380777743b7b6238f034b8cb81d8d907d74929334Brian Paul}
89480777743b7b6238f034b8cb81d8d907d74929334Brian Paul
89580777743b7b6238f034b8cb81d8d907d74929334Brian Paul
896a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline const float *
897adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheideggerget_texel_cube_seamless(const struct sp_sampler_view *sp_sview,
898adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                        union tex_tile_address addr, int x, int y,
899adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                        float *corner, int layer, unsigned face)
900adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger{
901adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
9022135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const unsigned level = addr.bits.level;
903adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   int new_x, new_y, max_x;
904adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger
905adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   max_x = (int) u_minify(texture->width0, level);
906adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger
907adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   assert(texture->width0 == texture->height0);
908adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   new_x = x;
909adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   new_y = y;
910adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger
911adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   /* change the face */
912adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   if (x < 0) {
913adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      /*
914adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger       * Cheat with corners. They are difficult and I believe because we don't get
915adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger       * per-pixel faces we can actually have multiple corner texels per pixel,
916adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger       * which screws things up majorly in any case (as the per spec behavior is
917adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger       * to average the 3 remaining texels, which we might not have).
918adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger       * Hence just make sure that the 2nd coord is clamped, will simply pick the
919adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger       * sample which would have fallen off the x coord, but not y coord.
920adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger       * So the filter weight of the samples will be wrong, but at least this
921adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger       * ensures that only valid texels near the corner are used.
922adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger       */
923adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      if (y < 0 || y >= max_x) {
924adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger         y = CLAMP(y, 0, max_x - 1);
925adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      }
926adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      new_x = get_next_xcoord(face, 0, max_x -1, x, y);
927adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      new_y = get_next_ycoord(face, 0, max_x -1, x, y);
928adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      face = get_next_face(face, 0);
929adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   } else if (x >= max_x) {
930adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      if (y < 0 || y >= max_x) {
931adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger         y = CLAMP(y, 0, max_x - 1);
932adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      }
933adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      new_x = get_next_xcoord(face, 1, max_x -1, x, y);
934adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      new_y = get_next_ycoord(face, 1, max_x -1, x, y);
935adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      face = get_next_face(face, 1);
936adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   } else if (y < 0) {
937adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      new_x = get_next_xcoord(face, 2, max_x -1, x, y);
938adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      new_y = get_next_ycoord(face, 2, max_x -1, x, y);
939adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      face = get_next_face(face, 2);
940adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   } else if (y >= max_x) {
941adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      new_x = get_next_xcoord(face, 3, max_x -1, x, y);
942adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      new_y = get_next_ycoord(face, 3, max_x -1, x, y);
943adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      face = get_next_face(face, 3);
944adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   }
945adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger
946adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   return get_texel_3d_no_border(sp_sview, addr, new_x, new_y, layer + face);
947adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger}
948adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger
949adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger
950309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie/* Get texel pointer for cube array texture */
951a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline const float *
952ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerget_texel_cube_array(const struct sp_sampler_view *sp_sview,
953ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                     const struct sp_sampler *sp_samp,
954309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie                     union tex_tile_address addr, int x, int y, int layer)
955309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie{
956ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
9572135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const unsigned level = addr.bits.level;
958309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie
959309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   assert(layer < (int) texture->array_size);
960309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   assert(layer >= 0);
961309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie
962309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   if (x < 0 || x >= (int) u_minify(texture->width0, level) ||
963309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie       y < 0 || y >= (int) u_minify(texture->height0, level)) {
964ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return sp_samp->base.border_color.f;
965309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   }
966309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   else {
967ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return get_texel_3d_no_border(sp_sview, addr, x, y, layer);
968309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   }
969309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie}
97075276ea316610a5737f2115326482024aa09d02aBrian Paul/**
97175276ea316610a5737f2115326482024aa09d02aBrian Paul * Given the logbase2 of a mipmap's base level size and a mipmap level,
97275276ea316610a5737f2115326482024aa09d02aBrian Paul * return the size (in texels) of that mipmap level.
97375276ea316610a5737f2115326482024aa09d02aBrian Paul * For example, if level[0].width = 256 then base_pot will be 8.
97475276ea316610a5737f2115326482024aa09d02aBrian Paul * If level = 2, then we'll return 64 (the width at level=2).
97575276ea316610a5737f2115326482024aa09d02aBrian Paul * Return 1 if level > base_pot.
97675276ea316610a5737f2115326482024aa09d02aBrian Paul */
977a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline unsigned
97875276ea316610a5737f2115326482024aa09d02aBrian Paulpot_level_size(unsigned base_pot, unsigned level)
97975276ea316610a5737f2115326482024aa09d02aBrian Paul{
98075276ea316610a5737f2115326482024aa09d02aBrian Paul   return (base_pot >= level) ? (1 << (base_pot - level)) : 1;
98175276ea316610a5737f2115326482024aa09d02aBrian Paul}
98275276ea316610a5737f2115326482024aa09d02aBrian Paul
98375276ea316610a5737f2115326482024aa09d02aBrian Paul
9844250882ccf8326ba9074c671110370534489caa6Brian Paulstatic void
985229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertprint_sample(const char *function, const float *rgba)
986229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
987229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   debug_printf("%s %g %g %g %g\n",
988229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                function,
989229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                rgba[0], rgba[TGSI_NUM_CHANNELS], rgba[2*TGSI_NUM_CHANNELS], rgba[3*TGSI_NUM_CHANNELS]);
990229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert}
991229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert
992229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert
993229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertstatic void
994229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertprint_sample_4(const char *function, float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
9954250882ccf8326ba9074c671110370534489caa6Brian Paul{
9964250882ccf8326ba9074c671110370534489caa6Brian Paul   debug_printf("%s %g %g %g %g, %g %g %g %g, %g %g %g %g, %g %g %g %g\n",
9974250882ccf8326ba9074c671110370534489caa6Brian Paul                function,
9984250882ccf8326ba9074c671110370534489caa6Brian Paul                rgba[0][0], rgba[1][0], rgba[2][0], rgba[3][0],
9994250882ccf8326ba9074c671110370534489caa6Brian Paul                rgba[0][1], rgba[1][1], rgba[2][1], rgba[3][1],
10004250882ccf8326ba9074c671110370534489caa6Brian Paul                rgba[0][2], rgba[1][2], rgba[2][2], rgba[3][2],
10014250882ccf8326ba9074c671110370534489caa6Brian Paul                rgba[0][3], rgba[1][3], rgba[2][3], rgba[3][3]);
10024250882ccf8326ba9074c671110370534489caa6Brian Paul}
10034250882ccf8326ba9074c671110370534489caa6Brian Paul
1004ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
100581601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell/* Some image-filter fastpaths:
100681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell */
1007a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline void
1008ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowakimg_filter_2d_linear_repeat_POT(const struct sp_sampler_view *sp_sview,
1009ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowak                                const struct sp_sampler *sp_samp,
101099e583120cde8820aae94eb0f8beb723509398fcDave Airlie                                const struct img_filter_args *args,
1011229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                float *rgba)
10126142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell{
10132135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const unsigned xpot = pot_level_size(sp_sview->xpot, args->level);
10142135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const unsigned ypot = pot_level_size(sp_sview->ypot, args->level);
10152135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int xmax = (xpot - 1) & (TEX_TILE_SIZE - 1); /* MIN2(TEX_TILE_SIZE, xpot) - 1; */
10162135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int ymax = (ypot - 1) & (TEX_TILE_SIZE - 1); /* MIN2(TEX_TILE_SIZE, ypot) - 1; */
1017153e474d22d1b440bb6bd7b04dabf244d7455582Keith Whitwell   union tex_tile_address addr;
1018229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
1019153e474d22d1b440bb6bd7b04dabf244d7455582Keith Whitwell
10202135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float u = (args->s * xpot - 0.5F) + args->offset[0];
10212135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float v = (args->t * ypot - 0.5F) + args->offset[1];
10226142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
10232135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int uflr = util_ifloor(u);
10242135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int vflr = util_ifloor(v);
10256142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
10262135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float xw = u - (float)uflr;
10272135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float yw = v - (float)vflr;
10286142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
10292135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int x0 = uflr & (xpot - 1);
10302135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int y0 = vflr & (ypot - 1);
10316142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
1032229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *tx[4];
10336142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
1034229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   addr.value = 0;
103599e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
1036fb586e1edb207328534f554a9afaf2c07434e08eRoland Scheidegger   addr.bits.z = sp_sview->base.u.tex.first_layer;
10376142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
1038229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   /* Can we fetch all four at once:
1039229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert    */
1040229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (x0 < xmax && y0 < ymax) {
1041ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      get_texel_quad_2d_no_border_single_tile(sp_sview, addr, x0, y0, tx);
1042229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   }
1043229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   else {
10442135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak      const unsigned x1 = (x0 + 1) & (xpot - 1);
10452135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak      const unsigned y1 = (y0 + 1) & (ypot - 1);
1046ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      get_texel_quad_2d_no_border(sp_sview, addr, x0, y0, x1, y1, tx);
1047229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   }
1048229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert
1049229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   /* interpolate R, G, B, A */
10504b249ed4cd813fa71e3b4a9457b365cc5dcbc3a1Roland Scheidegger   for (c = 0; c < TGSI_NUM_CHANNELS; c++) {
1051229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw,
1052229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                       tx[0][c], tx[1][c],
1053229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                       tx[2][c], tx[3][c]);
10546142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   }
10554250882ccf8326ba9074c671110370534489caa6Brian Paul
10564250882ccf8326ba9074c671110370534489caa6Brian Paul   if (DEBUG_TEX) {
10574250882ccf8326ba9074c671110370534489caa6Brian Paul      print_sample(__FUNCTION__, rgba);
10584250882ccf8326ba9074c671110370534489caa6Brian Paul   }
10596142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell}
10606142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
10616142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
1062a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline void
1063ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowakimg_filter_2d_nearest_repeat_POT(const struct sp_sampler_view *sp_sview,
1064ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowak                                 const struct sp_sampler *sp_samp,
106599e583120cde8820aae94eb0f8beb723509398fcDave Airlie                                 const struct img_filter_args *args,
10664b249ed4cd813fa71e3b4a9457b365cc5dcbc3a1Roland Scheidegger                                 float *rgba)
10676142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell{
10682135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const unsigned xpot = pot_level_size(sp_sview->xpot, args->level);
10692135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const unsigned ypot = pot_level_size(sp_sview->ypot, args->level);
1070229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *out;
1071153e474d22d1b440bb6bd7b04dabf244d7455582Keith Whitwell   union tex_tile_address addr;
1072229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
1073153e474d22d1b440bb6bd7b04dabf244d7455582Keith Whitwell
10742135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float u = args->s * xpot + args->offset[0];
10752135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float v = args->t * ypot + args->offset[1];
10766142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
10772135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int uflr = util_ifloor(u);
10782135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int vflr = util_ifloor(v);
10796142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
10802135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int x0 = uflr & (xpot - 1);
10812135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int y0 = vflr & (ypot - 1);
10826142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
1083229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   addr.value = 0;
108499e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
1085fb586e1edb207328534f554a9afaf2c07434e08eRoland Scheidegger   addr.bits.z = sp_sview->base.u.tex.first_layer;
10866142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
1087ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   out = get_texel_2d_no_border(sp_sview, addr, x0, y0);
10884b249ed4cd813fa71e3b4a9457b365cc5dcbc3a1Roland Scheidegger   for (c = 0; c < TGSI_NUM_CHANNELS; c++)
1089229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = out[c];
10904250882ccf8326ba9074c671110370534489caa6Brian Paul
10914250882ccf8326ba9074c671110370534489caa6Brian Paul   if (DEBUG_TEX) {
10924250882ccf8326ba9074c671110370534489caa6Brian Paul      print_sample(__FUNCTION__, rgba);
10934250882ccf8326ba9074c671110370534489caa6Brian Paul   }
10946142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell}
10956142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
10966142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
1097a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline void
1098ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowakimg_filter_2d_nearest_clamp_POT(const struct sp_sampler_view *sp_sview,
1099ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowak                                const struct sp_sampler *sp_samp,
110099e583120cde8820aae94eb0f8beb723509398fcDave Airlie                                const struct img_filter_args *args,
11014b249ed4cd813fa71e3b4a9457b365cc5dcbc3a1Roland Scheidegger                                float *rgba)
11026142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell{
11032135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const unsigned xpot = pot_level_size(sp_sview->xpot, args->level);
11042135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const unsigned ypot = pot_level_size(sp_sview->ypot, args->level);
1105153e474d22d1b440bb6bd7b04dabf244d7455582Keith Whitwell   union tex_tile_address addr;
1106229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
1107153e474d22d1b440bb6bd7b04dabf244d7455582Keith Whitwell
11082135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float u = args->s * xpot + args->offset[0];
11092135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float v = args->t * ypot + args->offset[1];
11106142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
1111229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x0, y0;
1112229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *out;
11136142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
1114229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   addr.value = 0;
111599e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
1116fb586e1edb207328534f554a9afaf2c07434e08eRoland Scheidegger   addr.bits.z = sp_sview->base.u.tex.first_layer;
1117229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert
1118229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   x0 = util_ifloor(u);
1119229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (x0 < 0)
1120229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      x0 = 0;
1121919236f3a28adfb04403e3f0db458afb9a897fd4Brian Paul   else if (x0 > (int) xpot - 1)
1122229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      x0 = xpot - 1;
1123229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert
1124229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   y0 = util_ifloor(v);
1125229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   if (y0 < 0)
1126229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      y0 = 0;
1127919236f3a28adfb04403e3f0db458afb9a897fd4Brian Paul   else if (y0 > (int) ypot - 1)
1128229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      y0 = ypot - 1;
1129229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert
1130ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   out = get_texel_2d_no_border(sp_sview, addr, x0, y0);
11314b249ed4cd813fa71e3b4a9457b365cc5dcbc3a1Roland Scheidegger   for (c = 0; c < TGSI_NUM_CHANNELS; c++)
1132229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = out[c];
11334250882ccf8326ba9074c671110370534489caa6Brian Paul
11344250882ccf8326ba9074c671110370534489caa6Brian Paul   if (DEBUG_TEX) {
11354250882ccf8326ba9074c671110370534489caa6Brian Paul      print_sample(__FUNCTION__, rgba);
11364250882ccf8326ba9074c671110370534489caa6Brian Paul   }
11376142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell}
11386142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
1139e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
11406142de393fe34ff0866f8489f1292eb473276f11Keith Whitwellstatic void
1141ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowakimg_filter_1d_nearest(const struct sp_sampler_view *sp_sview,
1142ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowak                      const struct sp_sampler *sp_samp,
114399e583120cde8820aae94eb0f8beb723509398fcDave Airlie                      const struct img_filter_args *args,
11444b249ed4cd813fa71e3b4a9457b365cc5dcbc3a1Roland Scheidegger                      float *rgba)
11456142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell{
1146ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
11472135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int width = u_minify(texture->width0, args->level);
1148229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x;
114981601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   union tex_tile_address addr;
1150229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *out;
1151229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
11526142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
11534fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   assert(width > 0);
11544f409da3456070946eda2d8ff5153b3b4306bb46Keith Whitwell
115581601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   addr.value = 0;
115699e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
115781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
11583f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x);
11594f409da3456070946eda2d8ff5153b3b4306bb46Keith Whitwell
1160fb586e1edb207328534f554a9afaf2c07434e08eRoland Scheidegger   out = get_texel_1d_array(sp_sview, sp_samp, addr, x,
1161fb586e1edb207328534f554a9afaf2c07434e08eRoland Scheidegger                            sp_sview->base.u.tex.first_layer);
11624b249ed4cd813fa71e3b4a9457b365cc5dcbc3a1Roland Scheidegger   for (c = 0; c < TGSI_NUM_CHANNELS; c++)
1163229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = out[c];
11644250882ccf8326ba9074c671110370534489caa6Brian Paul
11654250882ccf8326ba9074c671110370534489caa6Brian Paul   if (DEBUG_TEX) {
11664250882ccf8326ba9074c671110370534489caa6Brian Paul      print_sample(__FUNCTION__, rgba);
11674250882ccf8326ba9074c671110370534489caa6Brian Paul   }
11686142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell}
11696142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
11704fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
117160adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwellstatic void
1172ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowakimg_filter_1d_array_nearest(const struct sp_sampler_view *sp_sview,
1173ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowak                            const struct sp_sampler *sp_samp,
117499e583120cde8820aae94eb0f8beb723509398fcDave Airlie                            const struct img_filter_args *args,
1175229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                            float *rgba)
1176779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul{
1177ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
11782135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int width = u_minify(texture->width0, args->level);
11792135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int layer = coord_to_layer(args->t, sp_sview->base.u.tex.first_layer,
11802135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak                                    sp_sview->base.u.tex.last_layer);
11812135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   int x;
1182779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   union tex_tile_address addr;
1183229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *out;
1184229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
1185779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1186779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   assert(width > 0);
1187779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1188779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   addr.value = 0;
118999e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
1190779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
11913f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x);
1192779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1193ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   out = get_texel_1d_array(sp_sview, sp_samp, addr, x, layer);
11944b249ed4cd813fa71e3b4a9457b365cc5dcbc3a1Roland Scheidegger   for (c = 0; c < TGSI_NUM_CHANNELS; c++)
1195229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = out[c];
1196779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1197779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   if (DEBUG_TEX) {
1198779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul      print_sample(__FUNCTION__, rgba);
1199779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   }
1200779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul}
1201779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1202779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1203779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paulstatic void
1204ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowakimg_filter_2d_nearest(const struct sp_sampler_view *sp_sview,
1205ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowak                      const struct sp_sampler *sp_samp,
120699e583120cde8820aae94eb0f8beb723509398fcDave Airlie                      const struct img_filter_args *args,
1207229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                      float *rgba)
120860adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell{
1209ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
12102135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int width = u_minify(texture->width0, args->level);
12112135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int height = u_minify(texture->height0, args->level);
1212229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x, y;
121360adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell   union tex_tile_address addr;
1214229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *out;
1215229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
121681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
121760adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell   assert(width > 0);
12185dbedf3d7e99efe35fad308d382670e44cd60e25Brian Paul   assert(height > 0);
121960adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
122060adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell   addr.value = 0;
122199e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
1222fb586e1edb207328534f554a9afaf2c07434e08eRoland Scheidegger   addr.bits.z = sp_sview->base.u.tex.first_layer;
122360adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
12243f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x);
12253f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->nearest_texcoord_t(args->t, height, args->offset[1], &y);
122660adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
1227ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   out = get_texel_2d(sp_sview, sp_samp, addr, x, y);
12284b249ed4cd813fa71e3b4a9457b365cc5dcbc3a1Roland Scheidegger   for (c = 0; c < TGSI_NUM_CHANNELS; c++)
1229229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = out[c];
12304250882ccf8326ba9074c671110370534489caa6Brian Paul
12314250882ccf8326ba9074c671110370534489caa6Brian Paul   if (DEBUG_TEX) {
12324250882ccf8326ba9074c671110370534489caa6Brian Paul      print_sample(__FUNCTION__, rgba);
12334250882ccf8326ba9074c671110370534489caa6Brian Paul   }
123460adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell}
123560adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
1236e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
1237779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paulstatic void
1238ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowakimg_filter_2d_array_nearest(const struct sp_sampler_view *sp_sview,
1239ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowak                            const struct sp_sampler *sp_samp,
124099e583120cde8820aae94eb0f8beb723509398fcDave Airlie                            const struct img_filter_args *args,
1241229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                            float *rgba)
1242779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul{
1243ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
12442135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int width = u_minify(texture->width0, args->level);
12452135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int height = u_minify(texture->height0, args->level);
12462135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int layer = coord_to_layer(args->p, sp_sview->base.u.tex.first_layer,
12472135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak                                    sp_sview->base.u.tex.last_layer);
12482135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   int x, y;
1249779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   union tex_tile_address addr;
1250229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *out;
1251229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
1252779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1253779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   assert(width > 0);
1254779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   assert(height > 0);
1255779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1256779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   addr.value = 0;
125799e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
1258779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
12593f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x);
12603f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->nearest_texcoord_t(args->t, height, args->offset[1], &y);
1261779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1262ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   out = get_texel_2d_array(sp_sview, sp_samp, addr, x, y, layer);
12634b249ed4cd813fa71e3b4a9457b365cc5dcbc3a1Roland Scheidegger   for (c = 0; c < TGSI_NUM_CHANNELS; c++)
1264229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = out[c];
1265779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1266779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   if (DEBUG_TEX) {
1267779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul      print_sample(__FUNCTION__, rgba);
1268779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   }
1269779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul}
1270779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1271779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1272e12810d92ffb3547680b227bf88937c03018112bBrian Paulstatic void
1273ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowakimg_filter_cube_nearest(const struct sp_sampler_view *sp_sview,
1274ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowak                        const struct sp_sampler *sp_samp,
127599e583120cde8820aae94eb0f8beb723509398fcDave Airlie                        const struct img_filter_args *args,
1276229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                        float *rgba)
12770dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul{
1278ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
12792135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int width = u_minify(texture->width0, args->level);
12802135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int height = u_minify(texture->height0, args->level);
12812135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int layerface = args->face_id + sp_sview->base.u.tex.first_layer;
12822135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   int x, y;
128381601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   union tex_tile_address addr;
1284229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *out;
1285229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
128681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
1287b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul   assert(width > 0);
12885dbedf3d7e99efe35fad308d382670e44cd60e25Brian Paul   assert(height > 0);
128981601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
129081601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   addr.value = 0;
129199e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
1292612cfb749c3526eeb446bbc631bf24716522f373Brian Paul
1293621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   /*
1294621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie    * If NEAREST filtering is done within a miplevel, always apply wrap
1295621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie    * mode CLAMP_TO_EDGE.
1296621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie    */
1297ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   if (sp_samp->base.seamless_cube_map) {
12983f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      wrap_nearest_clamp_to_edge(args->s, width, args->offset[0], &x);
12993f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      wrap_nearest_clamp_to_edge(args->t, height, args->offset[1], &y);
1300621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   } else {
13017681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger      /* Would probably make sense to ignore mode and just do edge clamp */
13023f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x);
13033f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      sp_samp->nearest_texcoord_t(args->t, height, args->offset[1], &y);
1304621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   }
1305f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul
1306adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   out = get_texel_cube_array(sp_sview, sp_samp, addr, x, y, layerface);
13074b249ed4cd813fa71e3b4a9457b365cc5dcbc3a1Roland Scheidegger   for (c = 0; c < TGSI_NUM_CHANNELS; c++)
1308229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = out[c];
13094250882ccf8326ba9074c671110370534489caa6Brian Paul
13104250882ccf8326ba9074c671110370534489caa6Brian Paul   if (DEBUG_TEX) {
13114250882ccf8326ba9074c671110370534489caa6Brian Paul      print_sample(__FUNCTION__, rgba);
13124250882ccf8326ba9074c671110370534489caa6Brian Paul   }
13130dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul}
131434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul
1315309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airliestatic void
1316ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowakimg_filter_cube_array_nearest(const struct sp_sampler_view *sp_sview,
1317ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowak                              const struct sp_sampler *sp_samp,
131899e583120cde8820aae94eb0f8beb723509398fcDave Airlie                              const struct img_filter_args *args,
1319ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                              float *rgba)
1320ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger{
1321ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
13222135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int width = u_minify(texture->width0, args->level);
13232135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int height = u_minify(texture->height0, args->level);
13242135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int layerface =
13252135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak      coord_to_layer(6 * args->p + sp_sview->base.u.tex.first_layer,
13262135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak                     sp_sview->base.u.tex.first_layer,
13272135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak                     sp_sview->base.u.tex.last_layer - 5) + args->face_id;
13282135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   int x, y;
1329309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   union tex_tile_address addr;
1330309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   const float *out;
1331309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   int c;
1332309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie
1333309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   assert(width > 0);
1334309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   assert(height > 0);
1335309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie
1336309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   addr.value = 0;
133799e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
1338309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie
13393f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x);
13403f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->nearest_texcoord_t(args->t, height, args->offset[1], &y);
1341309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie
1342adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   out = get_texel_cube_array(sp_sview, sp_samp, addr, x, y, layerface);
13434b249ed4cd813fa71e3b4a9457b365cc5dcbc3a1Roland Scheidegger   for (c = 0; c < TGSI_NUM_CHANNELS; c++)
1344309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie      rgba[TGSI_NUM_CHANNELS*c] = out[c];
1345309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie
1346309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   if (DEBUG_TEX) {
1347309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie      print_sample(__FUNCTION__, rgba);
1348309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   }
1349309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie}
135034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul
13514fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
1352ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowakimg_filter_3d_nearest(const struct sp_sampler_view *sp_sview,
1353ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowak                      const struct sp_sampler *sp_samp,
135499e583120cde8820aae94eb0f8beb723509398fcDave Airlie                      const struct img_filter_args *args,
1355229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                      float *rgba)
135634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul{
1357ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
13582135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int width = u_minify(texture->width0, args->level);
13592135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int height = u_minify(texture->height0, args->level);
13602135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int depth = u_minify(texture->depth0, args->level);
1361229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x, y, z;
136281601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   union tex_tile_address addr;
1363229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *out;
1364229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
1365b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul
13663d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul   assert(width > 0);
13673d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul   assert(height > 0);
13683d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul   assert(depth > 0);
13693d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul
13703f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->nearest_texcoord_s(args->s, width,  args->offset[0], &x);
13713f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->nearest_texcoord_t(args->t, height, args->offset[1], &y);
13723f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->nearest_texcoord_p(args->p, depth,  args->offset[2], &z);
13733d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul
137481601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   addr.value = 0;
137599e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
137681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
1377ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   out = get_texel_3d(sp_sview, sp_samp, addr, x, y, z);
13784b249ed4cd813fa71e3b4a9457b365cc5dcbc3a1Roland Scheidegger   for (c = 0; c < TGSI_NUM_CHANNELS; c++)
1379229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = out[c];
138034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul}
138134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul
138234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul
138334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paulstatic void
1384ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowakimg_filter_1d_linear(const struct sp_sampler_view *sp_sview,
1385ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowak                     const struct sp_sampler *sp_samp,
138699e583120cde8820aae94eb0f8beb723509398fcDave Airlie                     const struct img_filter_args *args,
1387229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                     float *rgba)
138834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul{
1389ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
13902135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int width = u_minify(texture->width0, args->level);
1391229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x0, x1;
1392229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float xw; /* weights */
139381601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   union tex_tile_address addr;
1394229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *tx0, *tx1;
1395229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
13964fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
13974fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   assert(width > 0);
13984fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
139981601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   addr.value = 0;
140099e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
140181601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
14023f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->linear_texcoord_s(args->s, width, args->offset[0], &x0, &x1, &xw);
14034fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1404fb586e1edb207328534f554a9afaf2c07434e08eRoland Scheidegger   tx0 = get_texel_1d_array(sp_sview, sp_samp, addr, x0,
1405fb586e1edb207328534f554a9afaf2c07434e08eRoland Scheidegger                            sp_sview->base.u.tex.first_layer);
1406fb586e1edb207328534f554a9afaf2c07434e08eRoland Scheidegger   tx1 = get_texel_1d_array(sp_sview, sp_samp, addr, x1,
1407fb586e1edb207328534f554a9afaf2c07434e08eRoland Scheidegger                            sp_sview->base.u.tex.first_layer);
14084fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1409229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   /* interpolate R, G, B, A */
14104b249ed4cd813fa71e3b4a9457b365cc5dcbc3a1Roland Scheidegger   for (c = 0; c < TGSI_NUM_CHANNELS; c++)
1411229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = lerp(xw, tx0[c], tx1[c]);
141234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul}
141334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul
141481601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
141560adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwellstatic void
1416ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowakimg_filter_1d_array_linear(const struct sp_sampler_view *sp_sview,
1417ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowak                           const struct sp_sampler *sp_samp,
141899e583120cde8820aae94eb0f8beb723509398fcDave Airlie                           const struct img_filter_args *args,
1419229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                           float *rgba)
1420779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul{
1421ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
14222135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int width = u_minify(texture->width0, args->level);
14232135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int layer = coord_to_layer(args->t, sp_sview->base.u.tex.first_layer,
14242135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak                                    sp_sview->base.u.tex.last_layer);
14252135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   int x0, x1;
1426229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float xw; /* weights */
1427779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   union tex_tile_address addr;
1428229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *tx0, *tx1;
1429229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
1430779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1431779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   assert(width > 0);
1432779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1433779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   addr.value = 0;
143499e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
1435779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
14363f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->linear_texcoord_s(args->s, width, args->offset[0], &x0, &x1, &xw);
1437779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1438ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx0 = get_texel_1d_array(sp_sview, sp_samp, addr, x0, layer);
1439ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx1 = get_texel_1d_array(sp_sview, sp_samp, addr, x1, layer);
1440779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1441229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   /* interpolate R, G, B, A */
14424b249ed4cd813fa71e3b4a9457b365cc5dcbc3a1Roland Scheidegger   for (c = 0; c < TGSI_NUM_CHANNELS; c++)
1443229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] = lerp(xw, tx0[c], tx1[c]);
1444779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul}
1445779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
144655a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie/*
144755a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie * Retrieve the gathered value, need to convert to the
144855a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie * TGSI expected interface, and take component select
144955a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie * and swizzling into account.
145055a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie */
145155a7b5165d40b831fd303079f8f80962d195d6eeDave Airliestatic float
145255a7b5165d40b831fd303079f8f80962d195d6eeDave Airlieget_gather_value(const struct sp_sampler_view *sp_sview,
145355a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie                 int chan_in, int comp_sel,
145455a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie                 const float *tx[4])
145555a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie{
145655a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   int chan;
145755a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   unsigned swizzle;
145855a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie
145955a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   /*
146055a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie    * softpipe samples in a different order
146155a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie    * to TGSI expects, so we need to swizzle,
146255a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie    * the samples into the correct slots.
146355a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie    */
146455a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   switch (chan_in) {
146555a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   case 0:
146655a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      chan = 2;
146755a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      break;
146855a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   case 1:
146955a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      chan = 3;
147055a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      break;
147155a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   case 2:
147255a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      chan = 1;
147355a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      break;
147455a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   case 3:
147555a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      chan = 0;
147655a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      break;
147755a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   default:
147855a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      assert(0);
147955a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      return 0.0;
148055a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   }
148155a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie
148255a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   /* pick which component to use for the swizzle */
148355a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   switch (comp_sel) {
148455a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   case 0:
148555a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      swizzle = sp_sview->base.swizzle_r;
148655a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      break;
148755a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   case 1:
148855a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      swizzle = sp_sview->base.swizzle_g;
148955a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      break;
149055a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   case 2:
149155a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      swizzle = sp_sview->base.swizzle_b;
149255a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      break;
149355a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   case 3:
149455a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      swizzle = sp_sview->base.swizzle_a;
149555a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      break;
149655a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   default:
149755a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      assert(0);
149855a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      return 0.0;
149955a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   }
150055a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie
150155a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   /* get correct result using the channel and swizzle */
150255a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   switch (swizzle) {
1503fb523cb6ad3ffef22ab4b9cce9e53859c17c5739Marek Olšák   case PIPE_SWIZZLE_0:
150455a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      return 0.0;
1505fb523cb6ad3ffef22ab4b9cce9e53859c17c5739Marek Olšák   case PIPE_SWIZZLE_1:
150655a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      return 1.0;
150755a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   default:
150855a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      return tx[chan][swizzle];
150955a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   }
151055a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie}
151155a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie
1512779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1513779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paulstatic void
1514ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowakimg_filter_2d_linear(const struct sp_sampler_view *sp_sview,
1515ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowak                     const struct sp_sampler *sp_samp,
151699e583120cde8820aae94eb0f8beb723509398fcDave Airlie                     const struct img_filter_args *args,
1517229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                     float *rgba)
151860adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell{
1519ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
15202135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int width = u_minify(texture->width0, args->level);
15212135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int height = u_minify(texture->height0, args->level);
1522229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x0, y0, x1, y1;
1523229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float xw, yw; /* weights */
152460adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell   union tex_tile_address addr;
15250108eae2911d2fc8f2ae0ef0fc6fc503fbfc600dDave Airlie   const float *tx[4];
1526229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
152760adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
152860adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell   assert(width > 0);
15295dbedf3d7e99efe35fad308d382670e44cd60e25Brian Paul   assert(height > 0);
153060adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
153160adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell   addr.value = 0;
153299e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
1533fb586e1edb207328534f554a9afaf2c07434e08eRoland Scheidegger   addr.bits.z = sp_sview->base.u.tex.first_layer;
153460adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
15353f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->linear_texcoord_s(args->s, width,  args->offset[0], &x0, &x1, &xw);
15363f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->linear_texcoord_t(args->t, height, args->offset[1], &y0, &y1, &yw);
153760adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
15380108eae2911d2fc8f2ae0ef0fc6fc503fbfc600dDave Airlie   tx[0] = get_texel_2d(sp_sview, sp_samp, addr, x0, y0);
15390108eae2911d2fc8f2ae0ef0fc6fc503fbfc600dDave Airlie   tx[1] = get_texel_2d(sp_sview, sp_samp, addr, x1, y0);
15400108eae2911d2fc8f2ae0ef0fc6fc503fbfc600dDave Airlie   tx[2] = get_texel_2d(sp_sview, sp_samp, addr, x0, y1);
15410108eae2911d2fc8f2ae0ef0fc6fc503fbfc600dDave Airlie   tx[3] = get_texel_2d(sp_sview, sp_samp, addr, x1, y1);
154260adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell
154355a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   if (args->gather_only) {
15444b249ed4cd813fa71e3b4a9457b365cc5dcbc3a1Roland Scheidegger      for (c = 0; c < TGSI_NUM_CHANNELS; c++)
154555a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         rgba[TGSI_NUM_CHANNELS*c] = get_gather_value(sp_sview, c,
154655a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie                                                      args->gather_comp,
154755a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie                                                      tx);
154855a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   } else {
154955a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      /* interpolate R, G, B, A */
15504b249ed4cd813fa71e3b4a9457b365cc5dcbc3a1Roland Scheidegger      for (c = 0; c < TGSI_NUM_CHANNELS; c++)
155155a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw,
155255a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie                                             tx[0][c], tx[1][c],
155355a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie                                             tx[2][c], tx[3][c]);
155455a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   }
155560adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell}
155681601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
155781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
1558b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paulstatic void
1559ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowakimg_filter_2d_array_linear(const struct sp_sampler_view *sp_sview,
1560ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowak                           const struct sp_sampler *sp_samp,
156199e583120cde8820aae94eb0f8beb723509398fcDave Airlie                           const struct img_filter_args *args,
1562229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                           float *rgba)
1563779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul{
1564ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
15652135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int width = u_minify(texture->width0, args->level);
15662135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int height = u_minify(texture->height0, args->level);
15672135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int layer = coord_to_layer(args->p, sp_sview->base.u.tex.first_layer,
15682135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak                                    sp_sview->base.u.tex.last_layer);
15692135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   int x0, y0, x1, y1;
1570229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float xw, yw; /* weights */
1571779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   union tex_tile_address addr;
15720108eae2911d2fc8f2ae0ef0fc6fc503fbfc600dDave Airlie   const float *tx[4];
1573229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
1574779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1575779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   assert(width > 0);
1576779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   assert(height > 0);
1577779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1578779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   addr.value = 0;
157999e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
1580779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
15813f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->linear_texcoord_s(args->s, width,  args->offset[0], &x0, &x1, &xw);
15823f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->linear_texcoord_t(args->t, height, args->offset[1], &y0, &y1, &yw);
1583779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
15840108eae2911d2fc8f2ae0ef0fc6fc503fbfc600dDave Airlie   tx[0] = get_texel_2d_array(sp_sview, sp_samp, addr, x0, y0, layer);
15850108eae2911d2fc8f2ae0ef0fc6fc503fbfc600dDave Airlie   tx[1] = get_texel_2d_array(sp_sview, sp_samp, addr, x1, y0, layer);
15860108eae2911d2fc8f2ae0ef0fc6fc503fbfc600dDave Airlie   tx[2] = get_texel_2d_array(sp_sview, sp_samp, addr, x0, y1, layer);
15870108eae2911d2fc8f2ae0ef0fc6fc503fbfc600dDave Airlie   tx[3] = get_texel_2d_array(sp_sview, sp_samp, addr, x1, y1, layer);
1588779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
158955a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   if (args->gather_only) {
15904b249ed4cd813fa71e3b4a9457b365cc5dcbc3a1Roland Scheidegger      for (c = 0; c < TGSI_NUM_CHANNELS; c++)
159155a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         rgba[TGSI_NUM_CHANNELS*c] = get_gather_value(sp_sview, c,
159255a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie                                                      args->gather_comp,
159355a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie                                                      tx);
159455a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   } else {
159555a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      /* interpolate R, G, B, A */
15964b249ed4cd813fa71e3b4a9457b365cc5dcbc3a1Roland Scheidegger      for (c = 0; c < TGSI_NUM_CHANNELS; c++)
159755a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw,
159855a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie                                             tx[0][c], tx[1][c],
159955a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie                                             tx[2][c], tx[3][c]);
160055a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   }
1601779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul}
1602779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1603779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul
1604779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paulstatic void
1605ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowakimg_filter_cube_linear(const struct sp_sampler_view *sp_sview,
1606ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowak                       const struct sp_sampler *sp_samp,
160799e583120cde8820aae94eb0f8beb723509398fcDave Airlie                       const struct img_filter_args *args,
1608229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                       float *rgba)
1609b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul{
1610ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
16112135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int width = u_minify(texture->width0, args->level);
16122135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int height = u_minify(texture->height0, args->level);
16132135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int layer = sp_sview->base.u.tex.first_layer;
16142135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   int x0, y0, x1, y1;
1615229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float xw, yw; /* weights */
1616adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   union tex_tile_address addr;
16170108eae2911d2fc8f2ae0ef0fc6fc503fbfc600dDave Airlie   const float *tx[4];
1618ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   float corner0[TGSI_QUAD_SIZE], corner1[TGSI_QUAD_SIZE],
1619ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         corner2[TGSI_QUAD_SIZE], corner3[TGSI_QUAD_SIZE];
1620229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
1621b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul
1622b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul   assert(width > 0);
16235dbedf3d7e99efe35fad308d382670e44cd60e25Brian Paul   assert(height > 0);
1624b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul
162581601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   addr.value = 0;
162699e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
162781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
1628621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   /*
1629621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie    * For seamless if LINEAR filtering is done within a miplevel,
1630621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie    * always apply wrap mode CLAMP_TO_BORDER.
1631621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie    */
1632ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   if (sp_samp->base.seamless_cube_map) {
16337681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger      /* Note this is a bit overkill, actual clamping is not required */
16343f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      wrap_linear_clamp_to_border(args->s, width, args->offset[0], &x0, &x1, &xw);
16353f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      wrap_linear_clamp_to_border(args->t, height, args->offset[1], &y0, &y1, &yw);
1636621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   } else {
16377681beedd19cf437252fbc1041b19328ad773ea5Roland Scheidegger      /* Would probably make sense to ignore mode and just do edge clamp */
16383f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      sp_samp->linear_texcoord_s(args->s, width,  args->offset[0], &x0, &x1, &xw);
16393f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      sp_samp->linear_texcoord_t(args->t, height, args->offset[1], &y0, &y1, &yw);
1640621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   }
16414fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1642ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   if (sp_samp->base.seamless_cube_map) {
16430108eae2911d2fc8f2ae0ef0fc6fc503fbfc600dDave Airlie      tx[0] = get_texel_cube_seamless(sp_sview, addr, x0, y0, corner0, layer, args->face_id);
16440108eae2911d2fc8f2ae0ef0fc6fc503fbfc600dDave Airlie      tx[1] = get_texel_cube_seamless(sp_sview, addr, x1, y0, corner1, layer, args->face_id);
16450108eae2911d2fc8f2ae0ef0fc6fc503fbfc600dDave Airlie      tx[2] = get_texel_cube_seamless(sp_sview, addr, x0, y1, corner2, layer, args->face_id);
16460108eae2911d2fc8f2ae0ef0fc6fc503fbfc600dDave Airlie      tx[3] = get_texel_cube_seamless(sp_sview, addr, x1, y1, corner3, layer, args->face_id);
1647621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   } else {
16480108eae2911d2fc8f2ae0ef0fc6fc503fbfc600dDave Airlie      tx[0] = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y0, layer + args->face_id);
16490108eae2911d2fc8f2ae0ef0fc6fc503fbfc600dDave Airlie      tx[1] = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y0, layer + args->face_id);
16500108eae2911d2fc8f2ae0ef0fc6fc503fbfc600dDave Airlie      tx[2] = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y1, layer + args->face_id);
16510108eae2911d2fc8f2ae0ef0fc6fc503fbfc600dDave Airlie      tx[3] = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y1, layer + args->face_id);
1652621259b3de1f15c879620bbf17764fd8a27ae6f5Dave Airlie   }
1653adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger
165455a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   if (args->gather_only) {
16554b249ed4cd813fa71e3b4a9457b365cc5dcbc3a1Roland Scheidegger      for (c = 0; c < TGSI_NUM_CHANNELS; c++)
165655a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         rgba[TGSI_NUM_CHANNELS*c] = get_gather_value(sp_sview, c,
165755a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie                                                      args->gather_comp,
165855a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie                                                      tx);
165955a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   } else {
166055a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      /* interpolate R, G, B, A */
16614b249ed4cd813fa71e3b4a9457b365cc5dcbc3a1Roland Scheidegger      for (c = 0; c < TGSI_NUM_CHANNELS; c++)
166255a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw,
166355a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie                                             tx[0][c], tx[1][c],
166455a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie                                             tx[2][c], tx[3][c]);
166555a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   }
16664fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
16674fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
16684fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
16694fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
1670ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowakimg_filter_cube_array_linear(const struct sp_sampler_view *sp_sview,
1671ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowak                             const struct sp_sampler *sp_samp,
167299e583120cde8820aae94eb0f8beb723509398fcDave Airlie                             const struct img_filter_args *args,
1673309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie                             float *rgba)
1674309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie{
1675ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
16762135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int width = u_minify(texture->width0, args->level);
16772135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int height = u_minify(texture->height0, args->level);
16782135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int layer =
16792135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak      coord_to_layer(6 * args->p + sp_sview->base.u.tex.first_layer,
16802135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak                     sp_sview->base.u.tex.first_layer,
16812135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak                     sp_sview->base.u.tex.last_layer - 5);
16822135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   int x0, y0, x1, y1;
1683309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   float xw, yw; /* weights */
1684aafdc5bda424c2b04f23a54480b402dd64333555Dave Airlie   union tex_tile_address addr;
16850108eae2911d2fc8f2ae0ef0fc6fc503fbfc600dDave Airlie   const float *tx[4];
1686adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   float corner0[TGSI_QUAD_SIZE], corner1[TGSI_QUAD_SIZE],
1687adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger         corner2[TGSI_QUAD_SIZE], corner3[TGSI_QUAD_SIZE];
1688309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   int c;
1689309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie
1690309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   assert(width > 0);
1691309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   assert(height > 0);
1692309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie
1693309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   addr.value = 0;
169499e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
1695309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie
1696adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   /*
1697adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger    * For seamless if LINEAR filtering is done within a miplevel,
1698adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger    * always apply wrap mode CLAMP_TO_BORDER.
1699adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger    */
1700adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   if (sp_samp->base.seamless_cube_map) {
1701adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      /* Note this is a bit overkill, actual clamping is not required */
17023f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      wrap_linear_clamp_to_border(args->s, width, args->offset[0], &x0, &x1, &xw);
17033f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      wrap_linear_clamp_to_border(args->t, height, args->offset[1], &y0, &y1, &yw);
1704adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   } else {
1705adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      /* Would probably make sense to ignore mode and just do edge clamp */
17063f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      sp_samp->linear_texcoord_s(args->s, width,  args->offset[0], &x0, &x1, &xw);
17073f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie      sp_samp->linear_texcoord_t(args->t, height, args->offset[1], &y0, &y1, &yw);
1708adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   }
1709adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger
1710adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   if (sp_samp->base.seamless_cube_map) {
17110108eae2911d2fc8f2ae0ef0fc6fc503fbfc600dDave Airlie      tx[0] = get_texel_cube_seamless(sp_sview, addr, x0, y0, corner0, layer, args->face_id);
17120108eae2911d2fc8f2ae0ef0fc6fc503fbfc600dDave Airlie      tx[1] = get_texel_cube_seamless(sp_sview, addr, x1, y0, corner1, layer, args->face_id);
17130108eae2911d2fc8f2ae0ef0fc6fc503fbfc600dDave Airlie      tx[2] = get_texel_cube_seamless(sp_sview, addr, x0, y1, corner2, layer, args->face_id);
17140108eae2911d2fc8f2ae0ef0fc6fc503fbfc600dDave Airlie      tx[3] = get_texel_cube_seamless(sp_sview, addr, x1, y1, corner3, layer, args->face_id);
1715adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   } else {
17160108eae2911d2fc8f2ae0ef0fc6fc503fbfc600dDave Airlie      tx[0] = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y0, layer + args->face_id);
17170108eae2911d2fc8f2ae0ef0fc6fc503fbfc600dDave Airlie      tx[1] = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y0, layer + args->face_id);
17180108eae2911d2fc8f2ae0ef0fc6fc503fbfc600dDave Airlie      tx[2] = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y1, layer + args->face_id);
17190108eae2911d2fc8f2ae0ef0fc6fc503fbfc600dDave Airlie      tx[3] = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y1, layer + args->face_id);
1720adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   }
1721309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie
172255a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   if (args->gather_only) {
17234b249ed4cd813fa71e3b4a9457b365cc5dcbc3a1Roland Scheidegger      for (c = 0; c < TGSI_NUM_CHANNELS; c++)
172455a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         rgba[TGSI_NUM_CHANNELS*c] = get_gather_value(sp_sview, c,
172555a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie                                                      args->gather_comp,
172655a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie                                                      tx);
172755a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   } else {
172855a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      /* interpolate R, G, B, A */
17294b249ed4cd813fa71e3b4a9457b365cc5dcbc3a1Roland Scheidegger      for (c = 0; c < TGSI_NUM_CHANNELS; c++)
173055a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw,
173155a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie                                             tx[0][c], tx[1][c],
173255a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie                                             tx[2][c], tx[3][c]);
173355a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   }
1734309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie}
1735309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie
1736309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airliestatic void
1737ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowakimg_filter_3d_linear(const struct sp_sampler_view *sp_sview,
1738ea764baa61bec5b4ae15cf0d5928e3643061807dKrzesimir Nowak                     const struct sp_sampler *sp_samp,
173999e583120cde8820aae94eb0f8beb723509398fcDave Airlie                     const struct img_filter_args *args,
1740229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                     float *rgba)
17414fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
1742ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
17432135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int width = u_minify(texture->width0, args->level);
17442135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int height = u_minify(texture->height0, args->level);
17452135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int depth = u_minify(texture->depth0, args->level);
1746229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int x0, x1, y0, y1, z0, z1;
1747229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   float xw, yw, zw; /* interpolation weights */
174881601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   union tex_tile_address addr;
1749229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   const float *tx00, *tx01, *tx02, *tx03, *tx10, *tx11, *tx12, *tx13;
1750229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int c;
17514fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
175281601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell   addr.value = 0;
175399e583120cde8820aae94eb0f8beb723509398fcDave Airlie   addr.bits.level = args->level;
175481601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
17554fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   assert(width > 0);
17564fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   assert(height > 0);
17574fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   assert(depth > 0);
17584fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
17593f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->linear_texcoord_s(args->s, width,  args->offset[0], &x0, &x1, &xw);
17603f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->linear_texcoord_t(args->t, height, args->offset[1], &y0, &y1, &yw);
17613f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   sp_samp->linear_texcoord_p(args->p, depth,  args->offset[2], &z0, &z1, &zw);
17624fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
1763ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx00 = get_texel_3d(sp_sview, sp_samp, addr, x0, y0, z0);
1764ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx01 = get_texel_3d(sp_sview, sp_samp, addr, x1, y0, z0);
1765ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx02 = get_texel_3d(sp_sview, sp_samp, addr, x0, y1, z0);
1766ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx03 = get_texel_3d(sp_sview, sp_samp, addr, x1, y1, z0);
176781601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
1768ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx10 = get_texel_3d(sp_sview, sp_samp, addr, x0, y0, z1);
1769ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx11 = get_texel_3d(sp_sview, sp_samp, addr, x1, y0, z1);
1770ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx12 = get_texel_3d(sp_sview, sp_samp, addr, x0, y1, z1);
1771ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   tx13 = get_texel_3d(sp_sview, sp_samp, addr, x1, y1, z1);
177281601d85ef6b82297b046d5aab1b70e75168c2faKeith Whitwell
17734fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      /* interpolate R, G, B, A */
17744b249ed4cd813fa71e3b4a9457b365cc5dcbc3a1Roland Scheidegger   for (c = 0; c < TGSI_NUM_CHANNELS; c++)
1775229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      rgba[TGSI_NUM_CHANNELS*c] =  lerp_3d(xw, yw, zw,
1776229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                           tx00[c], tx01[c],
1777229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                           tx02[c], tx03[c],
1778229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                           tx10[c], tx11[c],
1779229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                                           tx12[c], tx13[c]);
17804fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
17814fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
17824fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
178375d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger/* Calculate level of detail for every fragment,
178475d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger * with lambda already computed.
17854bfe1c955fe679547c8a03119d1681e33593c768Michal Krol * Note that lambda has already been biased by global LOD bias.
178675d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger * \param biased_lambda per-quad lambda.
178775d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger * \param lod_in per-fragment lod_bias or explicit_lod.
178875d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger * \param lod returns the per-fragment lod.
17894bfe1c955fe679547c8a03119d1681e33593c768Michal Krol */
1790a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline void
17914bfe1c955fe679547c8a03119d1681e33593c768Michal Krolcompute_lod(const struct pipe_sampler_state *sampler,
179275d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger            enum tgsi_sampler_control control,
17934bfe1c955fe679547c8a03119d1681e33593c768Michal Krol            const float biased_lambda,
179475d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger            const float lod_in[TGSI_QUAD_SIZE],
17956b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard            float lod[TGSI_QUAD_SIZE])
17964bfe1c955fe679547c8a03119d1681e33593c768Michal Krol{
17972135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float min_lod = sampler->min_lod;
17982135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float max_lod = sampler->max_lod;
17994bfe1c955fe679547c8a03119d1681e33593c768Michal Krol   uint i;
18004bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
180175d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger   switch (control) {
18022c52c794d727e535c1baca671a7c1e5b38dffb00Brian Paul   case TGSI_SAMPLER_LOD_NONE:
18032c52c794d727e535c1baca671a7c1e5b38dffb00Brian Paul   case TGSI_SAMPLER_LOD_ZERO:
18046ace2e41da7dded630d932d03bacb7e14a93d47aRoland Scheidegger   /* XXX FIXME */
18052c52c794d727e535c1baca671a7c1e5b38dffb00Brian Paul   case TGSI_SAMPLER_DERIVS_EXPLICIT:
180675d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      lod[0] = lod[1] = lod[2] = lod[3] = CLAMP(biased_lambda, min_lod, max_lod);
180775d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      break;
18082c52c794d727e535c1baca671a7c1e5b38dffb00Brian Paul   case TGSI_SAMPLER_LOD_BIAS:
180975d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      for (i = 0; i < TGSI_QUAD_SIZE; i++) {
181075d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger         lod[i] = biased_lambda + lod_in[i];
181175d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger         lod[i] = CLAMP(lod[i], min_lod, max_lod);
181275d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      }
181375d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      break;
18142c52c794d727e535c1baca671a7c1e5b38dffb00Brian Paul   case TGSI_SAMPLER_LOD_EXPLICIT:
181575d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      for (i = 0; i < TGSI_QUAD_SIZE; i++) {
181675d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger         lod[i] = CLAMP(lod_in[i], min_lod, max_lod);
181775d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      }
181875d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      break;
181975d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger   default:
182075d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      assert(0);
182175d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      lod[0] = lod[1] = lod[2] = lod[3] = 0.0f;
182275d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger   }
182375d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger}
182475d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger
182575d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger
182616084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak/* Calculate level of detail for every fragment. The computed value is not
182716084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak * clamped to lod_min and lod_max.
182875d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger * \param lod_in per-fragment lod_bias or explicit_lod.
182975d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger * \param lod results per-fragment lod.
183075d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger */
1831a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline void
1832ea0fecd1a3f46439c602e04870b34e6f27ad5b2eKrzesimir Nowakcompute_lambda_lod_unclamped(const struct sp_sampler_view *sp_sview,
1833ea0fecd1a3f46439c602e04870b34e6f27ad5b2eKrzesimir Nowak                             const struct sp_sampler *sp_samp,
183416084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak                             const float s[TGSI_QUAD_SIZE],
183516084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak                             const float t[TGSI_QUAD_SIZE],
183616084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak                             const float p[TGSI_QUAD_SIZE],
183716084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak                             const float lod_in[TGSI_QUAD_SIZE],
183816084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak                             enum tgsi_sampler_control control,
183916084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak                             float lod[TGSI_QUAD_SIZE])
184075d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger{
1841ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_sampler_state *sampler = &sp_samp->base;
184216084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak   const float lod_bias = sampler->lod_bias;
184375d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger   float lambda;
184475d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger   uint i;
184575d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger
184675d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger   switch (control) {
18472c52c794d727e535c1baca671a7c1e5b38dffb00Brian Paul   case TGSI_SAMPLER_LOD_NONE:
18486ace2e41da7dded630d932d03bacb7e14a93d47aRoland Scheidegger      /* XXX FIXME */
18492c52c794d727e535c1baca671a7c1e5b38dffb00Brian Paul   case TGSI_SAMPLER_DERIVS_EXPLICIT:
1850ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      lambda = sp_sview->compute_lambda(sp_sview, s, t, p) + lod_bias;
185116084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak      lod[0] = lod[1] = lod[2] = lod[3] = lambda;
185275d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      break;
18532c52c794d727e535c1baca671a7c1e5b38dffb00Brian Paul   case TGSI_SAMPLER_LOD_BIAS:
1854ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      lambda = sp_sview->compute_lambda(sp_sview, s, t, p) + lod_bias;
185575d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      for (i = 0; i < TGSI_QUAD_SIZE; i++) {
185675d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger         lod[i] = lambda + lod_in[i];
185775d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      }
185875d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      break;
18592c52c794d727e535c1baca671a7c1e5b38dffb00Brian Paul   case TGSI_SAMPLER_LOD_EXPLICIT:
186075d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      for (i = 0; i < TGSI_QUAD_SIZE; i++) {
186116084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak         lod[i] = lod_in[i] + lod_bias;
186275d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      }
186375d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      break;
18642c52c794d727e535c1baca671a7c1e5b38dffb00Brian Paul   case TGSI_SAMPLER_LOD_ZERO:
18652c52c794d727e535c1baca671a7c1e5b38dffb00Brian Paul   case TGSI_SAMPLER_GATHER:
186616084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak      lod[0] = lod[1] = lod[2] = lod[3] = lod_bias;
186775d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      break;
186875d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger   default:
186975d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      assert(0);
187075d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger      lod[0] = lod[1] = lod[2] = lod[3] = 0.0f;
18714bfe1c955fe679547c8a03119d1681e33593c768Michal Krol   }
18724bfe1c955fe679547c8a03119d1681e33593c768Michal Krol}
18734bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
187416084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak/* Calculate level of detail for every fragment.
187516084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak * \param lod_in per-fragment lod_bias or explicit_lod.
187616084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak * \param lod results per-fragment lod.
187716084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak */
187816084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowakstatic inline void
1879ac23116de56e163a3815626277f9c3691bb56831Krzesimir Nowakcompute_lambda_lod(const struct sp_sampler_view *sp_sview,
1880ac23116de56e163a3815626277f9c3691bb56831Krzesimir Nowak                   const struct sp_sampler *sp_samp,
188116084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak                   const float s[TGSI_QUAD_SIZE],
188216084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak                   const float t[TGSI_QUAD_SIZE],
188316084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak                   const float p[TGSI_QUAD_SIZE],
188416084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak                   const float lod_in[TGSI_QUAD_SIZE],
188516084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak                   enum tgsi_sampler_control control,
188616084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak                   float lod[TGSI_QUAD_SIZE])
188716084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak{
188816084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak   const struct pipe_sampler_state *sampler = &sp_samp->base;
188916084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak   const float min_lod = sampler->min_lod;
189016084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak   const float max_lod = sampler->max_lod;
189116084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak   int i;
189216084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak
189316084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak   compute_lambda_lod_unclamped(sp_sview, sp_samp,
189416084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak                                s, t, p, lod_in, control, lod);
189516084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak   for (i = 0; i < TGSI_QUAD_SIZE; i++) {
189616084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak      lod[i] = CLAMP(lod[i], min_lod, max_lod);
189716084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak   }
189816084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak}
189916084cd2cf055849933e19047e604d384da81f8eKrzesimir Nowak
1900a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline unsigned
190155a7b5165d40b831fd303079f8f80962d195d6eeDave Airlieget_gather_component(const float lod_in[TGSI_QUAD_SIZE])
190255a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie{
190355a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   /* gather component is stored in lod_in slot as unsigned */
190455a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   return (*(unsigned int *)lod_in) & 0x3;
190555a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie}
19064bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
1907d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak/**
1908d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak * Clamps given lod to both lod limits and mip level limits. Clamping to the
1909d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak * latter limits is done so that lod is relative to the first (base) level.
1910d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak */
1911d71a3be86008c275b5902de7759385643546a210Krzesimir Nowakstatic void
1912d71a3be86008c275b5902de7759385643546a210Krzesimir Nowakclamp_lod(const struct sp_sampler_view *sp_sview,
1913d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak          const struct sp_sampler *sp_samp,
1914d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak          const float lod[TGSI_QUAD_SIZE],
1915d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak          float clamped[TGSI_QUAD_SIZE])
1916d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak{
1917d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak   const float min_lod = sp_samp->base.min_lod;
1918d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak   const float max_lod = sp_samp->base.max_lod;
1919d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak   const float min_level = sp_sview->base.u.tex.first_level;
1920d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak   const float max_level = sp_sview->base.u.tex.last_level;
1921d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak   int i;
1922d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak
1923d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak   for (i = 0; i < TGSI_QUAD_SIZE; i++) {
1924d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak      float cl = lod[i];
1925d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak
1926d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak      cl = CLAMP(cl, min_lod, max_lod);
1927d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak      cl = CLAMP(cl, 0, max_level - min_level);
1928d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak      clamped[i] = cl;
1929d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak   }
1930d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak}
1931d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak
1932d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak/**
1933d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak * Get mip level relative to base level for linear mip filter
1934d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak */
1935d71a3be86008c275b5902de7759385643546a210Krzesimir Nowakstatic void
1936ea0fecd1a3f46439c602e04870b34e6f27ad5b2eKrzesimir Nowakmip_rel_level_linear(const struct sp_sampler_view *sp_sview,
1937ea0fecd1a3f46439c602e04870b34e6f27ad5b2eKrzesimir Nowak                     const struct sp_sampler *sp_samp,
1938d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak                     const float lod[TGSI_QUAD_SIZE],
1939d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak                     float level[TGSI_QUAD_SIZE])
1940d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak{
1941d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak   clamp_lod(sp_sview, sp_samp, lod, level);
1942d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak}
1943d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak
19444fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
1945ac23116de56e163a3815626277f9c3691bb56831Krzesimir Nowakmip_filter_linear(const struct sp_sampler_view *sp_sview,
1946ac23116de56e163a3815626277f9c3691bb56831Krzesimir Nowak                  const struct sp_sampler *sp_samp,
1947ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                  img_filter_func min_filter,
1948ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                  img_filter_func mag_filter,
19496b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float s[TGSI_QUAD_SIZE],
19506b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float t[TGSI_QUAD_SIZE],
19516b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float p[TGSI_QUAD_SIZE],
19526b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float c0[TGSI_QUAD_SIZE],
195375d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger                  const float lod_in[TGSI_QUAD_SIZE],
19548bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie                  const struct filter_args *filt_args,
19556b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
19564fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
1957b1c1c7d31b3ad625243616597028e7d599eb8190Roland Scheidegger   const struct pipe_sampler_view *psview = &sp_sview->base;
1958229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int j;
19596b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float lod[TGSI_QUAD_SIZE];
196099e583120cde8820aae94eb0f8beb723509398fcDave Airlie   struct img_filter_args args;
19614fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
19628bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie   compute_lambda_lod(sp_sview, sp_samp, s, t, p, lod_in, filt_args->control, lod);
19634bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
19643f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   args.offset = filt_args->offset;
19652c52c794d727e535c1baca671a7c1e5b38dffb00Brian Paul   args.gather_only = filt_args->control == TGSI_SAMPLER_GATHER;
196655a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   args.gather_comp = get_gather_component(lod_in);
19673f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie
1968229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
19692135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak      const int level0 = psview->u.tex.first_level + (int)lod[j];
19704fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
197199e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.s = s[j];
197299e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.t = t[j];
197399e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.p = p[j];
19744ca2896e8ea1908ea5a0d5bffe8a1b42145a6f72Krzesimir Nowak      args.face_id = filt_args->faces[j];
19754fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
197699e583120cde8820aae94eb0f8beb723509398fcDave Airlie      if (lod[j] < 0.0) {
197799e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.level = psview->u.tex.first_level;
197899e583120cde8820aae94eb0f8beb723509398fcDave Airlie         mag_filter(sp_sview, sp_samp, &args, &rgba[0][j]);
197999e583120cde8820aae94eb0f8beb723509398fcDave Airlie      }
198099e583120cde8820aae94eb0f8beb723509398fcDave Airlie      else if (level0 >= (int) psview->u.tex.last_level) {
198199e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.level = psview->u.tex.last_level;
198299e583120cde8820aae94eb0f8beb723509398fcDave Airlie         min_filter(sp_sview, sp_samp, &args, &rgba[0][j]);
198399e583120cde8820aae94eb0f8beb723509398fcDave Airlie      }
1984229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      else {
1985229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         float levelBlend = frac(lod[j]);
1986229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         float rgbax[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
1987229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         int c;
1988229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert
198999e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.level = level0;
199099e583120cde8820aae94eb0f8beb723509398fcDave Airlie         min_filter(sp_sview, sp_samp, &args, &rgbax[0][0]);
199199e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.level = level0+1;
199299e583120cde8820aae94eb0f8beb723509398fcDave Airlie         min_filter(sp_sview, sp_samp, &args, &rgbax[0][1]);
19934fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
19944fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         for (c = 0; c < 4; c++) {
1995229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert            rgba[c][j] = lerp(levelBlend, rgbax[c][0], rgbax[c][1]);
1996b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul         }
1997b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul      }
1998b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul   }
19994250882ccf8326ba9074c671110370534489caa6Brian Paul
20004250882ccf8326ba9074c671110370534489caa6Brian Paul   if (DEBUG_TEX) {
2001229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      print_sample_4(__FUNCTION__, rgba);
20024250882ccf8326ba9074c671110370534489caa6Brian Paul   }
2003b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul}
2004b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul
2005b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul
200685425b3b609c480cd024b217b1efd0b9153bed58Brian Paul/**
2007d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak * Get mip level relative to base level for nearest mip filter
2008d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak */
2009d71a3be86008c275b5902de7759385643546a210Krzesimir Nowakstatic void
2010ea0fecd1a3f46439c602e04870b34e6f27ad5b2eKrzesimir Nowakmip_rel_level_nearest(const struct sp_sampler_view *sp_sview,
2011ea0fecd1a3f46439c602e04870b34e6f27ad5b2eKrzesimir Nowak                      const struct sp_sampler *sp_samp,
2012d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak                      const float lod[TGSI_QUAD_SIZE],
2013d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak                      float level[TGSI_QUAD_SIZE])
2014d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak{
2015d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak   int j;
2016d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak
2017d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak   clamp_lod(sp_sview, sp_samp, lod, level);
2018d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak   for (j = 0; j < TGSI_QUAD_SIZE; j++)
2019d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak      /* TODO: It should rather be:
2020d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak       * level[j] = ceil(level[j] + 0.5F) - 1.0F;
2021d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak       */
2022d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak      level[j] = (int)(level[j] + 0.5F);
2023d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak}
2024d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak
2025d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak/**
202685425b3b609c480cd024b217b1efd0b9153bed58Brian Paul * Compute nearest mipmap level from texcoords.
202785425b3b609c480cd024b217b1efd0b9153bed58Brian Paul * Then sample the texture level for four elements of a quad.
202885425b3b609c480cd024b217b1efd0b9153bed58Brian Paul * \param c0  the LOD bias factors, or absolute LODs (depending on control)
202985425b3b609c480cd024b217b1efd0b9153bed58Brian Paul */
20304fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
2031ac23116de56e163a3815626277f9c3691bb56831Krzesimir Nowakmip_filter_nearest(const struct sp_sampler_view *sp_sview,
2032ac23116de56e163a3815626277f9c3691bb56831Krzesimir Nowak                   const 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],
20386b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                   const float c0[TGSI_QUAD_SIZE],
203975d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger                   const float lod_in[TGSI_QUAD_SIZE],
20408bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie                   const struct filter_args *filt_args,
20416b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                   float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
20424fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
2043b1c1c7d31b3ad625243616597028e7d599eb8190Roland Scheidegger   const struct pipe_sampler_view *psview = &sp_sview->base;
20446b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float lod[TGSI_QUAD_SIZE];
2045229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int j;
204699e583120cde8820aae94eb0f8beb723509398fcDave Airlie   struct img_filter_args args;
20473f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie
20483f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   args.offset = filt_args->offset;
20492c52c794d727e535c1baca671a7c1e5b38dffb00Brian Paul   args.gather_only = filt_args->control == TGSI_SAMPLER_GATHER;
205055a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   args.gather_comp = get_gather_component(lod_in);
205155a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie
20528bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie   compute_lambda_lod(sp_sview, sp_samp, s, t, p, lod_in, filt_args->control, lod);
20534bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
2054229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
205599e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.s = s[j];
205699e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.t = t[j];
205799e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.p = p[j];
20584ca2896e8ea1908ea5a0d5bffe8a1b42145a6f72Krzesimir Nowak      args.face_id = filt_args->faces[j];
205999e583120cde8820aae94eb0f8beb723509398fcDave Airlie
206099e583120cde8820aae94eb0f8beb723509398fcDave Airlie      if (lod[j] < 0.0) {
206199e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.level = psview->u.tex.first_level;
206299e583120cde8820aae94eb0f8beb723509398fcDave Airlie         mag_filter(sp_sview, sp_samp, &args, &rgba[0][j]);
206399e583120cde8820aae94eb0f8beb723509398fcDave Airlie      } else {
20642135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak         const int level = psview->u.tex.first_level + (int)(lod[j] + 0.5F);
206599e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.level = MIN2(level, (int)psview->u.tex.last_level);
206699e583120cde8820aae94eb0f8beb723509398fcDave Airlie         min_filter(sp_sview, sp_samp, &args, &rgba[0][j]);
2067229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      }
20684fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   }
206975276ea316610a5737f2115326482024aa09d02aBrian Paul
20704250882ccf8326ba9074c671110370534489caa6Brian Paul   if (DEBUG_TEX) {
2071229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      print_sample_4(__FUNCTION__, rgba);
20724250882ccf8326ba9074c671110370534489caa6Brian Paul   }
20734fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
20744fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
20754fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
2076d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak/**
2077d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak * Get mip level relative to base level for none mip filter
2078d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak */
2079d71a3be86008c275b5902de7759385643546a210Krzesimir Nowakstatic void
2080ea0fecd1a3f46439c602e04870b34e6f27ad5b2eKrzesimir Nowakmip_rel_level_none(const struct sp_sampler_view *sp_sview,
2081ea0fecd1a3f46439c602e04870b34e6f27ad5b2eKrzesimir Nowak                   const struct sp_sampler *sp_samp,
2082d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak                   const float lod[TGSI_QUAD_SIZE],
2083d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak                   float level[TGSI_QUAD_SIZE])
2084d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak{
2085d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak   int j;
2086d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak
2087d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
2088d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak      level[j] = 0;
2089d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak   }
2090d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak}
2091d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak
20924fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
2093ac23116de56e163a3815626277f9c3691bb56831Krzesimir Nowakmip_filter_none(const struct sp_sampler_view *sp_sview,
2094ac23116de56e163a3815626277f9c3691bb56831Krzesimir Nowak                const struct sp_sampler *sp_samp,
2095ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                img_filter_func min_filter,
2096ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                img_filter_func mag_filter,
20976b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                const float s[TGSI_QUAD_SIZE],
20986b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                const float t[TGSI_QUAD_SIZE],
20996b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                const float p[TGSI_QUAD_SIZE],
21006b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                const float c0[TGSI_QUAD_SIZE],
210175d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger                const float lod_in[TGSI_QUAD_SIZE],
21028bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie                const struct filter_args *filt_args,
21036b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
21044fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
21056b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float lod[TGSI_QUAD_SIZE];
2106229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int j;
210799e583120cde8820aae94eb0f8beb723509398fcDave Airlie   struct img_filter_args args;
21084bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
210999e583120cde8820aae94eb0f8beb723509398fcDave Airlie   args.level = sp_sview->base.u.tex.first_level;
21103f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   args.offset = filt_args->offset;
21112c52c794d727e535c1baca671a7c1e5b38dffb00Brian Paul   args.gather_only = filt_args->control == TGSI_SAMPLER_GATHER;
21123f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie
21138bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie   compute_lambda_lod(sp_sview, sp_samp, s, t, p, lod_in, filt_args->control, lod);
21144bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
2115229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
211699e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.s = s[j];
211799e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.t = t[j];
211899e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.p = p[j];
21194ca2896e8ea1908ea5a0d5bffe8a1b42145a6f72Krzesimir Nowak      args.face_id = filt_args->faces[j];
212099e583120cde8820aae94eb0f8beb723509398fcDave Airlie      if (lod[j] < 0.0) {
212199e583120cde8820aae94eb0f8beb723509398fcDave Airlie         mag_filter(sp_sview, sp_samp, &args, &rgba[0][j]);
2122229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      }
2123229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      else {
212499e583120cde8820aae94eb0f8beb723509398fcDave Airlie         min_filter(sp_sview, sp_samp, &args, &rgba[0][j]);
2125229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      }
21264fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   }
21274fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell}
21284fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
21294fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
2130d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak/**
2131d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak * Get mip level relative to base level for none mip filter
2132d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak */
2133d71a3be86008c275b5902de7759385643546a210Krzesimir Nowakstatic void
2134ea0fecd1a3f46439c602e04870b34e6f27ad5b2eKrzesimir Nowakmip_rel_level_none_no_filter_select(const struct sp_sampler_view *sp_sview,
2135ea0fecd1a3f46439c602e04870b34e6f27ad5b2eKrzesimir Nowak                                    const struct sp_sampler *sp_samp,
2136d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak                                    const float lod[TGSI_QUAD_SIZE],
2137d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak                                    float level[TGSI_QUAD_SIZE])
2138d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak{
2139d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak   mip_rel_level_none(sp_sview, sp_samp, lod, level);
2140d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak}
2141d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak
2142229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertstatic void
2143ac23116de56e163a3815626277f9c3691bb56831Krzesimir Nowakmip_filter_none_no_filter_select(const struct sp_sampler_view *sp_sview,
2144ac23116de56e163a3815626277f9c3691bb56831Krzesimir Nowak                                 const struct sp_sampler *sp_samp,
2145ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                                 img_filter_func min_filter,
2146ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                                 img_filter_func mag_filter,
2147ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                                 const float s[TGSI_QUAD_SIZE],
2148ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                                 const float t[TGSI_QUAD_SIZE],
2149ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                                 const float p[TGSI_QUAD_SIZE],
2150ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                                 const float c0[TGSI_QUAD_SIZE],
2151ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                                 const float lod_in[TGSI_QUAD_SIZE],
21528bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie                                 const struct filter_args *filt_args,
2153ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                                 float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
2154229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert{
2155229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int j;
215699e583120cde8820aae94eb0f8beb723509398fcDave Airlie   struct img_filter_args args;
215799e583120cde8820aae94eb0f8beb723509398fcDave Airlie   args.level = sp_sview->base.u.tex.first_level;
21583f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   args.offset = filt_args->offset;
21592c52c794d727e535c1baca671a7c1e5b38dffb00Brian Paul   args.gather_only = filt_args->control == TGSI_SAMPLER_GATHER;
216099e583120cde8820aae94eb0f8beb723509398fcDave Airlie   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
216199e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.s = s[j];
216299e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.t = t[j];
216399e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.p = p[j];
21644ca2896e8ea1908ea5a0d5bffe8a1b42145a6f72Krzesimir Nowak      args.face_id = filt_args->faces[j];
216599e583120cde8820aae94eb0f8beb723509398fcDave Airlie      mag_filter(sp_sview, sp_samp, &args, &rgba[0][j]);
216699e583120cde8820aae94eb0f8beb723509398fcDave Airlie   }
2167229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert}
2168229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert
2169229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert
2170f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger/* For anisotropic filtering */
2171f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger#define WEIGHT_LUT_SIZE 1024
2172f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
21732135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowakstatic const float *weightLut = NULL;
2174f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2175f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger/**
2176f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger * Creates the look-up table used to speed-up EWA sampling
2177f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger */
2178f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fängerstatic void
2179f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fängercreate_filter_table(void)
2180f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger{
2181f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   unsigned i;
2182f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   if (!weightLut) {
21832135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak      float *lut = (float *) MALLOC(WEIGHT_LUT_SIZE * sizeof(float));
2184f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2185f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      for (i = 0; i < WEIGHT_LUT_SIZE; ++i) {
21862135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak         const float alpha = 2;
21872135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak         const float r2 = (float) i / (float) (WEIGHT_LUT_SIZE - 1);
21882135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak         const float weight = (float) exp(-alpha * r2);
21892135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak         lut[i] = weight;
2190f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      }
21912135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak      weightLut = lut;
2192f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   }
2193f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger}
2194f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2195f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2196f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger/**
2197f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger * Elliptical weighted average (EWA) filter for producing high quality
2198f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger * anisotropic filtered results.
2199229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert * Based on the Higher Quality Elliptical Weighted Average Filter
2200f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger * published by Paul S. Heckbert in his Master's Thesis
2201f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger * "Fundamentals of Texture Mapping and Image Warping" (1989)
2202f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger */
2203f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fängerstatic void
2204ac23116de56e163a3815626277f9c3691bb56831Krzesimir Nowakimg_filter_2d_ewa(const struct sp_sampler_view *sp_sview,
2205ac23116de56e163a3815626277f9c3691bb56831Krzesimir Nowak                  const struct sp_sampler *sp_samp,
2206ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                  img_filter_func min_filter,
2207ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                  img_filter_func mag_filter,
22086b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float s[TGSI_QUAD_SIZE],
22096b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float t[TGSI_QUAD_SIZE],
22106b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  const float p[TGSI_QUAD_SIZE],
221108ceb5e076328bf6ccceed3a8e5de205dcaf63b0Krzesimir Nowak                  const uint faces[TGSI_QUAD_SIZE],
22129e9d69979c7aff7dac2d670af950f4a50273bcdeRoland Scheidegger                  const int8_t *offset,
2213229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert                  unsigned level,
2214f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                  const float dudx, const float dvdx,
2215f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                  const float dudy, const float dvdy,
22166b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                  float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
2217f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger{
2218ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
2219f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2220229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   // ??? Won't the image filters blow up if level is negative?
22212135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const unsigned level0 = level > 0 ? level : 0;
22222135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float scaling = 1.0f / (1 << level0);
22232135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int width = u_minify(texture->width0, level0);
22242135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int height = u_minify(texture->height0, level0);
222599e583120cde8820aae94eb0f8beb723509398fcDave Airlie   struct img_filter_args args;
22262135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float ux = dudx * scaling;
22272135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float vx = dvdx * scaling;
22282135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float uy = dudy * scaling;
22292135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float vy = dvdy * scaling;
2230f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2231f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   /* compute ellipse coefficients to bound the region:
2232f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger    * A*x*x + B*x*y + C*y*y = F.
2233f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger    */
2234f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   float A = vx*vx+vy*vy+1;
2235f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   float B = -2*(ux*vx+uy*vy);
2236f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   float C = ux*ux+uy*uy+1;
223710393038f8d8279aca53df020c608f205e624043Brian Paul   float F = A*C-B*B/4.0f;
2238f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2239f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   /* check if it is an ellipse */
2240bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   /* assert(F > 0.0); */
2241f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2242f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   /* Compute the ellipse's (u,v) bounding box in texture space */
22432135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float d = -B*B+4.0f*C*A;
22442135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float box_u = 2.0f / d * sqrtf(d*C*F); /* box_u -> half of bbox with   */
22452135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float box_v = 2.0f / d * sqrtf(A*d*F); /* box_v -> half of bbox height */
2246f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
22476b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float rgba_temp[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
22486b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float s_buffer[TGSI_QUAD_SIZE];
22496b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float t_buffer[TGSI_QUAD_SIZE];
22506b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float weight_buffer[TGSI_QUAD_SIZE];
2251f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   int j;
2252f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2253f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   /* For each quad, the du and dx values are the same and so the ellipse is
2254f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger    * also the same. Note that texel/image access can only be performed using
2255f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger    * a quad, i.e. it is not possible to get the pixel value for a single
2256f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger    * tex coord. In order to have a better performance, the access is buffered
2257b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul    * using the s_buffer/t_buffer and weight_buffer. Only when the buffer is
2258b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul    * full, then the pixel values are read from the image.
2259f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger    */
22602135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float ddq = 2 * A;
22612135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak
22622135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   /* Scale ellipse formula to directly index the Filter Lookup Table.
22632135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak    * i.e. scale so that F = WEIGHT_LUT_SIZE-1
22642135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak    */
22652135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const double formScale = (double) (WEIGHT_LUT_SIZE - 1) / F;
22662135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   A *= formScale;
22672135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   B *= formScale;
22682135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   C *= formScale;
22692135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   /* F *= formScale; */ /* no need to scale F as we don't use it below here */
227099e583120cde8820aae94eb0f8beb723509398fcDave Airlie
227199e583120cde8820aae94eb0f8beb723509398fcDave Airlie   args.level = level;
22729e9d69979c7aff7dac2d670af950f4a50273bcdeRoland Scheidegger   args.offset = offset;
22739e9d69979c7aff7dac2d670af950f4a50273bcdeRoland Scheidegger
22746b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
2275f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      /* Heckbert MS thesis, p. 59; scan over the bounding box of the ellipse
2276f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger       * and incrementally update the value of Ax^2+Bxy*Cy^2; when this
2277f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger       * value, q, is less than F, we're inside the ellipse
2278f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger       */
22792135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak      const float tex_u = -0.5F + s[j] * texture->width0 * scaling;
22802135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak      const float tex_v = -0.5F + t[j] * texture->height0 * scaling;
2281f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
22822135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak      const int u0 = (int) floorf(tex_u - box_u);
22832135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak      const int u1 = (int) ceilf(tex_u + box_u);
22842135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak      const int v0 = (int) floorf(tex_v - box_v);
22852135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak      const int v1 = (int) ceilf(tex_v + box_v);
22862135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak      const float U = u0 - tex_u;
2287f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2288f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      float num[4] = {0.0F, 0.0F, 0.0F, 0.0F};
22892135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak      unsigned buffer_next = 0;
22902135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak      float den = 0;
22912135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak      int v;
22924ca2896e8ea1908ea5a0d5bffe8a1b42145a6f72Krzesimir Nowak      args.face_id = faces[j];
229399e583120cde8820aae94eb0f8beb723509398fcDave Airlie
2294f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      for (v = v0; v <= v1; ++v) {
22952135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak         const float V = v - tex_v;
2296f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         float dq = A * (2 * U + 1) + B * V;
2297f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         float q = (C * V + B * U) * V + A * U * U;
2298f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2299f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         int u;
2300f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         for (u = u0; u <= u1; ++u) {
2301b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul            /* Note that the ellipse has been pre-scaled so F =
2302b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul             * WEIGHT_LUT_SIZE - 1
2303b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul             */
2304f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger            if (q < WEIGHT_LUT_SIZE) {
2305f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger               /* as a LUT is used, q must never be negative;
2306f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                * should not happen, though
2307f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                */
2308f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger               const int qClamped = q >= 0.0F ? q : 0;
23092135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak               const float weight = weightLut[qClamped];
2310f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2311f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger               weight_buffer[buffer_next] = weight;
2312f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger               s_buffer[buffer_next] = u / ((float) width);
2313f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger               t_buffer[buffer_next] = v / ((float) height);
2314f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2315f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger               buffer_next++;
23166b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard               if (buffer_next == TGSI_QUAD_SIZE) {
2317f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                  /* 4 texel coords are in the buffer -> read it now */
2318b82db9a3c0a1b96d8eb5d0d78aecaf0ab331431aBrian Paul                  unsigned jj;
2319f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                  /* it is assumed that samp->min_img_filter is set to
2320f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                   * img_filter_2d_nearest or one of the
2321f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                   * accelerated img_filter_2d_nearest_XXX functions.
2322f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                   */
2323f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                  for (jj = 0; jj < buffer_next; jj++) {
232499e583120cde8820aae94eb0f8beb723509398fcDave Airlie                     args.s = s_buffer[jj];
232599e583120cde8820aae94eb0f8beb723509398fcDave Airlie                     args.t = t_buffer[jj];
232699e583120cde8820aae94eb0f8beb723509398fcDave Airlie                     args.p = p[jj];
232799e583120cde8820aae94eb0f8beb723509398fcDave Airlie                     min_filter(sp_sview, sp_samp, &args, &rgba_temp[0][jj]);
2328f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                     num[0] += weight_buffer[jj] * rgba_temp[0][jj];
2329f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                     num[1] += weight_buffer[jj] * rgba_temp[1][jj];
2330f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                     num[2] += weight_buffer[jj] * rgba_temp[2][jj];
2331f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                     num[3] += weight_buffer[jj] * rgba_temp[3][jj];
2332f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                  }
2333f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2334f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger                  buffer_next = 0;
2335f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger               }
2336f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2337f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger               den += weight;
2338f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger            }
2339f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger            q += dq;
2340f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger            dq += ddq;
2341f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         }
2342f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      }
2343f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2344b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul      /* if the tex coord buffer contains unread values, we will read
2345229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert       * them now.
2346f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger       */
2347f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      if (buffer_next > 0) {
2348b82db9a3c0a1b96d8eb5d0d78aecaf0ab331431aBrian Paul         unsigned jj;
2349f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         /* it is assumed that samp->min_img_filter is set to
2350f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger          * img_filter_2d_nearest or one of the
2351f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger          * accelerated img_filter_2d_nearest_XXX functions.
2352f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger          */
2353f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         for (jj = 0; jj < buffer_next; jj++) {
235499e583120cde8820aae94eb0f8beb723509398fcDave Airlie            args.s = s_buffer[jj];
235599e583120cde8820aae94eb0f8beb723509398fcDave Airlie            args.t = t_buffer[jj];
235699e583120cde8820aae94eb0f8beb723509398fcDave Airlie            args.p = p[jj];
235799e583120cde8820aae94eb0f8beb723509398fcDave Airlie            min_filter(sp_sview, sp_samp, &args, &rgba_temp[0][jj]);
2358f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger            num[0] += weight_buffer[jj] * rgba_temp[0][jj];
2359f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger            num[1] += weight_buffer[jj] * rgba_temp[1][jj];
2360f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger            num[2] += weight_buffer[jj] * rgba_temp[2][jj];
2361f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger            num[3] += weight_buffer[jj] * rgba_temp[3][jj];
2362f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         }
2363f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      }
2364f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2365f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      if (den <= 0.0F) {
2366b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul         /* Reaching this place would mean that no pixels intersected
2367b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul          * the ellipse.  This should never happen because the filter
2368b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul          * we use always intersects at least one pixel.
2369f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger          */
2370f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2371f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         /*rgba[0]=0;
2372f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         rgba[1]=0;
2373f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         rgba[2]=0;
2374f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         rgba[3]=0;*/
2375f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         /* not enough pixels in resampling, resort to direct interpolation */
237699e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.s = s[j];
237799e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.t = t[j];
237899e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.p = p[j];
237999e583120cde8820aae94eb0f8beb723509398fcDave Airlie         min_filter(sp_sview, sp_samp, &args, &rgba_temp[0][j]);
2380f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         den = 1;
2381f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         num[0] = rgba_temp[0][j];
2382f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         num[1] = rgba_temp[1][j];
2383f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         num[2] = rgba_temp[2][j];
2384f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         num[3] = rgba_temp[3][j];
2385f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      }
2386f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2387f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      rgba[0][j] = num[0] / den;
2388f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      rgba[1][j] = num[1] / den;
2389f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      rgba[2][j] = num[2] / den;
2390f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      rgba[3][j] = num[3] / den;
2391f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   }
2392f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger}
2393f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2394f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2395f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger/**
2396d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak * Get mip level relative to base level for linear mip filter
2397d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak */
2398d71a3be86008c275b5902de7759385643546a210Krzesimir Nowakstatic void
2399ea0fecd1a3f46439c602e04870b34e6f27ad5b2eKrzesimir Nowakmip_rel_level_linear_aniso(const struct sp_sampler_view *sp_sview,
2400ea0fecd1a3f46439c602e04870b34e6f27ad5b2eKrzesimir Nowak                           const struct sp_sampler *sp_samp,
2401d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak                           const float lod[TGSI_QUAD_SIZE],
2402d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak                           float level[TGSI_QUAD_SIZE])
2403d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak{
2404d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak   mip_rel_level_linear(sp_sview, sp_samp, lod, level);
2405d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak}
2406d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak
2407d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak/**
2408f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger * Sample 2D texture using an anisotropic filter.
2409f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger */
2410f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fängerstatic void
2411ac23116de56e163a3815626277f9c3691bb56831Krzesimir Nowakmip_filter_linear_aniso(const struct sp_sampler_view *sp_sview,
2412ac23116de56e163a3815626277f9c3691bb56831Krzesimir Nowak                        const struct sp_sampler *sp_samp,
2413ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                        img_filter_func min_filter,
2414ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                        img_filter_func mag_filter,
24156b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                        const float s[TGSI_QUAD_SIZE],
24166b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                        const float t[TGSI_QUAD_SIZE],
24176b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                        const float p[TGSI_QUAD_SIZE],
24186b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                        const float c0[TGSI_QUAD_SIZE],
241975d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger                        const float lod_in[TGSI_QUAD_SIZE],
24208bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie                        const struct filter_args *filt_args,
24216b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard                        float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
2422f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger{
2423ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
2424b1c1c7d31b3ad625243616597028e7d599eb8190Roland Scheidegger   const struct pipe_sampler_view *psview = &sp_sview->base;
2425f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   int level0;
2426f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   float lambda;
24276b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float lod[TGSI_QUAD_SIZE];
2428f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
24292135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float s_to_u = u_minify(texture->width0, psview->u.tex.first_level);
24302135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float t_to_v = u_minify(texture->height0, psview->u.tex.first_level);
24312135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float dudx = (s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]) * s_to_u;
24322135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float dudy = (s[QUAD_TOP_LEFT]     - s[QUAD_BOTTOM_LEFT]) * s_to_u;
24332135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float dvdx = (t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]) * t_to_v;
24342135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const float dvdy = (t[QUAD_TOP_LEFT]     - t[QUAD_BOTTOM_LEFT]) * t_to_v;
243599e583120cde8820aae94eb0f8beb723509398fcDave Airlie   struct img_filter_args args;
243699e583120cde8820aae94eb0f8beb723509398fcDave Airlie
24379e9d69979c7aff7dac2d670af950f4a50273bcdeRoland Scheidegger   args.offset = filt_args->offset;
24389e9d69979c7aff7dac2d670af950f4a50273bcdeRoland Scheidegger
24392c52c794d727e535c1baca671a7c1e5b38dffb00Brian Paul   if (filt_args->control == TGSI_SAMPLER_LOD_BIAS ||
24402c52c794d727e535c1baca671a7c1e5b38dffb00Brian Paul       filt_args->control == TGSI_SAMPLER_LOD_NONE ||
24416ace2e41da7dded630d932d03bacb7e14a93d47aRoland Scheidegger       /* XXX FIXME */
24422c52c794d727e535c1baca671a7c1e5b38dffb00Brian Paul       filt_args->control == TGSI_SAMPLER_DERIVS_EXPLICIT) {
2443f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      /* note: instead of working with Px and Py, we will use the
2444f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger       * squared length instead, to avoid sqrt.
2445f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger       */
24462135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak      const float Px2 = dudx * dudx + dvdx * dvdx;
24472135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak      const float Py2 = dudy * dudy + dvdy * dvdy;
2448f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2449f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      float Pmax2;
2450f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      float Pmin2;
2451f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      float e;
2452ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      const float maxEccentricity = sp_samp->base.max_anisotropy * sp_samp->base.max_anisotropy;
2453f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2454f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      if (Px2 < Py2) {
2455f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         Pmax2 = Py2;
2456f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         Pmin2 = Px2;
2457f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      }
2458f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      else {
2459f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         Pmax2 = Px2;
2460f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         Pmin2 = Py2;
2461f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      }
2462f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2463f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      /* if the eccentricity of the ellipse is too big, scale up the shorter
2464f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger       * of the two vectors to limit the maximum amount of work per pixel
2465f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger       */
2466f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      e = Pmax2 / Pmin2;
2467f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      if (e > maxEccentricity) {
2468f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         /* float s=e / maxEccentricity;
2469f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger            minor[0] *= s;
2470f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger            minor[1] *= s;
2471f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger            Pmin2 *= s; */
2472f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger         Pmin2 = Pmax2 / maxEccentricity;
2473f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      }
2474f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2475f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      /* note: we need to have Pmin=sqrt(Pmin2) here, but we can avoid
2476f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger       * this since 0.5*log(x) = log(sqrt(x))
2477f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger       */
2478ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      lambda = 0.5F * util_fast_log2(Pmin2) + sp_samp->base.lod_bias;
24798bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie      compute_lod(&sp_samp->base, filt_args->control, lambda, lod_in, lod);
2480f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   }
2481f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   else {
24822c52c794d727e535c1baca671a7c1e5b38dffb00Brian Paul      assert(filt_args->control == TGSI_SAMPLER_LOD_EXPLICIT ||
24832c52c794d727e535c1baca671a7c1e5b38dffb00Brian Paul             filt_args->control == TGSI_SAMPLER_LOD_ZERO);
24848bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie      compute_lod(&sp_samp->base, filt_args->control, sp_samp->base.lod_bias, lod_in, lod);
2485f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   }
2486f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2487f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   /* XXX: Take into account all lod values.
2488f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger    */
2489f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   lambda = lod[0];
2490b1c1c7d31b3ad625243616597028e7d599eb8190Roland Scheidegger   level0 = psview->u.tex.first_level + (int)lambda;
2491f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2492f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   /* If the ellipse covers the whole image, we can
2493f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger    * simply return the average of the whole image.
2494f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger    */
2495b1c1c7d31b3ad625243616597028e7d599eb8190Roland Scheidegger   if (level0 >= (int) psview->u.tex.last_level) {
2496229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      int j;
249799e583120cde8820aae94eb0f8beb723509398fcDave Airlie      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
249899e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.s = s[j];
249999e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.t = t[j];
250099e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.p = p[j];
250199e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.level = psview->u.tex.last_level;
25024ca2896e8ea1908ea5a0d5bffe8a1b42145a6f72Krzesimir Nowak         args.face_id = filt_args->faces[j];
25034b249ed4cd813fa71e3b4a9457b365cc5dcbc3a1Roland Scheidegger         /*
25044b249ed4cd813fa71e3b4a9457b365cc5dcbc3a1Roland Scheidegger          * XXX: we overwrote any linear filter with nearest, so this
25054b249ed4cd813fa71e3b4a9457b365cc5dcbc3a1Roland Scheidegger          * isn't right (albeit if last level is 1x1 and no border it
25064b249ed4cd813fa71e3b4a9457b365cc5dcbc3a1Roland Scheidegger          * will work just the same).
25074b249ed4cd813fa71e3b4a9457b365cc5dcbc3a1Roland Scheidegger          */
250899e583120cde8820aae94eb0f8beb723509398fcDave Airlie         min_filter(sp_sview, sp_samp, &args, &rgba[0][j]);
250999e583120cde8820aae94eb0f8beb723509398fcDave Airlie      }
2510f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   }
2511f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   else {
2512f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      /* don't bother interpolating between multiple LODs; it doesn't
2513f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger       * seem to be worth the extra running time.
2514f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger       */
2515ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      img_filter_2d_ewa(sp_sview, sp_samp, min_filter, mag_filter,
25169e9d69979c7aff7dac2d670af950f4a50273bcdeRoland Scheidegger                        s, t, p, filt_args->faces, filt_args->offset,
25179e9d69979c7aff7dac2d670af950f4a50273bcdeRoland Scheidegger                        level0, dudx, dvdx, dudy, dvdy, rgba);
2518f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   }
2519f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2520f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   if (DEBUG_TEX) {
2521229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      print_sample_4(__FUNCTION__, rgba);
2522f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger   }
2523f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger}
2524f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2525d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak/**
2526d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak * Get mip level relative to base level for linear mip filter
2527d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak */
2528d71a3be86008c275b5902de7759385643546a210Krzesimir Nowakstatic void
2529ea0fecd1a3f46439c602e04870b34e6f27ad5b2eKrzesimir Nowakmip_rel_level_linear_2d_linear_repeat_POT(
2530ea0fecd1a3f46439c602e04870b34e6f27ad5b2eKrzesimir Nowak   const struct sp_sampler_view *sp_sview,
2531ea0fecd1a3f46439c602e04870b34e6f27ad5b2eKrzesimir Nowak   const struct sp_sampler *sp_samp,
2532ea0fecd1a3f46439c602e04870b34e6f27ad5b2eKrzesimir Nowak   const float lod[TGSI_QUAD_SIZE],
2533ea0fecd1a3f46439c602e04870b34e6f27ad5b2eKrzesimir Nowak   float level[TGSI_QUAD_SIZE])
2534d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak{
2535d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak   mip_rel_level_linear(sp_sview, sp_samp, lod, level);
2536d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak}
2537f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger
2538e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul/**
2539e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul * Specialized version of mip_filter_linear with hard-wired calls to
25404fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell * 2d lambda calculation and 2d_linear_repeat_POT img filters.
2541a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul */
25424fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
25434fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellmip_filter_linear_2d_linear_repeat_POT(
2544ac23116de56e163a3815626277f9c3691bb56831Krzesimir Nowak   const struct sp_sampler_view *sp_sview,
2545ac23116de56e163a3815626277f9c3691bb56831Krzesimir Nowak   const struct sp_sampler *sp_samp,
2546ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   img_filter_func min_filter,
2547ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   img_filter_func mag_filter,
25486b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   const float s[TGSI_QUAD_SIZE],
25496b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   const float t[TGSI_QUAD_SIZE],
25506b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   const float p[TGSI_QUAD_SIZE],
25516b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   const float c0[TGSI_QUAD_SIZE],
255275d99673a8f47f62458034b0566d6c0221fae5d1Roland Scheidegger   const float lod_in[TGSI_QUAD_SIZE],
25538bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie   const struct filter_args *filt_args,
25546b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
255500c835918259f8d41c3f74eca679a972713b11b2Keith Whitwell{
2556b1c1c7d31b3ad625243616597028e7d599eb8190Roland Scheidegger   const struct pipe_sampler_view *psview = &sp_sview->base;
2557229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   int j;
25586b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard   float lod[TGSI_QUAD_SIZE];
25594bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
25608bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie   compute_lambda_lod(sp_sview, sp_samp, s, t, p, lod_in, filt_args->control, lod);
25614bfe1c955fe679547c8a03119d1681e33593c768Michal Krol
2562229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
25632135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak      const int level0 = psview->u.tex.first_level + (int)lod[j];
256499e583120cde8820aae94eb0f8beb723509398fcDave Airlie      struct img_filter_args args;
2565229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      /* Catches both negative and large values of level0:
2566229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert       */
256799e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.s = s[j];
256899e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.t = t[j];
256999e583120cde8820aae94eb0f8beb723509398fcDave Airlie      args.p = p[j];
25704ca2896e8ea1908ea5a0d5bffe8a1b42145a6f72Krzesimir Nowak      args.face_id = filt_args->faces[j];
2571065978d36b8a8ba5aa23248c6bcd0f0e4d6e86deDave Airlie      args.offset = filt_args->offset;
25722c52c794d727e535c1baca671a7c1e5b38dffb00Brian Paul      args.gather_only = filt_args->control == TGSI_SAMPLER_GATHER;
2573b1c1c7d31b3ad625243616597028e7d599eb8190Roland Scheidegger      if ((unsigned)level0 >= psview->u.tex.last_level) {
2574229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         if (level0 < 0)
257599e583120cde8820aae94eb0f8beb723509398fcDave Airlie            args.level = psview->u.tex.first_level;
2576229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         else
257799e583120cde8820aae94eb0f8beb723509398fcDave Airlie            args.level = psview->u.tex.last_level;
257899e583120cde8820aae94eb0f8beb723509398fcDave Airlie         img_filter_2d_linear_repeat_POT(sp_sview, sp_samp, &args,
257999e583120cde8820aae94eb0f8beb723509398fcDave Airlie                                         &rgba[0][j]);
25804fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
2581229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      }
2582229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      else {
25832135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak         const float levelBlend = frac(lod[j]);
2584229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         float rgbax[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
2585229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         int c;
25864fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
258799e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.level = level0;
258899e583120cde8820aae94eb0f8beb723509398fcDave Airlie         img_filter_2d_linear_repeat_POT(sp_sview, sp_samp, &args, &rgbax[0][0]);
258999e583120cde8820aae94eb0f8beb723509398fcDave Airlie         args.level = level0+1;
259099e583120cde8820aae94eb0f8beb723509398fcDave Airlie         img_filter_2d_linear_repeat_POT(sp_sview, sp_samp, &args, &rgbax[0][1]);
25914fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
2592229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert         for (c = 0; c < TGSI_NUM_CHANNELS; c++)
2593229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert            rgba[c][j] = lerp(levelBlend, rgbax[c][0], rgbax[c][1]);
2594b1ff7dac537947d412bf423a73e7eacd76f90d84Brian Paul      }
2595ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul   }
25964250882ccf8326ba9074c671110370534489caa6Brian Paul
25974250882ccf8326ba9074c671110370534489caa6Brian Paul   if (DEBUG_TEX) {
2598229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibert      print_sample_4(__FUNCTION__, rgba);
25994250882ccf8326ba9074c671110370534489caa6Brian Paul   }
2600b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul}
2601b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul
2602b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowakstatic const struct sp_filter_funcs funcs_linear = {
2603d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak   mip_rel_level_linear,
2604b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowak   mip_filter_linear
2605b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowak};
2606b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowak
2607b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowakstatic const struct sp_filter_funcs funcs_nearest = {
2608d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak   mip_rel_level_nearest,
2609b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowak   mip_filter_nearest
2610b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowak};
2611b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowak
2612b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowakstatic const struct sp_filter_funcs funcs_none = {
2613d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak   mip_rel_level_none,
2614b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowak   mip_filter_none
2615b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowak};
2616b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowak
2617b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowakstatic const struct sp_filter_funcs funcs_none_no_filter_select = {
2618d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak   mip_rel_level_none_no_filter_select,
2619b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowak   mip_filter_none_no_filter_select
2620b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowak};
2621b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowak
2622b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowakstatic const struct sp_filter_funcs funcs_linear_aniso = {
2623d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak   mip_rel_level_linear_aniso,
2624b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowak   mip_filter_linear_aniso
2625b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowak};
2626b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowak
2627b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowakstatic const struct sp_filter_funcs funcs_linear_2d_linear_repeat_POT = {
2628d71a3be86008c275b5902de7759385643546a210Krzesimir Nowak   mip_rel_level_linear_2d_linear_repeat_POT,
2629b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowak   mip_filter_linear_2d_linear_repeat_POT
2630b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowak};
2631b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul
2632e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul/**
2633e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul * Do shadow/depth comparisons.
26343d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul */
26354fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwellstatic void
2636231687c19b3c6ab4f5bead7469b7b27fdbda6d43Krzesimir Nowaksample_compare(const struct sp_sampler_view *sp_sview,
2637231687c19b3c6ab4f5bead7469b7b27fdbda6d43Krzesimir Nowak               const struct sp_sampler *sp_samp,
26386b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard               const float s[TGSI_QUAD_SIZE],
26396b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard               const float t[TGSI_QUAD_SIZE],
26406b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard               const float p[TGSI_QUAD_SIZE],
26416b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard               const float c0[TGSI_QUAD_SIZE],
2642309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie               const float c1[TGSI_QUAD_SIZE],
26434440428faa82f01b4dfb4be89618be2aaf153abdMichal Krol               enum tgsi_sampler_control control,
26446b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard               float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
26453d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul{
2646ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_sampler_state *sampler = &sp_samp->base;
264755a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   int j, v;
264855a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   int k[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
2649c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing   float pc[4];
26502135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const struct util_format_description *format_desc =
26512135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak      util_format_description(sp_sview->base.format);
26522135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   /* not entirely sure we couldn't end up with non-valid swizzle here */
26532135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const unsigned chan_type =
2654fb523cb6ad3ffef22ab4b9cce9e53859c17c5739Marek Olšák      format_desc->swizzle[0] <= PIPE_SWIZZLE_W ?
26552135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak      format_desc->channel[format_desc->swizzle[0]].type :
26562135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak      UTIL_FORMAT_TYPE_FLOAT;
26572135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const bool is_gather = (control == TGSI_SAMPLER_GATHER);
26583d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul
26594fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /**
26604fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell    * Compare texcoord 'p' (aka R) against texture value 'rgba[0]'
266197b778efe7949977b4e857413807d1efcad346aaDave Airlie    * for 2D Array texture we need to use the 'c0' (aka Q).
26624fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell    * When we sampled the depth texture, the depth value was put into all
26634fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell    * RGBA channels.  We look at the red channel here.
26644fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell    */
2665efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul
2666adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   if (sp_sview->base.target == PIPE_TEXTURE_2D_ARRAY ||
2667adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger       sp_sview->base.target == PIPE_TEXTURE_CUBE) {
2668c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[0] = c0[0];
2669c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[1] = c0[1];
2670c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[2] = c0[2];
2671c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[3] = c0[3];
2672adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   } else if (sp_sview->base.target == PIPE_TEXTURE_CUBE_ARRAY) {
2673c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[0] = c1[0];
2674c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[1] = c1[1];
2675c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[2] = c1[2];
2676c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[3] = c1[3];
267797b778efe7949977b4e857413807d1efcad346aaDave Airlie   } else {
2678c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[0] = p[0];
2679c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[1] = p[1];
2680c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[2] = p[2];
2681c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[3] = p[3];
268297b778efe7949977b4e857413807d1efcad346aaDave Airlie   }
2683aa84f1ad5537f5b0232eb681147cb3a3882323b8Roland Scheidegger
2684aa84f1ad5537f5b0232eb681147cb3a3882323b8Roland Scheidegger   if (chan_type != UTIL_FORMAT_TYPE_FLOAT) {
2685aa84f1ad5537f5b0232eb681147cb3a3882323b8Roland Scheidegger      /*
2686aa84f1ad5537f5b0232eb681147cb3a3882323b8Roland Scheidegger       * clamping is a result of conversion to texture format, hence
2687aa84f1ad5537f5b0232eb681147cb3a3882323b8Roland Scheidegger       * doesn't happen with floats. Technically also should do comparison
2688aa84f1ad5537f5b0232eb681147cb3a3882323b8Roland Scheidegger       * in texture format (quantization!).
2689aa84f1ad5537f5b0232eb681147cb3a3882323b8Roland Scheidegger       */
2690c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[0] = CLAMP(pc[0], 0.0F, 1.0F);
2691c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[1] = CLAMP(pc[1], 0.0F, 1.0F);
2692c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[2] = CLAMP(pc[2], 0.0F, 1.0F);
2693c8e7568f97b2a71e263b037eb8617efcf36603c8Heinrich Janzing      pc[3] = CLAMP(pc[3], 0.0F, 1.0F);
2694aa84f1ad5537f5b0232eb681147cb3a3882323b8Roland Scheidegger   }
2695aa84f1ad5537f5b0232eb681147cb3a3882323b8Roland Scheidegger
269655a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   for (v = 0; v < (is_gather ? TGSI_NUM_CHANNELS : 1); v++) {
269755a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      /* compare four texcoords vs. four texture samples */
269855a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      switch (sampler->compare_func) {
269955a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      case PIPE_FUNC_LESS:
270055a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         k[v][0] = pc[0] < rgba[v][0];
270155a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         k[v][1] = pc[1] < rgba[v][1];
270255a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         k[v][2] = pc[2] < rgba[v][2];
270355a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         k[v][3] = pc[3] < rgba[v][3];
270455a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         break;
270555a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      case PIPE_FUNC_LEQUAL:
270655a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         k[v][0] = pc[0] <= rgba[v][0];
270755a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         k[v][1] = pc[1] <= rgba[v][1];
270855a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         k[v][2] = pc[2] <= rgba[v][2];
270955a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         k[v][3] = pc[3] <= rgba[v][3];
271055a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         break;
271155a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      case PIPE_FUNC_GREATER:
271255a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         k[v][0] = pc[0] > rgba[v][0];
271355a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         k[v][1] = pc[1] > rgba[v][1];
271455a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         k[v][2] = pc[2] > rgba[v][2];
271555a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         k[v][3] = pc[3] > rgba[v][3];
271655a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         break;
271755a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      case PIPE_FUNC_GEQUAL:
271855a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         k[v][0] = pc[0] >= rgba[v][0];
271955a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         k[v][1] = pc[1] >= rgba[v][1];
272055a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         k[v][2] = pc[2] >= rgba[v][2];
272155a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         k[v][3] = pc[3] >= rgba[v][3];
272255a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         break;
272355a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      case PIPE_FUNC_EQUAL:
272455a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         k[v][0] = pc[0] == rgba[v][0];
272555a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         k[v][1] = pc[1] == rgba[v][1];
272655a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         k[v][2] = pc[2] == rgba[v][2];
272755a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         k[v][3] = pc[3] == rgba[v][3];
272855a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         break;
272955a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      case PIPE_FUNC_NOTEQUAL:
273055a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         k[v][0] = pc[0] != rgba[v][0];
273155a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         k[v][1] = pc[1] != rgba[v][1];
273255a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         k[v][2] = pc[2] != rgba[v][2];
273355a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         k[v][3] = pc[3] != rgba[v][3];
273455a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         break;
273555a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      case PIPE_FUNC_ALWAYS:
273655a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         k[v][0] = k[v][1] = k[v][2] = k[v][3] = 1;
273755a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         break;
273855a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      case PIPE_FUNC_NEVER:
273955a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         k[v][0] = k[v][1] = k[v][2] = k[v][3] = 0;
274055a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         break;
274155a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      default:
274255a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         k[v][0] = k[v][1] = k[v][2] = k[v][3] = 0;
274355a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         assert(0);
274455a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         break;
274555a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      }
2746efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   }
2747efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul
274855a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   if (is_gather) {
274955a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
275055a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         for (v = 0; v < TGSI_NUM_CHANNELS; v++) {
275155a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie            rgba[v][j] = k[v][j];
275255a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         }
275355a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      }
275455a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie   } else {
275555a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
275655a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         rgba[0][j] = k[0][j];
275755a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         rgba[1][j] = k[0][j];
275855a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         rgba[2][j] = k[0][j];
275955a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie         rgba[3][j] = 1.0F;
276055a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      }
2761efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul   }
2762efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul}
2763efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul
2764e12810d92ffb3547680b227bf88937c03018112bBrian Paulstatic void
2765ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerdo_swizzling(const struct pipe_sampler_view *sview,
2766b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul             float in[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE],
2767b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul             float out[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
2768c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul{
2769e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie   int j;
2770ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const unsigned swizzle_r = sview->swizzle_r;
2771ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const unsigned swizzle_g = sview->swizzle_g;
2772ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const unsigned swizzle_b = sview->swizzle_b;
2773ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const unsigned swizzle_a = sview->swizzle_a;
2774c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul
2775c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   switch (swizzle_r) {
2776fb523cb6ad3ffef22ab4b9cce9e53859c17c5739Marek Olšák   case PIPE_SWIZZLE_0:
2777c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2778e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[0][j] = 0.0f;
2779c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      break;
2780fb523cb6ad3ffef22ab4b9cce9e53859c17c5739Marek Olšák   case PIPE_SWIZZLE_1:
2781c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2782e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[0][j] = 1.0f;
2783c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      break;
2784c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   default:
2785c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      assert(swizzle_r < 4);
2786c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2787e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[0][j] = in[swizzle_r][j];
2788c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   }
2789c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul
2790c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   switch (swizzle_g) {
2791fb523cb6ad3ffef22ab4b9cce9e53859c17c5739Marek Olšák   case PIPE_SWIZZLE_0:
2792c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2793e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[1][j] = 0.0f;
2794c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      break;
2795fb523cb6ad3ffef22ab4b9cce9e53859c17c5739Marek Olšák   case PIPE_SWIZZLE_1:
2796c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2797e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[1][j] = 1.0f;
2798c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      break;
2799c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   default:
2800c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      assert(swizzle_g < 4);
2801c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2802e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[1][j] = in[swizzle_g][j];
2803c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   }
2804c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul
2805c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   switch (swizzle_b) {
2806fb523cb6ad3ffef22ab4b9cce9e53859c17c5739Marek Olšák   case PIPE_SWIZZLE_0:
2807c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2808e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[2][j] = 0.0f;
2809c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      break;
2810fb523cb6ad3ffef22ab4b9cce9e53859c17c5739Marek Olšák   case PIPE_SWIZZLE_1:
2811c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2812e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[2][j] = 1.0f;
2813c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      break;
2814c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   default:
2815c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      assert(swizzle_b < 4);
2816c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2817e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[2][j] = in[swizzle_b][j];
2818c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   }
2819c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul
2820c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   switch (swizzle_a) {
2821fb523cb6ad3ffef22ab4b9cce9e53859c17c5739Marek Olšák   case PIPE_SWIZZLE_0:
2822c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2823e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[3][j] = 0.0f;
2824c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      break;
2825fb523cb6ad3ffef22ab4b9cce9e53859c17c5739Marek Olšák   case PIPE_SWIZZLE_1:
2826c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2827e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[3][j] = 1.0f;
2828c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      break;
2829c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   default:
2830c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      assert(swizzle_a < 4);
2831c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul      for (j = 0; j < 4; j++)
2832e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie         out[3][j] = in[swizzle_a][j];
2833c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   }
2834c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul}
2835c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul
2836b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul
2837e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paulstatic wrap_nearest_func
2838e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paulget_nearest_unorm_wrap(unsigned mode)
28394fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
28404fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   switch (mode) {
28414fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP:
28424fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_unorm_clamp;
28434fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
2844b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul      return wrap_nearest_unorm_clamp_to_edge;
28454fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
28464fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_unorm_clamp_to_border;
28470dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul   default:
2848c9ae5038d564ec10a12658a2440cf49f83f1fab8Roland Scheidegger      debug_printf("illegal wrap mode %d with non-normalized coords\n", mode);
28494fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_unorm_clamp;
28500dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul   }
28510dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul}
285234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul
285334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul
2854e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paulstatic wrap_nearest_func
2855e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paulget_nearest_wrap(unsigned mode)
2856a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul{
28574fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   switch (mode) {
28584fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_REPEAT:
28594fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_repeat;
28604fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP:
28614fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_clamp;
28624fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
28634fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_clamp_to_edge;
28644fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
28654fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_clamp_to_border;
28664fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_MIRROR_REPEAT:
28674fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_mirror_repeat;
28684fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_MIRROR_CLAMP:
28694fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_mirror_clamp;
28704fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
28714fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_mirror_clamp_to_edge;
28724fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
28734fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_mirror_clamp_to_border;
28744fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   default:
28754fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      assert(0);
28764fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_nearest_repeat;
28774fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   }
2878a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul}
2879a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul
2880e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
2881e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paulstatic wrap_linear_func
2882e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paulget_linear_unorm_wrap(unsigned mode)
2883a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul{
28844fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   switch (mode) {
28854fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP:
28864fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_unorm_clamp;
28874fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
2888b5b128b26841e7f947edd8f0cbcc91a530d6bb8fBrian Paul      return wrap_linear_unorm_clamp_to_edge;
28894fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
28904fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_unorm_clamp_to_border;
28914fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   default:
2892c9ae5038d564ec10a12658a2440cf49f83f1fab8Roland Scheidegger      debug_printf("illegal wrap mode %d with non-normalized coords\n", mode);
28934fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_unorm_clamp;
28944fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   }
2895a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul}
2896a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul
2897e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
2898e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paulstatic wrap_linear_func
2899e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paulget_linear_wrap(unsigned mode)
290034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul{
29014fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   switch (mode) {
29024fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_REPEAT:
29034fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_repeat;
29044fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP:
29054fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_clamp;
29064fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
29074fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_clamp_to_edge;
29084fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
29094fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_clamp_to_border;
29104fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_MIRROR_REPEAT:
29114fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_mirror_repeat;
29124fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_MIRROR_CLAMP:
29134fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_mirror_clamp;
29144fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
29154fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_mirror_clamp_to_edge;
29164fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
29174fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_mirror_clamp_to_border;
29183d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul   default:
29193d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul      assert(0);
29204fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return wrap_linear_repeat;
29213d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul   }
292234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul}
292334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul
2924e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
292507f5dabc01e9a85073ffd333c37549ec5ae75c7aBrian Paul/**
292607f5dabc01e9a85073ffd333c37549ec5ae75c7aBrian Paul * Is swizzling needed for the given state key?
292707f5dabc01e9a85073ffd333c37549ec5ae75c7aBrian Paul */
2928a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline bool
2929ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerany_swizzle(const struct pipe_sampler_view *view)
293034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul{
2931fb523cb6ad3ffef22ab4b9cce9e53859c17c5739Marek Olšák   return (view->swizzle_r != PIPE_SWIZZLE_X ||
2932fb523cb6ad3ffef22ab4b9cce9e53859c17c5739Marek Olšák           view->swizzle_g != PIPE_SWIZZLE_Y ||
2933fb523cb6ad3ffef22ab4b9cce9e53859c17c5739Marek Olšák           view->swizzle_b != PIPE_SWIZZLE_Z ||
2934fb523cb6ad3ffef22ab4b9cce9e53859c17c5739Marek Olšák           view->swizzle_a != PIPE_SWIZZLE_W);
293534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul}
293634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul
2937e2329f2795d48d11131e9ac105e7aa3fd2c229c1Brian Paul
2938229a1a7e4da1a9c60b35b79f2a63e0bab451a76eOlivier Galibertstatic img_filter_func
2939ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerget_img_filter(const struct sp_sampler_view *sp_sview,
2940ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger               const struct pipe_sampler_state *sampler,
294155a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie               unsigned filter, bool gather)
2942b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul{
2943adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   switch (sp_sview->base.target) {
2944a6256f1e678cf72a2c0cb407a2118afa92bd1b20Dave Airlie   case PIPE_BUFFER:
29454fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEXTURE_1D:
29464fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      if (filter == PIPE_TEX_FILTER_NEAREST)
29474fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         return img_filter_1d_nearest;
29484fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      else
29494fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         return img_filter_1d_linear;
2950b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul      break;
2951779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   case PIPE_TEXTURE_1D_ARRAY:
2952779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul      if (filter == PIPE_TEX_FILTER_NEAREST)
2953779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul         return img_filter_1d_array_nearest;
2954779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul      else
2955779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul         return img_filter_1d_array_linear;
2956779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul      break;
29574fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEXTURE_2D:
2958ae0ef6f69f351cacdc7eaa9b21097a7c1b414e44Luca Barbieri   case PIPE_TEXTURE_RECT:
29594fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      /* Try for fast path:
29604fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell       */
296155a7b5165d40b831fd303079f8f80962d195d6eeDave Airlie      if (!gather && sp_sview->pot2d &&
29624fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell          sampler->wrap_s == sampler->wrap_t &&
29634fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell          sampler->normalized_coords)
296438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul      {
29654fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         switch (sampler->wrap_s) {
29664fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         case PIPE_TEX_WRAP_REPEAT:
29674fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell            switch (filter) {
29686142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell            case PIPE_TEX_FILTER_NEAREST:
29694fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell               return img_filter_2d_nearest_repeat_POT;
29706142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell            case PIPE_TEX_FILTER_LINEAR:
29714fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell               return img_filter_2d_linear_repeat_POT;
29726142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell            default:
29736142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell               break;
297438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul            }
29754fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell            break;
29764fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         case PIPE_TEX_WRAP_CLAMP:
29774fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell            switch (filter) {
29786142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell            case PIPE_TEX_FILTER_NEAREST:
29794fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell               return img_filter_2d_nearest_clamp_POT;
29806142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell            default:
29816142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell               break;
298238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian Paul            }
2983b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul         }
2984b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul      }
298560adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell      /* Otherwise use default versions:
29864fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell       */
29874fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      if (filter == PIPE_TEX_FILTER_NEAREST)
29884fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         return img_filter_2d_nearest;
29894fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      else
29904fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         return img_filter_2d_linear;
29914fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      break;
2992779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul   case PIPE_TEXTURE_2D_ARRAY:
2993779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul      if (filter == PIPE_TEX_FILTER_NEAREST)
2994779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul         return img_filter_2d_array_nearest;
2995779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul      else
2996779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul         return img_filter_2d_array_linear;
2997779e9cb658dba4ef44fae7e8aa62409f7227f46cBrian Paul      break;
299860adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell   case PIPE_TEXTURE_CUBE:
299960adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell      if (filter == PIPE_TEX_FILTER_NEAREST)
300060adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell         return img_filter_cube_nearest;
300160adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell      else
300260adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell         return img_filter_cube_linear;
300360adc15ba5633190fc8a68e7c182f06dc7909df4Keith Whitwell      break;
3004309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie   case PIPE_TEXTURE_CUBE_ARRAY:
3005309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie      if (filter == PIPE_TEX_FILTER_NEAREST)
3006309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie         return img_filter_cube_array_nearest;
3007309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie      else
3008309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie         return img_filter_cube_array_linear;
3009309fda2fb28dfe7e8b9be31806346125bef13b21Dave Airlie      break;
30104fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEXTURE_3D:
30114fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      if (filter == PIPE_TEX_FILTER_NEAREST)
30124fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         return img_filter_3d_nearest;
30134fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      else
30144fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell         return img_filter_3d_linear;
3015b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul      break;
3016b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul   default:
3017b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul      assert(0);
30184fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      return img_filter_1d_nearest;
3019b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul   }
3020b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul}
3021b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul
3022380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak/**
3023380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak * Get mip filter funcs, and optionally both img min filter and img mag
3024380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak * filter. Note that both img filter function pointers must be either non-NULL
3025380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak * or NULL.
3026380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak */
3027380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowakstatic void
3028ea0fecd1a3f46439c602e04870b34e6f27ad5b2eKrzesimir Nowakget_filters(const struct sp_sampler_view *sp_sview,
3029ea0fecd1a3f46439c602e04870b34e6f27ad5b2eKrzesimir Nowak            const struct sp_sampler *sp_samp,
3030ea0fecd1a3f46439c602e04870b34e6f27ad5b2eKrzesimir Nowak            const enum tgsi_sampler_control control,
3031380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak            const struct sp_filter_funcs **funcs,
3032380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak            img_filter_func *min,
3033380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak            img_filter_func *mag)
3034380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak{
3035380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak   assert(funcs);
30362c52c794d727e535c1baca671a7c1e5b38dffb00Brian Paul   if (control == TGSI_SAMPLER_GATHER) {
3037380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak      *funcs = &funcs_nearest;
3038380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak      if (min) {
3039380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak         *min = get_img_filter(sp_sview, &sp_samp->base,
3040380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak                               PIPE_TEX_FILTER_LINEAR, true);
3041380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak      }
3042380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak   } else if (sp_sview->pot2d & sp_samp->min_mag_equal_repeat_linear) {
3043380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak      *funcs = &funcs_linear_2d_linear_repeat_POT;
3044380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak   } else {
3045380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak      *funcs = sp_samp->filter_funcs;
3046380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak      if (min) {
3047380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak         assert(mag);
3048380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak         *min = get_img_filter(sp_sview, &sp_samp->base,
3049380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak                               sp_samp->min_img_filter, false);
3050380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak         if (sp_samp->min_mag_equal) {
3051380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak            *mag = *min;
3052380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak         } else {
3053380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak            *mag = get_img_filter(sp_sview, &sp_samp->base,
3054380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak                                  sp_samp->base.mag_img_filter, false);
3055380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak         }
3056380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak      }
3057380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak   }
3058380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak}
3059b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul
3060ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerstatic void
3061231687c19b3c6ab4f5bead7469b7b27fdbda6d43Krzesimir Nowaksample_mip(const struct sp_sampler_view *sp_sview,
3062231687c19b3c6ab4f5bead7469b7b27fdbda6d43Krzesimir Nowak           const struct sp_sampler *sp_samp,
3063ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger           const float s[TGSI_QUAD_SIZE],
3064ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger           const float t[TGSI_QUAD_SIZE],
3065ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger           const float p[TGSI_QUAD_SIZE],
3066ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger           const float c0[TGSI_QUAD_SIZE],
3067ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger           const float lod[TGSI_QUAD_SIZE],
30688bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie           const struct filter_args *filt_args,
3069ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger           float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
3070ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger{
3071b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowak   const struct sp_filter_funcs *funcs = NULL;
3072ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   img_filter_func min_img_filter = NULL;
3073ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   img_filter_func mag_img_filter = NULL;
3074ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3075380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak   get_filters(sp_sview, sp_samp, filt_args->control,
3076380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak               &funcs, &min_img_filter, &mag_img_filter);
3077ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3078b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowak   funcs->filter(sp_sview, sp_samp, min_img_filter, mag_img_filter,
3079b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowak                 s, t, p, c0, lod, filt_args, rgba);
3080ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3081ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   if (sp_samp->base.compare_mode != PIPE_TEX_COMPARE_NONE) {
3082380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak      sample_compare(sp_sview, sp_samp, s, t, p, c0,
3083380a3c08049e5a3b0b1a891e3288b001c535d62fKrzesimir Nowak                     lod, filt_args->control, rgba);
3084ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   }
3085ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
30862c52c794d727e535c1baca671a7c1e5b38dffb00Brian Paul   if (sp_sview->need_swizzle && filt_args->control != TGSI_SAMPLER_GATHER) {
3087ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      float rgba_temp[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
3088ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      memcpy(rgba_temp, rgba, sizeof(rgba_temp));
3089ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      do_swizzling(&sp_sview->base, rgba_temp, rgba);
3090ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   }
3091ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3092ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger}
3093ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3094ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3095a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul/**
3096ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak * This function uses cube texture coordinates to choose a face of a cube and
3097ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak * computes the 2D cube face coordinates. Puts face info into the sampler
3098ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak * faces[] array.
3099a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul */
3100ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerstatic void
3101ea0fecd1a3f46439c602e04870b34e6f27ad5b2eKrzesimir Nowakconvert_cube(const struct sp_sampler_view *sp_sview,
3102ea0fecd1a3f46439c602e04870b34e6f27ad5b2eKrzesimir Nowak             const struct sp_sampler *sp_samp,
3103ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak             const float s[TGSI_QUAD_SIZE],
3104ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak             const float t[TGSI_QUAD_SIZE],
3105ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak             const float p[TGSI_QUAD_SIZE],
3106ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak             const float c0[TGSI_QUAD_SIZE],
3107ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak             float ssss[TGSI_QUAD_SIZE],
3108ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak             float tttt[TGSI_QUAD_SIZE],
31094ca2896e8ea1908ea5a0d5bffe8a1b42145a6f72Krzesimir Nowak             float pppp[TGSI_QUAD_SIZE],
311008ceb5e076328bf6ccceed3a8e5de205dcaf63b0Krzesimir Nowak             uint faces[TGSI_QUAD_SIZE])
311134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul{
3112ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   unsigned j;
31130b9e96fae9493d5d58f046e01c983a3c4267090eBrian Paul
3114ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   pppp[0] = c0[0];
3115ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   pppp[1] = c0[1];
3116ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   pppp[2] = c0[2];
3117ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   pppp[3] = c0[3];
3118ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   /*
3119ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger     major axis
3120ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger     direction    target                             sc     tc    ma
3121ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger     ----------   -------------------------------    ---    ---   ---
3122ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger     +rx          TEXTURE_CUBE_MAP_POSITIVE_X_EXT    -rz    -ry   rx
3123ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger     -rx          TEXTURE_CUBE_MAP_NEGATIVE_X_EXT    +rz    -ry   rx
3124ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger     +ry          TEXTURE_CUBE_MAP_POSITIVE_Y_EXT    +rx    +rz   ry
3125ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger     -ry          TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT    +rx    -rz   ry
3126ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger     +rz          TEXTURE_CUBE_MAP_POSITIVE_Z_EXT    +rx    -ry   rz
3127ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger     -rz          TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT    -rx    -ry   rz
3128ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   */
31294f23468bd0d14b8ed687a641003d587b91ad39a7Brian Paul
3130ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   /* Choose the cube face and compute new s/t coords for the 2D face.
3131ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger    *
3132ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger    * Use the same cube face for all four pixels in the quad.
3133ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger    *
3134ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger    * This isn't ideal, but if we want to use a different cube face
3135ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger    * per pixel in the quad, we'd have to also compute the per-face
3136ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger    * LOD here too.  That's because the four post-face-selection
3137ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger    * texcoords are no longer related to each other (they're
3138ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger    * per-face!)  so we can't use subtraction to compute the partial
3139ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger    * deriviates to compute the LOD.  Doing so (near cube edges
3140ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger    * anyway) gives us pretty much random values.
3141ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger    */
3142ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   {
3143ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      /* use the average of the four pixel's texcoords to choose the face */
3144ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      const float rx = 0.25F * (s[0] + s[1] + s[2] + s[3]);
3145ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      const float ry = 0.25F * (t[0] + t[1] + t[2] + t[3]);
3146ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      const float rz = 0.25F * (p[0] + p[1] + p[2] + p[3]);
3147ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz);
3148ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3149ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      if (arx >= ary && arx >= arz) {
3150ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak         const float sign = (rx >= 0.0F) ? 1.0F : -1.0F;
3151ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak         const uint face = (rx >= 0.0F) ?
3152ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak            PIPE_TEX_FACE_POS_X : PIPE_TEX_FACE_NEG_X;
3153ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         for (j = 0; j < TGSI_QUAD_SIZE; j++) {
3154ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            const float ima = -0.5F / fabsf(s[j]);
3155ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            ssss[j] = sign *  p[j] * ima + 0.5F;
3156ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            tttt[j] =         t[j] * ima + 0.5F;
31574ca2896e8ea1908ea5a0d5bffe8a1b42145a6f72Krzesimir Nowak            faces[j] = face;
3158ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         }
3159ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      }
3160ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      else if (ary >= arx && ary >= arz) {
3161ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak         const float sign = (ry >= 0.0F) ? 1.0F : -1.0F;
3162ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak         const uint face = (ry >= 0.0F) ?
3163ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak            PIPE_TEX_FACE_POS_Y : PIPE_TEX_FACE_NEG_Y;
3164ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         for (j = 0; j < TGSI_QUAD_SIZE; j++) {
3165ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            const float ima = -0.5F / fabsf(t[j]);
3166ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            ssss[j] =        -s[j] * ima + 0.5F;
3167ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            tttt[j] = sign * -p[j] * ima + 0.5F;
31684ca2896e8ea1908ea5a0d5bffe8a1b42145a6f72Krzesimir Nowak            faces[j] = face;
3169ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         }
3170ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      }
3171ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      else {
3172ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak         const float sign = (rz >= 0.0F) ? 1.0F : -1.0F;
3173ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak         const uint face = (rz >= 0.0F) ?
3174ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak            PIPE_TEX_FACE_POS_Z : PIPE_TEX_FACE_NEG_Z;
3175ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         for (j = 0; j < TGSI_QUAD_SIZE; j++) {
3176ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            const float ima = -0.5F / fabsf(p[j]);
3177ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            ssss[j] = sign * -s[j] * ima + 0.5F;
3178ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            tttt[j] =         t[j] * ima + 0.5F;
31794ca2896e8ea1908ea5a0d5bffe8a1b42145a6f72Krzesimir Nowak            faces[j] = face;
3180ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         }
3181ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      }
3182ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   }
3183ecfa8be150ed276af816467b467e76e026f5b541Keith Whitwell}
3184ecfa8be150ed276af816467b467e76e026f5b541Keith Whitwell
3185b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul
3186461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airliestatic void
3187231687c19b3c6ab4f5bead7469b7b27fdbda6d43Krzesimir Nowaksp_get_dims(const struct sp_sampler_view *sp_sview,
3188231687c19b3c6ab4f5bead7469b7b27fdbda6d43Krzesimir Nowak            int level,
3189ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            int dims[4])
3190ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger{
3191ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_sampler_view *view = &sp_sview->base;
3192ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = view->texture;
3193ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3194adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   if (view->target == PIPE_BUFFER) {
31957cd256ce7e4bad680bb77d033cf5dd662abab2ddMarek Olšák      dims[0] = view->u.buf.size / util_format_get_blocksize(view->format);
3196c45b9b572159983a20cf771016c3528a423643e1Brian Paul      /* the other values are undefined, but let's avoid potential valgrind
3197c45b9b572159983a20cf771016c3528a423643e1Brian Paul       * warnings.
3198c45b9b572159983a20cf771016c3528a423643e1Brian Paul       */
3199c45b9b572159983a20cf771016c3528a423643e1Brian Paul      dims[1] = dims[2] = dims[3] = 0;
3200c45b9b572159983a20cf771016c3528a423643e1Brian Paul      return;
3201c45b9b572159983a20cf771016c3528a423643e1Brian Paul   }
3202c45b9b572159983a20cf771016c3528a423643e1Brian Paul
3203ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   /* undefined according to EXT_gpu_program */
3204ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   level += view->u.tex.first_level;
3205ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   if (level > view->u.tex.last_level)
3206ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return;
3207ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3208c45b9b572159983a20cf771016c3528a423643e1Brian Paul   dims[3] = view->u.tex.last_level - view->u.tex.first_level + 1;
3209ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   dims[0] = u_minify(texture->width0, level);
3210ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3211adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   switch (view->target) {
3212ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_1D_ARRAY:
3213ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      dims[1] = view->u.tex.last_layer - view->u.tex.first_layer + 1;
3214ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      /* fallthrough */
3215ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_1D:
3216ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return;
3217ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_2D_ARRAY:
3218ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      dims[2] = view->u.tex.last_layer - view->u.tex.first_layer + 1;
3219ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      /* fallthrough */
3220ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_2D:
3221ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_CUBE:
3222ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_RECT:
3223ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      dims[1] = u_minify(texture->height0, level);
3224ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return;
3225ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_3D:
3226ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      dims[1] = u_minify(texture->height0, level);
3227ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      dims[2] = u_minify(texture->depth0, level);
3228ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return;
3229ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_CUBE_ARRAY:
3230ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      dims[1] = u_minify(texture->height0, level);
3231ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      dims[2] = (view->u.tex.last_layer - view->u.tex.first_layer + 1) / 6;
3232ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      break;
3233ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   default:
3234ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      assert(!"unexpected texture target in sp_get_dims()");
3235ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return;
3236ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   }
3237461646f539aa306afa1df3f9d9c72da06818a3b6Dave Airlie}
3238ecfa8be150ed276af816467b467e76e026f5b541Keith Whitwell
323992d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul/**
324092d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul * This function is only used for getting unfiltered texels via the
324192d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul * TXF opcode.  The GL spec says that out-of-bounds texel fetches
324292d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul * produce undefined results.  Instead of crashing, lets just clamp
324392d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul * coords to the texture image size.
324492d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul */
324562ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airliestatic void
3246231687c19b3c6ab4f5bead7469b7b27fdbda6d43Krzesimir Nowaksp_get_texels(const struct sp_sampler_view *sp_sview,
3247ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger              const int v_i[TGSI_QUAD_SIZE],
3248ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger              const int v_j[TGSI_QUAD_SIZE],
3249ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger              const int v_k[TGSI_QUAD_SIZE],
3250ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger              const int lod[TGSI_QUAD_SIZE],
3251ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger              const int8_t offset[3],
3252ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger              float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
325362ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie{
325462ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   union tex_tile_address addr;
3255ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   const struct pipe_resource *texture = sp_sview->base.texture;
325662ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   int j, c;
3257e3a7cb4a6c94efe250c0212f062930e2026a861dBrian Paul   const float *tx;
325862ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   /* TODO write a better test for LOD */
32592135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const unsigned level =
32602135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak      sp_sview->base.target == PIPE_BUFFER ? 0 :
32612135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak      CLAMP(lod[0] + sp_sview->base.u.tex.first_level,
32622135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak            sp_sview->base.u.tex.first_level,
32632135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak            sp_sview->base.u.tex.last_level);
32642135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int width = u_minify(texture->width0, level);
32652135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int height = u_minify(texture->height0, level);
32662135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const int depth = u_minify(texture->depth0, level);
32677cd256ce7e4bad680bb77d033cf5dd662abab2ddMarek Olšák   unsigned elem_size, first_element, last_element;
326862ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie
32692135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   addr.value = 0;
32702135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   addr.bits.level = level;
327192d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul
3272adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   switch (sp_sview->base.target) {
3273a6256f1e678cf72a2c0cb407a2118afa92bd1b20Dave Airlie   case PIPE_BUFFER:
32747cd256ce7e4bad680bb77d033cf5dd662abab2ddMarek Olšák      elem_size = util_format_get_blocksize(sp_sview->base.format);
32757cd256ce7e4bad680bb77d033cf5dd662abab2ddMarek Olšák      first_element = sp_sview->base.u.buf.offset / elem_size;
32767cd256ce7e4bad680bb77d033cf5dd662abab2ddMarek Olšák      last_element = (sp_sview->base.u.buf.offset +
32777cd256ce7e4bad680bb77d033cf5dd662abab2ddMarek Olšák                      sp_sview->base.u.buf.size) / elem_size - 1;
3278fb586e1edb207328534f554a9afaf2c07434e08eRoland Scheidegger      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
3279fb586e1edb207328534f554a9afaf2c07434e08eRoland Scheidegger         const int x = CLAMP(v_i[j] + offset[0] +
32807cd256ce7e4bad680bb77d033cf5dd662abab2ddMarek Olšák                             first_element,
32817cd256ce7e4bad680bb77d033cf5dd662abab2ddMarek Olšák                             first_element,
32827cd256ce7e4bad680bb77d033cf5dd662abab2ddMarek Olšák                             last_element);
3283fb586e1edb207328534f554a9afaf2c07434e08eRoland Scheidegger         tx = get_texel_2d_no_border(sp_sview, addr, x, 0);
3284fb586e1edb207328534f554a9afaf2c07434e08eRoland Scheidegger         for (c = 0; c < 4; c++) {
3285fb586e1edb207328534f554a9afaf2c07434e08eRoland Scheidegger            rgba[c][j] = tx[c];
3286fb586e1edb207328534f554a9afaf2c07434e08eRoland Scheidegger         }
3287fb586e1edb207328534f554a9afaf2c07434e08eRoland Scheidegger      }
3288fb586e1edb207328534f554a9afaf2c07434e08eRoland Scheidegger      break;
328962ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   case PIPE_TEXTURE_1D:
32906b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
32912135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak         const int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
3292fb586e1edb207328534f554a9afaf2c07434e08eRoland Scheidegger         tx = get_texel_2d_no_border(sp_sview, addr, x,
3293fb586e1edb207328534f554a9afaf2c07434e08eRoland Scheidegger                                     sp_sview->base.u.tex.first_layer);
3294ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         for (c = 0; c < 4; c++) {
3295ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            rgba[c][j] = tx[c];
3296ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         }
329762ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      }
329862ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      break;
329962ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   case PIPE_TEXTURE_1D_ARRAY:
33006b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
33012135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak         const int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
33022135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak         const int y = CLAMP(v_j[j], sp_sview->base.u.tex.first_layer,
33032135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak                             sp_sview->base.u.tex.last_layer);
3304ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         tx = get_texel_2d_no_border(sp_sview, addr, x, y);
3305ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         for (c = 0; c < 4; c++) {
3306ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            rgba[c][j] = tx[c];
3307ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         }
330862ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      }
330962ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      break;
331062ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   case PIPE_TEXTURE_2D:
331162ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   case PIPE_TEXTURE_RECT:
33126b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
33132135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak         const int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
33142135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak         const int y = CLAMP(v_j[j] + offset[1], 0, height - 1);
3315fb586e1edb207328534f554a9afaf2c07434e08eRoland Scheidegger         tx = get_texel_3d_no_border(sp_sview, addr, x, y,
3316fb586e1edb207328534f554a9afaf2c07434e08eRoland Scheidegger                                     sp_sview->base.u.tex.first_layer);
3317ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         for (c = 0; c < 4; c++) {
3318ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            rgba[c][j] = tx[c];
3319ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         }
332062ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      }
332162ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      break;
332262ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   case PIPE_TEXTURE_2D_ARRAY:
33236b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
33242135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak         const int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
33252135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak         const int y = CLAMP(v_j[j] + offset[1], 0, height - 1);
33262135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak         const int layer = CLAMP(v_k[j], sp_sview->base.u.tex.first_layer,
33272135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak                                 sp_sview->base.u.tex.last_layer);
3328ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         tx = get_texel_3d_no_border(sp_sview, addr, x, y, layer);
3329ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         for (c = 0; c < 4; c++) {
3330ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            rgba[c][j] = tx[c];
3331ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         }
333262ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      }
333362ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      break;
333462ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   case PIPE_TEXTURE_3D:
33356b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
333692d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul         int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
333792d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul         int y = CLAMP(v_j[j] + offset[1], 0, height - 1);
333892d899303a0498e53b66fe19658a2f7fd6dc9a26Brian Paul         int z = CLAMP(v_k[j] + offset[2], 0, depth - 1);
3339ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         tx = get_texel_3d_no_border(sp_sview, addr, x, y, z);
3340ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         for (c = 0; c < 4; c++) {
3341ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger            rgba[c][j] = tx[c];
3342ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         }
334362ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      }
334462ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      break;
334562ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   case PIPE_TEXTURE_CUBE: /* TXF can't work on CUBE according to spec */
3346fb586e1edb207328534f554a9afaf2c07434e08eRoland Scheidegger   case PIPE_TEXTURE_CUBE_ARRAY:
334762ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   default:
334862ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      assert(!"Unknown or CUBE texture type in TXF processing\n");
334962ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie      break;
335062ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie   }
3351e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie
3352ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   if (sp_sview->need_swizzle) {
33536b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard      float rgba_temp[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
3354e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie      memcpy(rgba_temp, rgba, sizeof(rgba_temp));
3355ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      do_swizzling(&sp_sview->base, rgba_temp, rgba);
3356e809b7a6787e40f974883104606550fb3d53ba47Dave Airlie   }
335762ad6e66a5c11fa58e51a6251f97a12a759773ecDave Airlie}
3358b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul
3359b5e44c2cfb93ff0cfc6141dda6bdaa59a11a5920Brian Paul
3360ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggervoid *
3361ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggersoftpipe_create_sampler_state(struct pipe_context *pipe,
3362ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                              const struct pipe_sampler_state *sampler)
33634fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell{
3364ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   struct sp_sampler *samp = CALLOC_STRUCT(sp_sampler);
33654fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
3366ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   samp->base = *sampler;
33674fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
33684fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   /* Note that (for instance) linear_texcoord_s and
33694fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell    * nearest_texcoord_s may be active at the same time, if the
33704fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell    * sampler min_img_filter differs from its mag_img_filter.
33714fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell    */
33724fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   if (sampler->normalized_coords) {
33734fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->linear_texcoord_s = get_linear_wrap( sampler->wrap_s );
33744fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->linear_texcoord_t = get_linear_wrap( sampler->wrap_t );
33754fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->linear_texcoord_p = get_linear_wrap( sampler->wrap_r );
3376ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
33774fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->nearest_texcoord_s = get_nearest_wrap( sampler->wrap_s );
33784fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->nearest_texcoord_t = get_nearest_wrap( sampler->wrap_t );
33794fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->nearest_texcoord_p = get_nearest_wrap( sampler->wrap_r );
33804fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   }
33814fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   else {
33824fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->linear_texcoord_s = get_linear_unorm_wrap( sampler->wrap_s );
33834fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->linear_texcoord_t = get_linear_unorm_wrap( sampler->wrap_t );
33844fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->linear_texcoord_p = get_linear_unorm_wrap( sampler->wrap_r );
3385ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
33864fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->nearest_texcoord_s = get_nearest_unorm_wrap( sampler->wrap_s );
33874fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->nearest_texcoord_t = get_nearest_unorm_wrap( sampler->wrap_t );
33884fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell      samp->nearest_texcoord_p = get_nearest_unorm_wrap( sampler->wrap_r );
33894fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   }
33904fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
3391ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   samp->min_img_filter = sampler->min_img_filter;
33924fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
33934fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   switch (sampler->min_mip_filter) {
33944fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_MIPFILTER_NONE:
3395ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      if (sampler->min_img_filter == sampler->mag_img_filter)
3396b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowak         samp->filter_funcs = &funcs_none_no_filter_select;
3397b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul      else
3398b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowak         samp->filter_funcs = &funcs_none;
339934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul      break;
34004fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
34014fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_MIPFILTER_NEAREST:
3402b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowak      samp->filter_funcs = &funcs_nearest;
340334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul      break;
34044fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
34054fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   case PIPE_TEX_MIPFILTER_LINEAR:
3406ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      if (sampler->min_img_filter == sampler->mag_img_filter &&
34074fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell          sampler->normalized_coords &&
34084fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell          sampler->wrap_s == PIPE_TEX_WRAP_REPEAT &&
3409cf102b031e7ef33c8e3ffce2f9dcd064f44e8190Brian Paul          sampler->wrap_t == PIPE_TEX_WRAP_REPEAT &&
3410ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger          sampler->min_img_filter == PIPE_TEX_FILTER_LINEAR &&
3411ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger          sampler->max_anisotropy <= 1) {
3412ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         samp->min_mag_equal_repeat_linear = TRUE;
34136142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell      }
3414b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowak      samp->filter_funcs = &funcs_linear;
3415ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3416f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      /* Anisotropic filtering extension. */
3417f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      if (sampler->max_anisotropy > 1) {
3418b9bc6c42c96773a5784897c55da5387045c0e9b3Krzesimir Nowak         samp->filter_funcs = &funcs_linear_aniso;
3419ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3420ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         /* Override min_img_filter:
3421ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger          * min_img_filter needs to be set to NEAREST since we need to access
3422ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger          * each texture pixel as it is and weight it later; using linear
3423ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger          * filters will have incorrect results.
3424ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger          * By setting the filter to NEAREST here, we can avoid calling the
3425ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger          * generic img_filter_2d_nearest in the anisotropic filter function,
3426ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger          * making it possible to use one of the accelerated implementations
3427ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger          */
3428ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         samp->min_img_filter = PIPE_TEX_FILTER_NEAREST;
3429ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3430ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         /* on first access create the lookup table containing the filter weights. */
3431f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger        if (!weightLut) {
3432f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger           create_filter_table();
3433f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger        }
3434f4537f99cc83cb8133f66dc97c613e95dc0fe162Andreas Fänger      }
343534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul      break;
343634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul   }
3437ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   if (samp->min_img_filter == sampler->mag_img_filter) {
3438ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      samp->min_mag_equal = TRUE;
34394fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell   }
34404fc7d0345a18042a79686940fb7cc4e698cc9192Keith Whitwell
3441ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   return (void *)samp;
3442ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger}
3443c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul
3444ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3445ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggercompute_lambda_func
3446ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggersoftpipe_get_lambda_func(const struct pipe_sampler_view *view, unsigned shader)
3447ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger{
3448ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   if (shader != PIPE_SHADER_FRAGMENT)
3449ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return compute_lambda_vert;
3450ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3451adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger   switch (view->target) {
3452ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_BUFFER:
3453ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_1D:
3454ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_1D_ARRAY:
3455ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return compute_lambda_1d;
3456ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_2D:
3457ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_2D_ARRAY:
3458ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_RECT:
3459ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_CUBE:
3460ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_CUBE_ARRAY:
3461ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return compute_lambda_2d;
3462ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   case PIPE_TEXTURE_3D:
3463ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return compute_lambda_3d;
3464ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   default:
3465ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      assert(0);
3466ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      return compute_lambda_1d;
3467c62bb90d6a864468fe1a717aebb9c1a9c43bf3c8Brian Paul   }
3468ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger}
3469ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3470ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3471ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggerstruct pipe_sampler_view *
3472ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheideggersoftpipe_create_sampler_view(struct pipe_context *pipe,
3473ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                             struct pipe_resource *resource,
3474ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger                             const struct pipe_sampler_view *templ)
3475ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger{
3476ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   struct sp_sampler_view *sview = CALLOC_STRUCT(sp_sampler_view);
34772135aba8d99d5b0b5f73d97d4aac6a25d69de57cKrzesimir Nowak   const struct softpipe_resource *spr = (struct softpipe_resource *)resource;
3478ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3479ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   if (sview) {
3480ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      struct pipe_sampler_view *view = &sview->base;
3481ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      *view = *templ;
3482ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      view->reference.count = 1;
3483ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      view->texture = NULL;
3484ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      pipe_resource_reference(&view->texture, resource);
3485ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      view->context = pipe;
3486ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3487adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger#ifdef DEBUG
3488adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger     /*
3489adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      * This is possibly too lenient, but the primary reason is just
3490adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      * to catch state trackers which forget to initialize this, so
3491adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      * it only catches clearly impossible view targets.
3492adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      */
3493adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      if (view->target != resource->target) {
3494adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger         if (view->target == PIPE_TEXTURE_1D)
3495adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger            assert(resource->target == PIPE_TEXTURE_1D_ARRAY);
3496adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger         else if (view->target == PIPE_TEXTURE_1D_ARRAY)
3497adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger            assert(resource->target == PIPE_TEXTURE_1D);
3498adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger         else if (view->target == PIPE_TEXTURE_2D)
3499adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger            assert(resource->target == PIPE_TEXTURE_2D_ARRAY ||
3500adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                   resource->target == PIPE_TEXTURE_CUBE ||
3501adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                   resource->target == PIPE_TEXTURE_CUBE_ARRAY);
3502adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger         else if (view->target == PIPE_TEXTURE_2D_ARRAY)
3503adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger            assert(resource->target == PIPE_TEXTURE_2D ||
3504adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                   resource->target == PIPE_TEXTURE_CUBE ||
3505adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                   resource->target == PIPE_TEXTURE_CUBE_ARRAY);
3506adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger         else if (view->target == PIPE_TEXTURE_CUBE)
3507adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger            assert(resource->target == PIPE_TEXTURE_CUBE_ARRAY ||
3508adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                   resource->target == PIPE_TEXTURE_2D_ARRAY);
3509adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger         else if (view->target == PIPE_TEXTURE_CUBE_ARRAY)
3510adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger            assert(resource->target == PIPE_TEXTURE_CUBE ||
3511adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                   resource->target == PIPE_TEXTURE_2D_ARRAY);
3512adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger         else
3513adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger            assert(0);
3514adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger      }
3515adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger#endif
3516adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger
3517ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      if (any_swizzle(view)) {
3518ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger         sview->need_swizzle = TRUE;
3519ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      }
3520ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3521ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak      sview->need_cube_convert = (view->target == PIPE_TEXTURE_CUBE ||
3522ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak                                  view->target == PIPE_TEXTURE_CUBE_ARRAY);
3523ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      sview->pot2d = spr->pot &&
3524adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                     (view->target == PIPE_TEXTURE_2D ||
3525adcf8f8a13717f7eb53b2aa86c4b56e344f2f317Roland Scheidegger                      view->target == PIPE_TEXTURE_RECT);
3526ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3527ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      sview->xpot = util_logbase2( resource->width0 );
3528ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger      sview->ypot = util_logbase2( resource->height0 );
35296142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell   }
35306142de393fe34ff0866f8489f1292eb473276f11Keith Whitwell
3531ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   return (struct pipe_sampler_view *) sview;
353234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul}
35336b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger
35346b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger
3535231687c19b3c6ab4f5bead7469b7b27fdbda6d43Krzesimir Nowakstatic inline const struct sp_tgsi_sampler *
3536231687c19b3c6ab4f5bead7469b7b27fdbda6d43Krzesimir Nowaksp_tgsi_sampler_cast_c(const struct tgsi_sampler *sampler)
3537231687c19b3c6ab4f5bead7469b7b27fdbda6d43Krzesimir Nowak{
3538231687c19b3c6ab4f5bead7469b7b27fdbda6d43Krzesimir Nowak   return (const struct sp_tgsi_sampler *)sampler;
3539231687c19b3c6ab4f5bead7469b7b27fdbda6d43Krzesimir Nowak}
3540231687c19b3c6ab4f5bead7469b7b27fdbda6d43Krzesimir Nowak
3541231687c19b3c6ab4f5bead7469b7b27fdbda6d43Krzesimir Nowak
35426b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheideggerstatic void
35436b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheideggersp_tgsi_get_dims(struct tgsi_sampler *tgsi_sampler,
35446b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                 const unsigned sview_index,
35456b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                 int level, int dims[4])
35466b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger{
3547231687c19b3c6ab4f5bead7469b7b27fdbda6d43Krzesimir Nowak   const struct sp_tgsi_sampler *sp_samp =
3548231687c19b3c6ab4f5bead7469b7b27fdbda6d43Krzesimir Nowak      sp_tgsi_sampler_cast_c(tgsi_sampler);
35496b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger
3550ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   assert(sview_index < PIPE_MAX_SHADER_SAMPLER_VIEWS);
3551bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger   /* always have a view here but texture is NULL if no sampler view was set. */
3552bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger   if (!sp_samp->sp_sview[sview_index].base.texture) {
3553bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger      dims[0] = dims[1] = dims[2] = dims[3] = 0;
3554bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger      return;
3555bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger   }
3556ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   sp_get_dims(&sp_samp->sp_sview[sview_index], level, dims);
35576b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger}
35586b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger
35596b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger
35606b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheideggerstatic void
35616b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheideggersp_tgsi_get_samples(struct tgsi_sampler *tgsi_sampler,
35626b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                    const unsigned sview_index,
35636b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                    const unsigned sampler_index,
35646b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                    const float s[TGSI_QUAD_SIZE],
35656b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                    const float t[TGSI_QUAD_SIZE],
35666b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                    const float p[TGSI_QUAD_SIZE],
35676b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                    const float c0[TGSI_QUAD_SIZE],
35686b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                    const float lod[TGSI_QUAD_SIZE],
35696ace2e41da7dded630d932d03bacb7e14a93d47aRoland Scheidegger                    float derivs[3][2][TGSI_QUAD_SIZE],
35706ace2e41da7dded630d932d03bacb7e14a93d47aRoland Scheidegger                    const int8_t offset[3],
35716b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                    enum tgsi_sampler_control control,
35726b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                    float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
35736b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger{
3574231687c19b3c6ab4f5bead7469b7b27fdbda6d43Krzesimir Nowak   const struct sp_tgsi_sampler *sp_tgsi_samp =
3575231687c19b3c6ab4f5bead7469b7b27fdbda6d43Krzesimir Nowak      sp_tgsi_sampler_cast_c(tgsi_sampler);
3576231687c19b3c6ab4f5bead7469b7b27fdbda6d43Krzesimir Nowak   const struct sp_sampler_view *sp_sview;
3577231687c19b3c6ab4f5bead7469b7b27fdbda6d43Krzesimir Nowak   const struct sp_sampler *sp_samp;
35788bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie   struct filter_args filt_args;
3579ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak
3580ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   assert(sview_index < PIPE_MAX_SHADER_SAMPLER_VIEWS);
3581ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   assert(sampler_index < PIPE_MAX_SAMPLERS);
3582ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak   assert(sp_tgsi_samp->sp_sampler[sampler_index]);
3583ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak
3584ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak   sp_sview = &sp_tgsi_samp->sp_sview[sview_index];
3585ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak   sp_samp = sp_tgsi_samp->sp_sampler[sampler_index];
3586bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger   /* always have a view here but texture is NULL if no sampler view was set. */
3587ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak   if (!sp_sview->base.texture) {
3588bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger      int i, j;
3589bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger      for (j = 0; j < TGSI_NUM_CHANNELS; j++) {
3590bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger         for (i = 0; i < TGSI_QUAD_SIZE; i++) {
3591bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger            rgba[j][i] = 0.0f;
3592bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger         }
3593bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger      }
3594bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger      return;
3595bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger   }
35968bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie
35978bec83a30761d52088fa5cd2301b469b7aacf755Dave Airlie   filt_args.control = control;
35983f5c67d6510fe0210079ddecc0d30227a6cc4111Dave Airlie   filt_args.offset = offset;
3599ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak
3600ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak   if (sp_sview->need_cube_convert) {
3601ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak      float cs[TGSI_QUAD_SIZE];
3602ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak      float ct[TGSI_QUAD_SIZE];
3603ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak      float cp[TGSI_QUAD_SIZE];
360408ceb5e076328bf6ccceed3a8e5de205dcaf63b0Krzesimir Nowak      uint faces[TGSI_QUAD_SIZE];
3605ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak
36064ca2896e8ea1908ea5a0d5bffe8a1b42145a6f72Krzesimir Nowak      convert_cube(sp_sview, sp_samp, s, t, p, c0, cs, ct, cp, faces);
3607ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak
36084ca2896e8ea1908ea5a0d5bffe8a1b42145a6f72Krzesimir Nowak      filt_args.faces = faces;
3609ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak      sample_mip(sp_sview, sp_samp, cs, ct, cp, c0, lod, &filt_args, rgba);
3610ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak   } else {
361108ceb5e076328bf6ccceed3a8e5de205dcaf63b0Krzesimir Nowak      static const uint zero_faces[TGSI_QUAD_SIZE] = {0, 0, 0, 0};
36124ca2896e8ea1908ea5a0d5bffe8a1b42145a6f72Krzesimir Nowak
36134ca2896e8ea1908ea5a0d5bffe8a1b42145a6f72Krzesimir Nowak      filt_args.faces = zero_faces;
3614ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak      sample_mip(sp_sview, sp_samp, s, t, p, c0, lod, &filt_args, rgba);
3615ac3637dda04fe1315f19099bd142e4f8f6754b1dKrzesimir Nowak   }
36166b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger}
36176b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger
361860905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowakstatic void
3619ba72e6cfb8248ae0d8b3cf5ebf9add7c49f45743Krzesimir Nowaksp_tgsi_query_lod(const struct tgsi_sampler *tgsi_sampler,
362060905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak                  const unsigned sview_index,
362160905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak                  const unsigned sampler_index,
362260905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak                  const float s[TGSI_QUAD_SIZE],
362360905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak                  const float t[TGSI_QUAD_SIZE],
362460905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak                  const float p[TGSI_QUAD_SIZE],
362560905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak                  const float c0[TGSI_QUAD_SIZE],
362660905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak                  const enum tgsi_sampler_control control,
362760905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak                  float mipmap[TGSI_QUAD_SIZE],
362860905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak                  float lod[TGSI_QUAD_SIZE])
362960905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak{
363060905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak   static const float lod_in[TGSI_QUAD_SIZE] = { 0.0, 0.0, 0.0, 0.0 };
363160905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak
3632ea0fecd1a3f46439c602e04870b34e6f27ad5b2eKrzesimir Nowak   const struct sp_tgsi_sampler *sp_tgsi_samp =
3633231687c19b3c6ab4f5bead7469b7b27fdbda6d43Krzesimir Nowak      sp_tgsi_sampler_cast_c(tgsi_sampler);
3634ea0fecd1a3f46439c602e04870b34e6f27ad5b2eKrzesimir Nowak   const struct sp_sampler_view *sp_sview;
3635ea0fecd1a3f46439c602e04870b34e6f27ad5b2eKrzesimir Nowak   const struct sp_sampler *sp_samp;
363660905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak   const struct sp_filter_funcs *funcs;
363760905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak   int i;
363860905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak
363960905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak   assert(sview_index < PIPE_MAX_SHADER_SAMPLER_VIEWS);
364060905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak   assert(sampler_index < PIPE_MAX_SAMPLERS);
364160905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak   assert(sp_tgsi_samp->sp_sampler[sampler_index]);
364260905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak
364360905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak   sp_sview = &sp_tgsi_samp->sp_sview[sview_index];
364460905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak   sp_samp = sp_tgsi_samp->sp_sampler[sampler_index];
364560905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak   /* always have a view here but texture is NULL if no sampler view was
364660905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak    * set. */
364760905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak   if (!sp_sview->base.texture) {
364860905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak      for (i = 0; i < TGSI_QUAD_SIZE; i++) {
364960905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak         mipmap[i] = 0.0f;
365060905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak         lod[i] = 0.0f;
365160905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak      }
365260905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak      return;
365360905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak   }
365460905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak
365560905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak   if (sp_sview->need_cube_convert) {
365660905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak      float cs[TGSI_QUAD_SIZE];
365760905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak      float ct[TGSI_QUAD_SIZE];
365860905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak      float cp[TGSI_QUAD_SIZE];
365908ceb5e076328bf6ccceed3a8e5de205dcaf63b0Krzesimir Nowak      uint unused_faces[TGSI_QUAD_SIZE];
366060905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak
36614ca2896e8ea1908ea5a0d5bffe8a1b42145a6f72Krzesimir Nowak      convert_cube(sp_sview, sp_samp, s, t, p, c0, cs, ct, cp, unused_faces);
366260905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak      compute_lambda_lod_unclamped(sp_sview, sp_samp,
366360905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak                                   cs, ct, cp, lod_in, control, lod);
366460905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak   } else {
366560905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak      compute_lambda_lod_unclamped(sp_sview, sp_samp,
366660905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak                                   s, t, p, lod_in, control, lod);
366760905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak   }
366860905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak
366960905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak   get_filters(sp_sview, sp_samp, control, &funcs, NULL, NULL);
367060905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak   funcs->relative_level(sp_sview, sp_samp, lod, mipmap);
367160905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak}
36726b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger
36736b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheideggerstatic void
36746b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheideggersp_tgsi_get_texel(struct tgsi_sampler *tgsi_sampler,
36756b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                  const unsigned sview_index,
36766b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                  const int i[TGSI_QUAD_SIZE],
36776b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                  const int j[TGSI_QUAD_SIZE], const int k[TGSI_QUAD_SIZE],
36786b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                  const int lod[TGSI_QUAD_SIZE], const int8_t offset[3],
36796b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger                  float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
36806b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger{
3681231687c19b3c6ab4f5bead7469b7b27fdbda6d43Krzesimir Nowak   const struct sp_tgsi_sampler *sp_samp =
3682231687c19b3c6ab4f5bead7469b7b27fdbda6d43Krzesimir Nowak      sp_tgsi_sampler_cast_c(tgsi_sampler);
3683ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger
3684ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   assert(sview_index < PIPE_MAX_SHADER_SAMPLER_VIEWS);
3685bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger   /* always have a view here but texture is NULL if no sampler view was set. */
3686bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger   if (!sp_samp->sp_sview[sview_index].base.texture) {
3687bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger      int i, j;
3688bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger      for (j = 0; j < TGSI_NUM_CHANNELS; j++) {
3689bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger         for (i = 0; i < TGSI_QUAD_SIZE; i++) {
3690bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger            rgba[j][i] = 0.0f;
3691bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger         }
3692bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger      }
3693bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger      return;
3694bb7dc1b2f68bd9b8dc267a6314cea336cb36e1b7Roland Scheidegger   }
3695ef17cc9cb697a7146cf2a3dba2eb0f6a968918ccRoland Scheidegger   sp_get_texels(&sp_samp->sp_sview[sview_index], i, j, k, lod, offset, rgba);
36966b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger}
36976b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger
36986b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger
36996b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheideggerstruct sp_tgsi_sampler *
37006b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheideggersp_create_tgsi_sampler(void)
37016b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger{
37026b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger   struct sp_tgsi_sampler *samp = CALLOC_STRUCT(sp_tgsi_sampler);
37036b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger   if (!samp)
37046b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger      return NULL;
37056b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger
37066b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger   samp->base.get_dims = sp_tgsi_get_dims;
37076b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger   samp->base.get_samples = sp_tgsi_get_samples;
37086b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger   samp->base.get_texel = sp_tgsi_get_texel;
370960905f2b19e13b03b5ae981e36ac434c6a4529aeKrzesimir Nowak   samp->base.query_lod = sp_tgsi_query_lod;
37106b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger
37116b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger   return samp;
37126b35c2b110be0d9ae6a292250fdcbab11a9190a5Roland Scheidegger}
3713