sp_tex_sample.c revision 3d53d38d5e35386de4793162b9dd32e171927059
10dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul/************************************************************************** 20dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * 30dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 40dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * All Rights Reserved. 50dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * 60dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * Permission is hereby granted, free of charge, to any person obtaining a 70dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * copy of this software and associated documentation files (the 80dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * "Software"), to deal in the Software without restriction, including 90dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * without limitation the rights to use, copy, modify, merge, publish, 100dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * distribute, sub license, and/or sell copies of the Software, and to 110dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * permit persons to whom the Software is furnished to do so, subject to 120dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * the following conditions: 130dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * 140dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * The above copyright notice and this permission notice (including the 150dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * next paragraph) shall be included in all copies or substantial portions 160dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * of the Software. 170dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * 180dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 190dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 200dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 210dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 220dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 230dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 240dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 250dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * 260dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul **************************************************************************/ 270dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul 280dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul/** 290dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * Texture sampling 300dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * 310dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * Authors: 320dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * Brian Paul 330dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul */ 340dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul 3508f33a025100dea2d951e6d628891fe294b18082Brian Paul#include "sp_context.h" 36b91de8a6e7d74d38698b6dad9f34040e484e69afBrian Paul#include "sp_headers.h" 370dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul#include "sp_surface.h" 380dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul#include "sp_tex_sample.h" 3970eb7996f265f3634dabda078f13d1be3533cc65Brian Paul#include "sp_tile_cache.h" 400dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul#include "pipe/p_context.h" 410dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul#include "pipe/p_defines.h" 427de874ec2c7b9e3aff7f81b7e30045b45381fbadMichal Krol#include "pipe/p_util.h" 436acd63a4980951727939c0dd545a0324965b3834José Fonseca#include "tgsi/exec/tgsi_exec.h" 440dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul 450dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul 4608f33a025100dea2d951e6d628891fe294b18082Brian Paul/* 4708f33a025100dea2d951e6d628891fe294b18082Brian Paul * Note, the FRAC macro has to work perfectly. Otherwise you'll sometimes 4808f33a025100dea2d951e6d628891fe294b18082Brian Paul * see 1-pixel bands of improperly weighted linear-filtered textures. 4908f33a025100dea2d951e6d628891fe294b18082Brian Paul * The tests/texwrap.c demo is a good test. 5008f33a025100dea2d951e6d628891fe294b18082Brian Paul * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0. 5108f33a025100dea2d951e6d628891fe294b18082Brian Paul * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x). 5208f33a025100dea2d951e6d628891fe294b18082Brian Paul */ 5370af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell#define FRAC(f) ((f) - ifloor(f)) 5408f33a025100dea2d951e6d628891fe294b18082Brian Paul 5508f33a025100dea2d951e6d628891fe294b18082Brian Paul 5608f33a025100dea2d951e6d628891fe294b18082Brian Paul/** 5708f33a025100dea2d951e6d628891fe294b18082Brian Paul * Linear interpolation macro 5808f33a025100dea2d951e6d628891fe294b18082Brian Paul */ 590dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul#define LERP(T, A, B) ( (A) + (T) * ((B) - (A)) ) 600dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul 610dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul 620dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul/** 630dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * Do 2D/biliner interpolation of float values. 640dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * v00, v10, v01 and v11 are typically four texture samples in a square/box. 650dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * a and b are the horizontal and vertical interpolants. 660dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * It's important that this function is inlined when compiled with 670dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * optimization! If we find that's not true on some systems, convert 680dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul * to a macro. 690dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul */ 70b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paulstatic INLINE float 71b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paullerp_2d(float a, float b, 72b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul float v00, float v10, float v01, float v11) 730dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul{ 74b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float temp0 = LERP(a, v00, v10); 75b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float temp1 = LERP(a, v01, v11); 760dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul return LERP(b, temp0, temp1); 770dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul} 780dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul 790dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul 800dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul/** 81906768316d9521a32d9a7eebc9edaf76c06a98a7Brian Paul * If A is a signed integer, A % B doesn't give the right value for A < 0 82906768316d9521a32d9a7eebc9edaf76c06a98a7Brian Paul * (in terms of texture repeat). Just casting to unsigned fixes that. 830dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul */ 84906768316d9521a32d9a7eebc9edaf76c06a98a7Brian Paul#define REMAINDER(A, B) ((unsigned) (A) % (unsigned) (B)) 8508f33a025100dea2d951e6d628891fe294b18082Brian Paul 8608f33a025100dea2d951e6d628891fe294b18082Brian Paul 8708f33a025100dea2d951e6d628891fe294b18082Brian Paul/** 8808f33a025100dea2d951e6d628891fe294b18082Brian Paul * Apply texture coord wrapping mode and return integer texture index. 8908f33a025100dea2d951e6d628891fe294b18082Brian Paul * \param wrapMode PIPE_TEX_WRAP_x 9008f33a025100dea2d951e6d628891fe294b18082Brian Paul * \param s the texcoord 9108f33a025100dea2d951e6d628891fe294b18082Brian Paul * \param size the texture image size 9208f33a025100dea2d951e6d628891fe294b18082Brian Paul * \return integer texture index 9308f33a025100dea2d951e6d628891fe294b18082Brian Paul */ 9470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwellstatic INLINE int 9570af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwellnearest_texcoord(unsigned wrapMode, float s, unsigned size) 960dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul{ 9770af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell int i; 980dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul switch (wrapMode) { 990dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul case PIPE_TEX_WRAP_REPEAT: 10008f33a025100dea2d951e6d628891fe294b18082Brian Paul /* s limited to [0,1) */ 10108f33a025100dea2d951e6d628891fe294b18082Brian Paul /* i limited to [0,size-1] */ 10270af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell i = ifloor(s * size); 103906768316d9521a32d9a7eebc9edaf76c06a98a7Brian Paul i = REMAINDER(i, size); 10408f33a025100dea2d951e6d628891fe294b18082Brian Paul return i; 1050dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul case PIPE_TEX_WRAP_CLAMP: 10608f33a025100dea2d951e6d628891fe294b18082Brian Paul /* s limited to [0,1] */ 10708f33a025100dea2d951e6d628891fe294b18082Brian Paul /* i limited to [0,size-1] */ 10808f33a025100dea2d951e6d628891fe294b18082Brian Paul if (s <= 0.0F) 10908f33a025100dea2d951e6d628891fe294b18082Brian Paul i = 0; 11008f33a025100dea2d951e6d628891fe294b18082Brian Paul else if (s >= 1.0F) 11108f33a025100dea2d951e6d628891fe294b18082Brian Paul i = size - 1; 11208f33a025100dea2d951e6d628891fe294b18082Brian Paul else 11370af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell i = ifloor(s * size); 11408f33a025100dea2d951e6d628891fe294b18082Brian Paul return i; 11508f33a025100dea2d951e6d628891fe294b18082Brian Paul case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 11608f33a025100dea2d951e6d628891fe294b18082Brian Paul { 11708f33a025100dea2d951e6d628891fe294b18082Brian Paul /* s limited to [min,max] */ 11808f33a025100dea2d951e6d628891fe294b18082Brian Paul /* i limited to [0, size-1] */ 119b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float min = 1.0F / (2.0F * size); 120b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float max = 1.0F - min; 12108f33a025100dea2d951e6d628891fe294b18082Brian Paul if (s < min) 12208f33a025100dea2d951e6d628891fe294b18082Brian Paul i = 0; 12308f33a025100dea2d951e6d628891fe294b18082Brian Paul else if (s > max) 12408f33a025100dea2d951e6d628891fe294b18082Brian Paul i = size - 1; 12508f33a025100dea2d951e6d628891fe294b18082Brian Paul else 12670af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell i = ifloor(s * size); 12708f33a025100dea2d951e6d628891fe294b18082Brian Paul } 12808f33a025100dea2d951e6d628891fe294b18082Brian Paul return i; 12908f33a025100dea2d951e6d628891fe294b18082Brian Paul case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 13008f33a025100dea2d951e6d628891fe294b18082Brian Paul { 13108f33a025100dea2d951e6d628891fe294b18082Brian Paul /* s limited to [min,max] */ 13208f33a025100dea2d951e6d628891fe294b18082Brian Paul /* i limited to [-1, size] */ 133b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float min = -1.0F / (2.0F * size); 134b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float max = 1.0F - min; 13508f33a025100dea2d951e6d628891fe294b18082Brian Paul if (s <= min) 13608f33a025100dea2d951e6d628891fe294b18082Brian Paul i = -1; 13708f33a025100dea2d951e6d628891fe294b18082Brian Paul else if (s >= max) 13808f33a025100dea2d951e6d628891fe294b18082Brian Paul i = size; 13908f33a025100dea2d951e6d628891fe294b18082Brian Paul else 14070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell i = ifloor(s * size); 14108f33a025100dea2d951e6d628891fe294b18082Brian Paul } 14208f33a025100dea2d951e6d628891fe294b18082Brian Paul return i; 14308f33a025100dea2d951e6d628891fe294b18082Brian Paul case PIPE_TEX_WRAP_MIRROR_REPEAT: 14408f33a025100dea2d951e6d628891fe294b18082Brian Paul { 145b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float min = 1.0F / (2.0F * size); 146b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float max = 1.0F - min; 14770af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell const int flr = ifloor(s); 148b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul float u; 14908f33a025100dea2d951e6d628891fe294b18082Brian Paul if (flr & 1) 150b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul u = 1.0F - (s - (float) flr); 15108f33a025100dea2d951e6d628891fe294b18082Brian Paul else 152b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul u = s - (float) flr; 15308f33a025100dea2d951e6d628891fe294b18082Brian Paul if (u < min) 15408f33a025100dea2d951e6d628891fe294b18082Brian Paul i = 0; 15508f33a025100dea2d951e6d628891fe294b18082Brian Paul else if (u > max) 15608f33a025100dea2d951e6d628891fe294b18082Brian Paul i = size - 1; 15708f33a025100dea2d951e6d628891fe294b18082Brian Paul else 15870af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell i = ifloor(u * size); 15908f33a025100dea2d951e6d628891fe294b18082Brian Paul } 16008f33a025100dea2d951e6d628891fe294b18082Brian Paul return i; 16108f33a025100dea2d951e6d628891fe294b18082Brian Paul case PIPE_TEX_WRAP_MIRROR_CLAMP: 16208f33a025100dea2d951e6d628891fe294b18082Brian Paul { 16308f33a025100dea2d951e6d628891fe294b18082Brian Paul /* s limited to [0,1] */ 16408f33a025100dea2d951e6d628891fe294b18082Brian Paul /* i limited to [0,size-1] */ 165b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float u = FABSF(s); 16608f33a025100dea2d951e6d628891fe294b18082Brian Paul if (u <= 0.0F) 16708f33a025100dea2d951e6d628891fe294b18082Brian Paul i = 0; 16808f33a025100dea2d951e6d628891fe294b18082Brian Paul else if (u >= 1.0F) 16908f33a025100dea2d951e6d628891fe294b18082Brian Paul i = size - 1; 17008f33a025100dea2d951e6d628891fe294b18082Brian Paul else 17170af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell i = ifloor(u * size); 17208f33a025100dea2d951e6d628891fe294b18082Brian Paul } 17308f33a025100dea2d951e6d628891fe294b18082Brian Paul return i; 17408f33a025100dea2d951e6d628891fe294b18082Brian Paul case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: 17508f33a025100dea2d951e6d628891fe294b18082Brian Paul { 17608f33a025100dea2d951e6d628891fe294b18082Brian Paul /* s limited to [min,max] */ 17708f33a025100dea2d951e6d628891fe294b18082Brian Paul /* i limited to [0, size-1] */ 178b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float min = 1.0F / (2.0F * size); 179b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float max = 1.0F - min; 180b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float u = FABSF(s); 18108f33a025100dea2d951e6d628891fe294b18082Brian Paul if (u < min) 18208f33a025100dea2d951e6d628891fe294b18082Brian Paul i = 0; 18308f33a025100dea2d951e6d628891fe294b18082Brian Paul else if (u > max) 18408f33a025100dea2d951e6d628891fe294b18082Brian Paul i = size - 1; 18508f33a025100dea2d951e6d628891fe294b18082Brian Paul else 18670af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell i = ifloor(u * size); 18708f33a025100dea2d951e6d628891fe294b18082Brian Paul } 18808f33a025100dea2d951e6d628891fe294b18082Brian Paul return i; 18908f33a025100dea2d951e6d628891fe294b18082Brian Paul case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: 19008f33a025100dea2d951e6d628891fe294b18082Brian Paul { 19108f33a025100dea2d951e6d628891fe294b18082Brian Paul /* s limited to [min,max] */ 19208f33a025100dea2d951e6d628891fe294b18082Brian Paul /* i limited to [0, size-1] */ 193b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float min = -1.0F / (2.0F * size); 194b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float max = 1.0F - min; 195b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float u = FABSF(s); 19608f33a025100dea2d951e6d628891fe294b18082Brian Paul if (u < min) 19708f33a025100dea2d951e6d628891fe294b18082Brian Paul i = -1; 19808f33a025100dea2d951e6d628891fe294b18082Brian Paul else if (u > max) 19908f33a025100dea2d951e6d628891fe294b18082Brian Paul i = size; 20008f33a025100dea2d951e6d628891fe294b18082Brian Paul else 20170af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell i = ifloor(u * size); 20208f33a025100dea2d951e6d628891fe294b18082Brian Paul } 20308f33a025100dea2d951e6d628891fe294b18082Brian Paul return i; 2040dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul default: 2050dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul assert(0); 20608f33a025100dea2d951e6d628891fe294b18082Brian Paul return 0; 2070dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul } 2080dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul} 2090dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul 21008f33a025100dea2d951e6d628891fe294b18082Brian Paul 21108f33a025100dea2d951e6d628891fe294b18082Brian Paul/** 21208f33a025100dea2d951e6d628891fe294b18082Brian Paul * Used to compute texel locations for linear sampling. 21308f33a025100dea2d951e6d628891fe294b18082Brian Paul * \param wrapMode PIPE_TEX_WRAP_x 21408f33a025100dea2d951e6d628891fe294b18082Brian Paul * \param s the texcoord 21508f33a025100dea2d951e6d628891fe294b18082Brian Paul * \param size the texture image size 21608f33a025100dea2d951e6d628891fe294b18082Brian Paul * \param i0 returns first texture index 21708f33a025100dea2d951e6d628891fe294b18082Brian Paul * \param i1 returns second texture index (usually *i0 + 1) 21808f33a025100dea2d951e6d628891fe294b18082Brian Paul * \param a returns blend factor/weight between texture indexes 21908f33a025100dea2d951e6d628891fe294b18082Brian Paul */ 2200dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paulstatic INLINE void 22170af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwelllinear_texcoord(unsigned wrapMode, float s, unsigned size, 22270af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell int *i0, int *i1, float *a) 2230dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul{ 224b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul float u; 2250dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul switch (wrapMode) { 2260dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul case PIPE_TEX_WRAP_REPEAT: 22708f33a025100dea2d951e6d628891fe294b18082Brian Paul u = s * size - 0.5F; 228906768316d9521a32d9a7eebc9edaf76c06a98a7Brian Paul *i0 = REMAINDER(ifloor(u), size); 229906768316d9521a32d9a7eebc9edaf76c06a98a7Brian Paul *i1 = REMAINDER(*i0 + 1, size); 2300dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul break; 2310dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul case PIPE_TEX_WRAP_CLAMP: 23208f33a025100dea2d951e6d628891fe294b18082Brian Paul if (s <= 0.0F) 23308f33a025100dea2d951e6d628891fe294b18082Brian Paul u = 0.0F; 23408f33a025100dea2d951e6d628891fe294b18082Brian Paul else if (s >= 1.0F) 235b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul u = (float) size; 23608f33a025100dea2d951e6d628891fe294b18082Brian Paul else 23708f33a025100dea2d951e6d628891fe294b18082Brian Paul u = s * size; 23808f33a025100dea2d951e6d628891fe294b18082Brian Paul u -= 0.5F; 23970af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell *i0 = ifloor(u); 24008f33a025100dea2d951e6d628891fe294b18082Brian Paul *i1 = *i0 + 1; 24108f33a025100dea2d951e6d628891fe294b18082Brian Paul break; 24208f33a025100dea2d951e6d628891fe294b18082Brian Paul case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 24308f33a025100dea2d951e6d628891fe294b18082Brian Paul if (s <= 0.0F) 24408f33a025100dea2d951e6d628891fe294b18082Brian Paul u = 0.0F; 24508f33a025100dea2d951e6d628891fe294b18082Brian Paul else if (s >= 1.0F) 246b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul u = (float) size; 24708f33a025100dea2d951e6d628891fe294b18082Brian Paul else 24808f33a025100dea2d951e6d628891fe294b18082Brian Paul u = s * size; 24908f33a025100dea2d951e6d628891fe294b18082Brian Paul u -= 0.5F; 25070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell *i0 = ifloor(u); 25108f33a025100dea2d951e6d628891fe294b18082Brian Paul *i1 = *i0 + 1; 25208f33a025100dea2d951e6d628891fe294b18082Brian Paul if (*i0 < 0) 25308f33a025100dea2d951e6d628891fe294b18082Brian Paul *i0 = 0; 25470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell if (*i1 >= (int) size) 25508f33a025100dea2d951e6d628891fe294b18082Brian Paul *i1 = size - 1; 25608f33a025100dea2d951e6d628891fe294b18082Brian Paul break; 25708f33a025100dea2d951e6d628891fe294b18082Brian Paul case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 25808f33a025100dea2d951e6d628891fe294b18082Brian Paul { 259b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float min = -1.0F / (2.0F * size); 260b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float max = 1.0F - min; 26108f33a025100dea2d951e6d628891fe294b18082Brian Paul if (s <= min) 26208f33a025100dea2d951e6d628891fe294b18082Brian Paul u = min * size; 26308f33a025100dea2d951e6d628891fe294b18082Brian Paul else if (s >= max) 26408f33a025100dea2d951e6d628891fe294b18082Brian Paul u = max * size; 26508f33a025100dea2d951e6d628891fe294b18082Brian Paul else 26608f33a025100dea2d951e6d628891fe294b18082Brian Paul u = s * size; 26708f33a025100dea2d951e6d628891fe294b18082Brian Paul u -= 0.5F; 26870af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell *i0 = ifloor(u); 26908f33a025100dea2d951e6d628891fe294b18082Brian Paul *i1 = *i0 + 1; 27008f33a025100dea2d951e6d628891fe294b18082Brian Paul } 27108f33a025100dea2d951e6d628891fe294b18082Brian Paul break; 27208f33a025100dea2d951e6d628891fe294b18082Brian Paul case PIPE_TEX_WRAP_MIRROR_REPEAT: 27308f33a025100dea2d951e6d628891fe294b18082Brian Paul { 27470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell const int flr = ifloor(s); 27508f33a025100dea2d951e6d628891fe294b18082Brian Paul if (flr & 1) 276b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul u = 1.0F - (s - (float) flr); 27708f33a025100dea2d951e6d628891fe294b18082Brian Paul else 278b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul u = s - (float) flr; 27908f33a025100dea2d951e6d628891fe294b18082Brian Paul u = (u * size) - 0.5F; 28070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell *i0 = ifloor(u); 28108f33a025100dea2d951e6d628891fe294b18082Brian Paul *i1 = *i0 + 1; 28208f33a025100dea2d951e6d628891fe294b18082Brian Paul if (*i0 < 0) 28308f33a025100dea2d951e6d628891fe294b18082Brian Paul *i0 = 0; 28470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell if (*i1 >= (int) size) 28508f33a025100dea2d951e6d628891fe294b18082Brian Paul *i1 = size - 1; 28608f33a025100dea2d951e6d628891fe294b18082Brian Paul } 28708f33a025100dea2d951e6d628891fe294b18082Brian Paul break; 28808f33a025100dea2d951e6d628891fe294b18082Brian Paul case PIPE_TEX_WRAP_MIRROR_CLAMP: 28908f33a025100dea2d951e6d628891fe294b18082Brian Paul u = FABSF(s); 29008f33a025100dea2d951e6d628891fe294b18082Brian Paul if (u >= 1.0F) 291b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul u = (float) size; 29208f33a025100dea2d951e6d628891fe294b18082Brian Paul else 29308f33a025100dea2d951e6d628891fe294b18082Brian Paul u *= size; 29408f33a025100dea2d951e6d628891fe294b18082Brian Paul u -= 0.5F; 29570af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell *i0 = ifloor(u); 29608f33a025100dea2d951e6d628891fe294b18082Brian Paul *i1 = *i0 + 1; 29708f33a025100dea2d951e6d628891fe294b18082Brian Paul break; 29808f33a025100dea2d951e6d628891fe294b18082Brian Paul case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: 29908f33a025100dea2d951e6d628891fe294b18082Brian Paul u = FABSF(s); 30008f33a025100dea2d951e6d628891fe294b18082Brian Paul if (u >= 1.0F) 301b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul u = (float) size; 30208f33a025100dea2d951e6d628891fe294b18082Brian Paul else 30308f33a025100dea2d951e6d628891fe294b18082Brian Paul u *= size; 30408f33a025100dea2d951e6d628891fe294b18082Brian Paul u -= 0.5F; 30570af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell *i0 = ifloor(u); 30608f33a025100dea2d951e6d628891fe294b18082Brian Paul *i1 = *i0 + 1; 30708f33a025100dea2d951e6d628891fe294b18082Brian Paul if (*i0 < 0) 30808f33a025100dea2d951e6d628891fe294b18082Brian Paul *i0 = 0; 30970af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell if (*i1 >= (int) size) 31008f33a025100dea2d951e6d628891fe294b18082Brian Paul *i1 = size - 1; 31108f33a025100dea2d951e6d628891fe294b18082Brian Paul break; 31208f33a025100dea2d951e6d628891fe294b18082Brian Paul case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: 31308f33a025100dea2d951e6d628891fe294b18082Brian Paul { 314b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float min = -1.0F / (2.0F * size); 315b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float max = 1.0F - min; 31608f33a025100dea2d951e6d628891fe294b18082Brian Paul u = FABSF(s); 31708f33a025100dea2d951e6d628891fe294b18082Brian Paul if (u <= min) 31808f33a025100dea2d951e6d628891fe294b18082Brian Paul u = min * size; 31908f33a025100dea2d951e6d628891fe294b18082Brian Paul else if (u >= max) 32008f33a025100dea2d951e6d628891fe294b18082Brian Paul u = max * size; 32108f33a025100dea2d951e6d628891fe294b18082Brian Paul else 32208f33a025100dea2d951e6d628891fe294b18082Brian Paul u *= size; 32308f33a025100dea2d951e6d628891fe294b18082Brian Paul u -= 0.5F; 32470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell *i0 = ifloor(u); 32508f33a025100dea2d951e6d628891fe294b18082Brian Paul *i1 = *i0 + 1; 32608f33a025100dea2d951e6d628891fe294b18082Brian Paul } 3270dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul break; 3280dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul default: 3290dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul assert(0); 3300dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul } 33108f33a025100dea2d951e6d628891fe294b18082Brian Paul *a = FRAC(u); 3320dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul} 3330dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul 3340dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul 335b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul/** 336b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul * For RECT textures / unnormalized texcoords 337b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul * Only a subset of wrap modes supported. 338b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul */ 339b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paulstatic INLINE int 340b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paulnearest_texcoord_unnorm(unsigned wrapMode, float s, unsigned size) 341b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul{ 342b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul int i; 343b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul switch (wrapMode) { 344b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul case PIPE_TEX_WRAP_CLAMP: 345b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul i = ifloor(s); 34669a7c9739bc0f11e66e11ab410d813fa69fe5fc9Michal Krol return CLAMP(i, 0, (int) size-1); 347b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 348b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul /* fall-through */ 349b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 3504ec46e4869b60b60c7ddf43168604713b5c4c359Brian Paul return ifloor( CLAMP(s, 0.5F, (float) size - 0.5F) ); 351b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul default: 352b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul assert(0); 353b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul return 0; 354b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul } 355b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul} 356b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul 357b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul 358b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul/** 359b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul * For RECT textures / unnormalized texcoords. 360b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul * Only a subset of wrap modes supported. 361b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul */ 362b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paulstatic INLINE void 363b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paullinear_texcoord_unnorm(unsigned wrapMode, float s, unsigned size, 364b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul int *i0, int *i1, float *a) 365b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul{ 366b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul switch (wrapMode) { 367b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul case PIPE_TEX_WRAP_CLAMP: 368b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul /* Not exactly what the spec says, but it matches NVIDIA output */ 36969a7c9739bc0f11e66e11ab410d813fa69fe5fc9Michal Krol s = CLAMP(s - 0.5F, 0.0f, (float) size - 1.0f); 370b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul *i0 = ifloor(s); 371b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul *i1 = *i0 + 1; 372b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul break; 373b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 374b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul /* fall-through */ 375b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 3764ec46e4869b60b60c7ddf43168604713b5c4c359Brian Paul s = CLAMP(s, 0.5F, (float) size - 0.5F); 377b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul s -= 0.5F; 378b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul *i0 = ifloor(s); 379b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul *i1 = *i0 + 1; 38069a7c9739bc0f11e66e11ab410d813fa69fe5fc9Michal Krol if (*i1 > (int) size - 1) 381b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul *i1 = size - 1; 382b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul break; 383b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul default: 384b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul assert(0); 385b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul } 386b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul *a = FRAC(s); 387b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul} 388b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul 389b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul 39070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwellstatic unsigned 391a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paulchoose_cube_face(float rx, float ry, float rz, float *newS, float *newT) 39234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul{ 39334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul /* 39434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul major axis 39534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul direction target sc tc ma 39634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul ---------- ------------------------------- --- --- --- 39734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul +rx TEXTURE_CUBE_MAP_POSITIVE_X_EXT -rz -ry rx 39834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul -rx TEXTURE_CUBE_MAP_NEGATIVE_X_EXT +rz -ry rx 39934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul +ry TEXTURE_CUBE_MAP_POSITIVE_Y_EXT +rx +rz ry 40034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul -ry TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT +rx -rz ry 40134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul +rz TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz 40234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul -rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz 40334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul */ 404b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float arx = FABSF(rx), ary = FABSF(ry), arz = FABSF(rz); 40570af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell unsigned face; 406b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul float sc, tc, ma; 40734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul 40834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul if (arx > ary && arx > arz) { 40934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul if (rx >= 0.0F) { 41034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul face = PIPE_TEX_FACE_POS_X; 41134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul sc = -rz; 41234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul tc = -ry; 41334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul ma = arx; 41434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul } 41534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul else { 41634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul face = PIPE_TEX_FACE_NEG_X; 41734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul sc = rz; 41834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul tc = -ry; 41934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul ma = arx; 42034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul } 42134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul } 42234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul else if (ary > arx && ary > arz) { 42334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul if (ry >= 0.0F) { 42434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul face = PIPE_TEX_FACE_POS_Y; 42534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul sc = rx; 42634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul tc = rz; 42734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul ma = ary; 42834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul } 42934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul else { 43034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul face = PIPE_TEX_FACE_NEG_Y; 43134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul sc = rx; 43234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul tc = -rz; 43334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul ma = ary; 43434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul } 43534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul } 43634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul else { 43734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul if (rz > 0.0F) { 43834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul face = PIPE_TEX_FACE_POS_Z; 43934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul sc = rx; 44034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul tc = -ry; 44134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul ma = arz; 44234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul } 44334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul else { 44434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul face = PIPE_TEX_FACE_NEG_Z; 44534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul sc = -rx; 44634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul tc = -ry; 44734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul ma = arz; 44834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul } 44934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul } 45034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul 451a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul *newS = ( sc / ma + 1.0F ) * 0.5F; 452a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul *newT = ( tc / ma + 1.0F ) * 0.5F; 45334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul 45434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul return face; 45534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul} 45634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul 45734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul 458b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul/** 459b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul * Examine the quad's texture coordinates to compute the partial 460b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul * derivatives w.r.t X and Y, then compute lambda (level of detail). 461b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul * 462b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul * This is only done for fragment shaders, not vertex shaders. 463b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul */ 464b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paulstatic float 465b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paulcompute_lambda(struct tgsi_sampler *sampler, 466b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float s[QUAD_SIZE], 467b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float t[QUAD_SIZE], 468f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul const float p[QUAD_SIZE], 469f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul float lodbias) 470b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul{ 471b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul float rho, lambda; 472b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul 473b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul assert(sampler->state->normalized_coords); 474b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul 475b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul assert(s); 476b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul { 477b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul float dsdx = s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]; 478b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul float dsdy = s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]; 479b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul dsdx = FABSF(dsdx); 480b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul dsdy = FABSF(dsdy); 481b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul rho = MAX2(dsdx, dsdy) * sampler->texture->width[0]; 482b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul } 483b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul if (t) { 484b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]; 485b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul float dtdy = t[QUAD_TOP_LEFT] - t[QUAD_BOTTOM_LEFT]; 486b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul float max; 487b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul dtdx = FABSF(dtdx); 488b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul dtdy = FABSF(dtdy); 489b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul max = MAX2(dtdx, dtdy) * sampler->texture->height[0]; 490b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul rho = MAX2(rho, max); 491b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul } 492b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul if (p) { 493b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul float dpdx = p[QUAD_BOTTOM_RIGHT] - p[QUAD_BOTTOM_LEFT]; 494b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul float dpdy = p[QUAD_TOP_LEFT] - p[QUAD_BOTTOM_LEFT]; 495b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul float max; 496b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul dpdx = FABSF(dpdx); 497b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul dpdy = FABSF(dpdy); 498b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul max = MAX2(dpdx, dpdy) * sampler->texture->depth[0]; 499b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul rho = MAX2(rho, max); 500b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul } 501b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul 502b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul lambda = LOG2(rho); 503f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul lambda += lodbias + sampler->state->lod_bias; 504b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul lambda = CLAMP(lambda, sampler->state->min_lod, sampler->state->max_lod); 505b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul 506b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul return lambda; 507b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul} 508b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul 509b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul 510f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul/** 511c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul * Do several things here: 512c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul * 1. Compute lambda from the texcoords, if needed 513c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul * 2. Determine if we're minifying or magnifying 514c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul * 3. If minifying, choose mipmap levels 515c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul * 4. Return image filter to use within mipmap images 516f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul */ 517f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paulstatic void 518c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paulchoose_mipmap_levels(struct tgsi_sampler *sampler, 519c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul const float s[QUAD_SIZE], 520c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul const float t[QUAD_SIZE], 521c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul const float p[QUAD_SIZE], 522c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul float lodbias, 523c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul unsigned *level0, unsigned *level1, float *levelBlend, 524c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul unsigned *imgFilter) 52509a1b912605ff48c8782dcc5aae55ac77e27037bBrian Paul{ 526c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) { 527c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul /* no mipmap selection needed */ 5280c6bbd41bd6dc1041eaca7c907d3768d107c1afaBrian Paul *level0 = *level1 = CLAMP((int) sampler->state->min_lod, 5290c6bbd41bd6dc1041eaca7c907d3768d107c1afaBrian Paul 0, (int) sampler->texture->last_level); 53008c9534107fcaf06f9b801551524ed5dc724db13Brian Paul 53108c9534107fcaf06f9b801551524ed5dc724db13Brian Paul if (sampler->state->min_img_filter != sampler->state->mag_img_filter) { 53208c9534107fcaf06f9b801551524ed5dc724db13Brian Paul /* non-mipmapped texture, but still need to determine if doing 53308c9534107fcaf06f9b801551524ed5dc724db13Brian Paul * minification or magnification. 53408c9534107fcaf06f9b801551524ed5dc724db13Brian Paul */ 53508c9534107fcaf06f9b801551524ed5dc724db13Brian Paul float lambda = compute_lambda(sampler, s, t, p, lodbias); 5363b2a291888d8e62787de03f8529806fb562bd186Brian Paul if (lambda <= 0.0) { 53708c9534107fcaf06f9b801551524ed5dc724db13Brian Paul *imgFilter = sampler->state->mag_img_filter; 53808c9534107fcaf06f9b801551524ed5dc724db13Brian Paul } 53908c9534107fcaf06f9b801551524ed5dc724db13Brian Paul else { 54008c9534107fcaf06f9b801551524ed5dc724db13Brian Paul *imgFilter = sampler->state->min_img_filter; 54108c9534107fcaf06f9b801551524ed5dc724db13Brian Paul } 54208c9534107fcaf06f9b801551524ed5dc724db13Brian Paul } 5433b2a291888d8e62787de03f8529806fb562bd186Brian Paul else { 5443b2a291888d8e62787de03f8529806fb562bd186Brian Paul *imgFilter = sampler->state->mag_img_filter; 5453b2a291888d8e62787de03f8529806fb562bd186Brian Paul } 546c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul } 547c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul else { 548c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul float lambda; 549c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul 550c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul if (1) 551c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul /* fragment shader */ 552c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul lambda = compute_lambda(sampler, s, t, p, lodbias); 553c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul else 554c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul /* vertex shader */ 555c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul lambda = lodbias; /* not really a bias, but absolute LOD */ 556c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul 5573b2a291888d8e62787de03f8529806fb562bd186Brian Paul if (lambda <= 0.0) { /* XXX threshold depends on the filter */ 558c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul /* magnifying */ 559c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul *imgFilter = sampler->state->mag_img_filter; 5604da1cdf78fa3b954840650fa46cf72da5daf149fBrian Paul *level0 = *level1 = 0; 561f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul } 562c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul else { 563c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul /* minifying */ 564c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul *imgFilter = sampler->state->min_img_filter; 565c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul 566c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul /* choose mipmap level(s) and compute the blend factor between them */ 567c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NEAREST) { 568c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul /* Nearest mipmap level */ 569c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul const int lvl = (int) (lambda + 0.5); 570c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul *level0 = 5714da1cdf78fa3b954840650fa46cf72da5daf149fBrian Paul *level1 = CLAMP(lvl, 0, (int) sampler->texture->last_level); 572c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul } 573c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul else { 574c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul /* Linear interpolation between mipmap levels */ 575c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul const int lvl = (int) lambda; 5764da1cdf78fa3b954840650fa46cf72da5daf149fBrian Paul *level0 = CLAMP(lvl, 0, (int) sampler->texture->last_level); 5774da1cdf78fa3b954840650fa46cf72da5daf149fBrian Paul *level1 = CLAMP(lvl + 1, 0, (int) sampler->texture->last_level); 578c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul *levelBlend = FRAC(lambda); /* blending weight between levels */ 579c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul } 580f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul } 58109a1b912605ff48c8782dcc5aae55ac77e27037bBrian Paul } 58209a1b912605ff48c8782dcc5aae55ac77e27037bBrian Paul} 58309a1b912605ff48c8782dcc5aae55ac77e27037bBrian Paul 58408f33a025100dea2d951e6d628891fe294b18082Brian Paul 585b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul/** 586a13de2464dd034ff117f9314df5757d068cae8e5Brian Paul * Get a texel from a texture, using the texture tile cache. 587a13de2464dd034ff117f9314df5757d068cae8e5Brian Paul * 588b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul * \param face the cube face in 0..5 589b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul * \param level the mipmap level 590b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul * \param x the x coord of texel within 2D image 591b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul * \param y the y coord of texel within 2D image 59270eb7996f265f3634dabda078f13d1be3533cc65Brian Paul * \param z which slice of a 3D texture 593b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul * \param rgba the quad to put the texel/color into 594b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul * \param j which element of the rgba quad to write to 59570eb7996f265f3634dabda078f13d1be3533cc65Brian Paul * 59670eb7996f265f3634dabda078f13d1be3533cc65Brian Paul * XXX maybe move this into sp_tile_cache.c and merge with the 59770eb7996f265f3634dabda078f13d1be3533cc65Brian Paul * sp_get_cached_tile_tex() function. Also, get 4 texels instead of 1... 598b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul */ 599b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paulstatic void 600b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paulget_texel(struct tgsi_sampler *sampler, 60170eb7996f265f3634dabda078f13d1be3533cc65Brian Paul unsigned face, unsigned level, int x, int y, int z, 602a13de2464dd034ff117f9314df5757d068cae8e5Brian Paul float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j) 603b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul{ 60470eb7996f265f3634dabda078f13d1be3533cc65Brian Paul const int tx = x % TILE_SIZE; 60570eb7996f265f3634dabda078f13d1be3533cc65Brian Paul const int ty = y % TILE_SIZE; 60670eb7996f265f3634dabda078f13d1be3533cc65Brian Paul const struct softpipe_cached_tile *tile 60770eb7996f265f3634dabda078f13d1be3533cc65Brian Paul = sp_get_cached_tile_tex(sampler->pipe, sampler->cache, 60870eb7996f265f3634dabda078f13d1be3533cc65Brian Paul x, y, z, face, level); 60970eb7996f265f3634dabda078f13d1be3533cc65Brian Paul rgba[0][j] = tile->data.color[ty][tx][0]; 61070eb7996f265f3634dabda078f13d1be3533cc65Brian Paul rgba[1][j] = tile->data.color[ty][tx][1]; 61170eb7996f265f3634dabda078f13d1be3533cc65Brian Paul rgba[2][j] = tile->data.color[ty][tx][2]; 61270eb7996f265f3634dabda078f13d1be3533cc65Brian Paul rgba[3][j] = tile->data.color[ty][tx][3]; 613b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul} 614b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul 615b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul 6163d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul/** 6173d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul * Compare texcoord 'p' (aka R) against texture value 'rgba[0]' 6183d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul * When we sampled the depth texture, the depth value was put into all 6193d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul * RGBA channels. We look at the red channel here. 6203d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul */ 6213d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paulstatic INLINE void 6223d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paulshadow_compare(uint compare_func, 6233d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul float rgba[NUM_CHANNELS][QUAD_SIZE], 6243d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul const float p[QUAD_SIZE], 6253d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul uint j) 6263d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul{ 6273d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul int k; 6283d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul switch (compare_func) { 6293d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul case PIPE_FUNC_LESS: 6303d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul k = p[j] < rgba[0][j]; 6313d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul break; 6323d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul case PIPE_FUNC_LEQUAL: 6333d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul k = p[j] <= rgba[0][j]; 6343d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul break; 6353d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul case PIPE_FUNC_GREATER: 6363d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul k = p[j] > rgba[0][j]; 6373d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul break; 6383d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul case PIPE_FUNC_GEQUAL: 6393d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul k = p[j] >= rgba[0][j]; 6403d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul break; 6413d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul case PIPE_FUNC_EQUAL: 6423d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul k = p[j] == rgba[0][j]; 6433d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul break; 6443d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul case PIPE_FUNC_NOTEQUAL: 6453d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul k = p[j] != rgba[0][j]; 6463d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul break; 6473d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul case PIPE_FUNC_ALWAYS: 6483d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul k = 1; 6493d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul break; 6503d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul case PIPE_FUNC_NEVER: 6513d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul k = 0; 6523d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul break; 6533d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul default: 654f9b1d47d652778012fd35552ffc51717ac0b6f79Keith Whitwell k = 0; 6553d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul assert(0); 656f9b1d47d652778012fd35552ffc51717ac0b6f79Keith Whitwell break; 6573d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul } 6583d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul 6593d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul rgba[0][j] = rgba[1][j] = rgba[2][j] = (float) k; 6603d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul} 6613d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul 662b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul 663b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul/** 664a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul * Common code for sampling 1D/2D/cube textures. 665a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul * Could probably extend for 3D... 6660dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul */ 667e12810d92ffb3547680b227bf88937c03018112bBrian Paulstatic void 668a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paulsp_get_samples_2d_common(struct tgsi_sampler *sampler, 669a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul const float s[QUAD_SIZE], 670a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul const float t[QUAD_SIZE], 671a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul const float p[QUAD_SIZE], 672a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul float lodbias, 673a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul float rgba[NUM_CHANNELS][QUAD_SIZE], 674a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul const unsigned faces[4]) 6750dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul{ 6763d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul const uint compare_func = sampler->state->compare_func; 677f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul unsigned level0, level1, j, imgFilter; 678f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul int width, height; 679c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul float levelBlend; 680a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul 681c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul choose_mipmap_levels(sampler, s, t, p, lodbias, 682c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul &level0, &level1, &levelBlend, &imgFilter); 68309a1b912605ff48c8782dcc5aae55ac77e27037bBrian Paul 684b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul assert(sampler->state->normalized_coords); 685b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul 686b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul width = sampler->texture->width[level0]; 687b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul height = sampler->texture->height[level0]; 68809a1b912605ff48c8782dcc5aae55ac77e27037bBrian Paul 689b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul assert(width > 0); 690612cfb749c3526eeb446bbc631bf24716522f373Brian Paul 691b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul switch (imgFilter) { 6920dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul case PIPE_TEX_FILTER_NEAREST: 693b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul for (j = 0; j < QUAD_SIZE; j++) { 694b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul int x = nearest_texcoord(sampler->state->wrap_s, s[j], width); 695b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul int y = nearest_texcoord(sampler->state->wrap_t, t[j], height); 696df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul get_texel(sampler, faces[j], level0, x, y, 0, rgba, j); 6973d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { 6983d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul shadow_compare(compare_func, rgba, p, j); 6993d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul } 700f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul 701f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul if (level0 != level1) { 702f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul /* get texels from second mipmap level and blend */ 703f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul float rgba2[4][4]; 704f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul unsigned c; 705f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul x = x / 2; 706f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul y = y / 2; 707df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul get_texel(sampler, faces[j], level1, x, y, 0, rgba2, j); 7083d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){ 7093d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul shadow_compare(compare_func, rgba2, p, j); 7103d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul } 7113d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul 712f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul for (c = 0; c < NUM_CHANNELS; c++) { 71317c2f56dc3f2f58ba89d8e305e7d9b423e3cae16Brian Paul rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]); 714f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul } 715f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul } 7160dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul } 7170dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul break; 7180dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul case PIPE_TEX_FILTER_LINEAR: 71998ae83d5cc73b61826823c915b5c59746c2e85c7Keith Whitwell case PIPE_TEX_FILTER_ANISO: 720b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul for (j = 0; j < QUAD_SIZE; j++) { 721b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul float tx[4][4], a, b; 722b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul int x0, y0, x1, y1, c; 723b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul linear_texcoord(sampler->state->wrap_s, s[j], width, &x0, &x1, &a); 724b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul linear_texcoord(sampler->state->wrap_t, t[j], height, &y0, &y1, &b); 725df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul get_texel(sampler, faces[j], level0, x0, y0, 0, tx, 0); 726df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul get_texel(sampler, faces[j], level0, x1, y0, 0, tx, 1); 727df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul get_texel(sampler, faces[j], level0, x0, y1, 0, tx, 2); 728df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul get_texel(sampler, faces[j], level0, x1, y1, 0, tx, 3); 7293d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { 7303d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul shadow_compare(compare_func, tx, p, 0); 7313d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul shadow_compare(compare_func, tx, p, 1); 7323d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul shadow_compare(compare_func, tx, p, 2); 7333d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul shadow_compare(compare_func, tx, p, 3); 7343d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul } 7353d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul 736b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul for (c = 0; c < 4; c++) { 737b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul rgba[c][j] = lerp_2d(a, b, tx[c][0], tx[c][1], tx[c][2], tx[c][3]); 738b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul } 739f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul 740f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul if (level0 != level1) { 741f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul /* get texels from second mipmap level and blend */ 742f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul float rgba2[4][4]; 743f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul x0 = x0 / 2; 744f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul y0 = y0 / 2; 745f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul x1 = x1 / 2; 746f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul y1 = y1 / 2; 747df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul get_texel(sampler, faces[j], level1, x0, y0, 0, tx, 0); 748df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul get_texel(sampler, faces[j], level1, x1, y0, 0, tx, 1); 749df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul get_texel(sampler, faces[j], level1, x0, y1, 0, tx, 2); 750df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul get_texel(sampler, faces[j], level1, x1, y1, 0, tx, 3); 7513d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){ 7523d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul shadow_compare(compare_func, tx, p, 0); 7533d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul shadow_compare(compare_func, tx, p, 1); 7543d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul shadow_compare(compare_func, tx, p, 2); 7553d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul shadow_compare(compare_func, tx, p, 3); 7563d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul } 7573d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul 758f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul for (c = 0; c < 4; c++) { 759f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul rgba2[c][j] = lerp_2d(a, b, 760f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul tx[c][0], tx[c][1], tx[c][2], tx[c][3]); 761f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul } 762f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul 763f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul for (c = 0; c < NUM_CHANNELS; c++) { 764c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian Paul rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]); 765f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul } 766f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul } 76709a1b912605ff48c8782dcc5aae55ac77e27037bBrian Paul } 76809a1b912605ff48c8782dcc5aae55ac77e27037bBrian Paul break; 7690dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul default: 7700dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul assert(0); 7710dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul } 7720dc4eea64f56cc93e5359372b08b99a2d600273cBrian Paul} 77334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul 77434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul 77534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paulstatic void 776a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paulsp_get_samples_1d(struct tgsi_sampler *sampler, 777a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul const float s[QUAD_SIZE], 778a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul const float t[QUAD_SIZE], 779a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul const float p[QUAD_SIZE], 780a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul float lodbias, 781a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul float rgba[NUM_CHANNELS][QUAD_SIZE]) 782a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul{ 783a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul static const unsigned faces[4] = {0, 0, 0, 0}; 784d16b4bc32a731cb6ae320e8c187af3bc751d4138Brian Paul static const float tzero[4] = {0, 0, 0, 0}; 785d16b4bc32a731cb6ae320e8c187af3bc751d4138Brian Paul sp_get_samples_2d_common(sampler, s, tzero, NULL, lodbias, rgba, faces); 786a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul} 787a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul 788a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul 789a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paulstatic void 790a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paulsp_get_samples_2d(struct tgsi_sampler *sampler, 791a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul const float s[QUAD_SIZE], 792a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul const float t[QUAD_SIZE], 793a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul const float p[QUAD_SIZE], 794a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul float lodbias, 795a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul float rgba[NUM_CHANNELS][QUAD_SIZE]) 796a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul{ 797a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul static const unsigned faces[4] = {0, 0, 0, 0}; 7983d8c05f7320151898dd224c1daaf3118e1f7ea34Brian Paul sp_get_samples_2d_common(sampler, s, t, p, lodbias, rgba, faces); 799a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul} 800a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul 801a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul 802a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paulstatic void 803b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paulsp_get_samples_3d(struct tgsi_sampler *sampler, 804b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float s[QUAD_SIZE], 805b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float t[QUAD_SIZE], 806b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float p[QUAD_SIZE], 807f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul float lodbias, 808b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul float rgba[NUM_CHANNELS][QUAD_SIZE]) 80934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul{ 81034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul /* get/map pipe_surfaces corresponding to 3D tex slices */ 8113d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul unsigned level0, level1, j, imgFilter; 8123d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul int width, height, depth; 8133d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul float levelBlend; 8143d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul const uint face = 0; 8153d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul 8163d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul choose_mipmap_levels(sampler, s, t, p, lodbias, 8173d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul &level0, &level1, &levelBlend, &imgFilter); 8183d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul 819b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul assert(sampler->state->normalized_coords); 820b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul 821b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul width = sampler->texture->width[level0]; 822b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul height = sampler->texture->height[level0]; 823b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul depth = sampler->texture->depth[level0]; 8243d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul 8253d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul assert(width > 0); 8263d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul assert(height > 0); 8273d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul assert(depth > 0); 8283d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul 8293d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul switch (imgFilter) { 8303d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul case PIPE_TEX_FILTER_NEAREST: 8313d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul for (j = 0; j < QUAD_SIZE; j++) { 8323d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul int x = nearest_texcoord(sampler->state->wrap_s, s[j], width); 8333d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul int y = nearest_texcoord(sampler->state->wrap_t, t[j], height); 8343d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul int z = nearest_texcoord(sampler->state->wrap_r, p[j], depth); 835df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul get_texel(sampler, face, level0, x, y, z, rgba, j); 8363d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul 8373d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul if (level0 != level1) { 8383d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul /* get texels from second mipmap level and blend */ 8393d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul float rgba2[4][4]; 8403d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul unsigned c; 8413d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul x /= 2; 8423d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul y /= 2; 8433d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul z /= 2; 844df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul get_texel(sampler, face, level1, x, y, z, rgba2, j); 8453d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul for (c = 0; c < NUM_CHANNELS; c++) { 8463d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul rgba[c][j] = LERP(levelBlend, rgba2[c][j], rgba[c][j]); 8473d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul } 8483d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul } 8493d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul } 8503d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul break; 8513d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul case PIPE_TEX_FILTER_LINEAR: 85298ae83d5cc73b61826823c915b5c59746c2e85c7Keith Whitwell case PIPE_TEX_FILTER_ANISO: 8533d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul for (j = 0; j < QUAD_SIZE; j++) { 854df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul float texel0[4][4], texel1[4][4]; 855df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul float xw, yw, zw; /* interpolation weights */ 8563d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul int x0, x1, y0, y1, z0, z1, c; 8573d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul linear_texcoord(sampler->state->wrap_s, s[j], width, &x0, &x1, &xw); 8583d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul linear_texcoord(sampler->state->wrap_t, t[j], height, &y0, &y1, &yw); 8593d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul linear_texcoord(sampler->state->wrap_r, p[j], depth, &z0, &z1, &zw); 860df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul get_texel(sampler, face, level0, x0, y0, z0, texel0, 0); 861df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul get_texel(sampler, face, level0, x1, y0, z0, texel0, 1); 862df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul get_texel(sampler, face, level0, x0, y1, z0, texel0, 2); 863df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul get_texel(sampler, face, level0, x1, y1, z0, texel0, 3); 864df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul get_texel(sampler, face, level0, x0, y0, z1, texel1, 0); 865df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul get_texel(sampler, face, level0, x1, y0, z1, texel1, 1); 866df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul get_texel(sampler, face, level0, x0, y1, z1, texel1, 2); 867df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul get_texel(sampler, face, level0, x1, y1, z1, texel1, 3); 8683d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul 8693d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul /* 3D lerp */ 8703d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul for (c = 0; c < 4; c++) { 8713d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul float ctemp0[4][4], ctemp1[4][4]; 8723d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul ctemp0[c][j] = lerp_2d(xw, yw, 8733d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul texel0[c][0], texel0[c][1], 8743d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul texel0[c][2], texel0[c][3]); 8753d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul ctemp1[c][j] = lerp_2d(xw, yw, 8763d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul texel1[c][0], texel1[c][1], 8773d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul texel1[c][2], texel1[c][3]); 8783d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul rgba[c][j] = LERP(zw, ctemp0[c][j], ctemp1[c][j]); 8793d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul } 8803d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul 8813d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul if (level0 != level1) { 8823d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul /* get texels from second mipmap level and blend */ 8833d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul float rgba2[4][4]; 8843d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul x0 /= 2; 8853d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul y0 /= 2; 8863d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul z0 /= 2; 8873d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul x1 /= 2; 8883d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul y1 /= 2; 8893d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul z1 /= 2; 890df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul get_texel(sampler, face, level1, x0, y0, z0, texel0, 0); 891df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul get_texel(sampler, face, level1, x1, y0, z0, texel0, 1); 892df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul get_texel(sampler, face, level1, x0, y1, z0, texel0, 2); 893df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul get_texel(sampler, face, level1, x1, y1, z0, texel0, 3); 894df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul get_texel(sampler, face, level1, x0, y0, z1, texel1, 0); 895df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul get_texel(sampler, face, level1, x1, y0, z1, texel1, 1); 896df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul get_texel(sampler, face, level1, x0, y1, z1, texel1, 2); 897df4410a59784482fcbd48f82788dd0a9f5a62c15Brian Paul get_texel(sampler, face, level1, x1, y1, z1, texel1, 3); 8983d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul 8993d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul /* 3D lerp */ 9003d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul for (c = 0; c < 4; c++) { 9013d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul float ctemp0[4][4], ctemp1[4][4]; 9023d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul ctemp0[c][j] = lerp_2d(xw, yw, 9033d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul texel0[c][0], texel0[c][1], 9043d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul texel0[c][2], texel0[c][3]); 9053d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul ctemp1[c][j] = lerp_2d(xw, yw, 9063d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul texel1[c][0], texel1[c][1], 9073d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul texel1[c][2], texel1[c][3]); 9083d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul rgba2[c][j] = LERP(zw, ctemp0[c][j], ctemp1[c][j]); 9093d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul } 9103d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul 9113d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul /* blend mipmap levels */ 9123d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul for (c = 0; c < NUM_CHANNELS; c++) { 9133d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]); 9143d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul } 9153d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul } 9163d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul } 9173d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul break; 9183d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul default: 9193d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul assert(0); 9203d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian Paul } 92134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul} 92234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul 92334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul 92434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paulstatic void 925b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paulsp_get_samples_cube(struct tgsi_sampler *sampler, 926b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float s[QUAD_SIZE], 927b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float t[QUAD_SIZE], 928b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float p[QUAD_SIZE], 929f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul float lodbias, 930b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul float rgba[NUM_CHANNELS][QUAD_SIZE]) 93134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul{ 932a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul unsigned faces[QUAD_SIZE], j; 933a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul float ssss[4], tttt[4]; 934b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul for (j = 0; j < QUAD_SIZE; j++) { 935a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul faces[j] = choose_cube_face(s[j], t[j], p[j], ssss + j, tttt + j); 936b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul } 937a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul sp_get_samples_2d_common(sampler, ssss, tttt, NULL, lodbias, rgba, faces); 93834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul} 93934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul 94034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul 941b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paulstatic void 942b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paulsp_get_samples_rect(struct tgsi_sampler *sampler, 943b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul const float s[QUAD_SIZE], 944b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul const float t[QUAD_SIZE], 945b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul const float p[QUAD_SIZE], 946b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul float lodbias, 947b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul float rgba[NUM_CHANNELS][QUAD_SIZE]) 948b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul{ 949b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul //sp_get_samples_2d_common(sampler, s, t, p, lodbias, rgba, faces); 950b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul static const uint face = 0; 951b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul const uint compare_func = sampler->state->compare_func; 952b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul unsigned level0, level1, j, imgFilter; 953b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul int width, height; 954b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul float levelBlend; 955b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul 956b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul choose_mipmap_levels(sampler, s, t, p, lodbias, 957b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul &level0, &level1, &levelBlend, &imgFilter); 958b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul 959b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul /* texture RECTS cannot be mipmapped */ 960b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul assert(level0 == level1); 961b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul 962b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul width = sampler->texture->width[level0]; 963b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul height = sampler->texture->height[level0]; 964b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul 965b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul assert(width > 0); 966b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul 967b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul switch (imgFilter) { 968b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul case PIPE_TEX_FILTER_NEAREST: 969b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul for (j = 0; j < QUAD_SIZE; j++) { 970b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul int x = nearest_texcoord_unnorm(sampler->state->wrap_s, s[j], width); 971b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul int y = nearest_texcoord_unnorm(sampler->state->wrap_t, t[j], height); 972b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul get_texel(sampler, face, level0, x, y, 0, rgba, j); 973b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { 974b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul shadow_compare(compare_func, rgba, p, j); 975b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul } 976b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul } 977b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul break; 978b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul case PIPE_TEX_FILTER_LINEAR: 97998ae83d5cc73b61826823c915b5c59746c2e85c7Keith Whitwell case PIPE_TEX_FILTER_ANISO: 980b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul for (j = 0; j < QUAD_SIZE; j++) { 981b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul float tx[4][4], a, b; 982b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul int x0, y0, x1, y1, c; 983b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul linear_texcoord_unnorm(sampler->state->wrap_s, s[j], width, &x0, &x1, &a); 984b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul linear_texcoord_unnorm(sampler->state->wrap_t, t[j], height, &y0, &y1, &b); 985b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul get_texel(sampler, face, level0, x0, y0, 0, tx, 0); 986b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul get_texel(sampler, face, level0, x1, y0, 0, tx, 1); 987b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul get_texel(sampler, face, level0, x0, y1, 0, tx, 2); 988b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul get_texel(sampler, face, level0, x1, y1, 0, tx, 3); 989b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { 990b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul shadow_compare(compare_func, tx, p, 0); 991b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul shadow_compare(compare_func, tx, p, 1); 992b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul shadow_compare(compare_func, tx, p, 2); 993b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul shadow_compare(compare_func, tx, p, 3); 994b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul } 995b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul 996b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul for (c = 0; c < 4; c++) { 997b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul rgba[c][j] = lerp_2d(a, b, tx[c][0], tx[c][1], tx[c][2], tx[c][3]); 998b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul } 999b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul } 1000b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul break; 1001b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul default: 1002b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul assert(0); 1003b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul } 1004b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul} 1005b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul 1006b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul 1007b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul 1008b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul 1009a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul/** 1010a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul * Called via tgsi_sampler::get_samples() 1011a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul * Use the sampler's state setting to get a filtered RGBA value 1012753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * from the sampler's texture. 1013a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul * 1014a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul * XXX we can implement many versions of this function, each 1015a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul * tightly coded for a specific combination of sampler state 1016a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul * (nearest + repeat), (bilinear mipmap + clamp), etc. 1017a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul * 1018a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul * The update_samplers() function in st_atom_sampler.c could create 1019a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul * a new tgsi_sampler object for each state combo it finds.... 1020a34b8594b7b2d00404bb639621ec1ce918ba0786Brian Paul */ 102134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paulvoid 1022b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paulsp_get_samples(struct tgsi_sampler *sampler, 1023b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float s[QUAD_SIZE], 1024b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float t[QUAD_SIZE], 1025b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul const float p[QUAD_SIZE], 1026f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul float lodbias, 1027b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian Paul float rgba[NUM_CHANNELS][QUAD_SIZE]) 102834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul{ 10294f23468bd0d14b8ed687a641003d587b91ad39a7Brian Paul if (!sampler->texture) 10304f23468bd0d14b8ed687a641003d587b91ad39a7Brian Paul return; 10314f23468bd0d14b8ed687a641003d587b91ad39a7Brian Paul 103234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul switch (sampler->texture->target) { 103370af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell case PIPE_TEXTURE_1D: 1034b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul assert(sampler->state->normalized_coords); 1035f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul sp_get_samples_1d(sampler, s, t, p, lodbias, rgba); 103634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul break; 103770af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell case PIPE_TEXTURE_2D: 1038b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul if (sampler->state->normalized_coords) 1039b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul sp_get_samples_2d(sampler, s, t, p, lodbias, rgba); 1040b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul else 1041b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul sp_get_samples_rect(sampler, s, t, p, lodbias, rgba); 104234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul break; 104370af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell case PIPE_TEXTURE_3D: 1044b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul assert(sampler->state->normalized_coords); 1045f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul sp_get_samples_3d(sampler, s, t, p, lodbias, rgba); 104634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul break; 104770af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell case PIPE_TEXTURE_CUBE: 1048b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian Paul assert(sampler->state->normalized_coords); 1049f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian Paul sp_get_samples_cube(sampler, s, t, p, lodbias, rgba); 105034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul break; 105134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul default: 105234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul assert(0); 105334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul } 10543d53d38d5e35386de4793162b9dd32e171927059Brian Paul 10553d53d38d5e35386de4793162b9dd32e171927059Brian Paul#if 0 /* DEBUG */ 10563d53d38d5e35386de4793162b9dd32e171927059Brian Paul { 10573d53d38d5e35386de4793162b9dd32e171927059Brian Paul int i; 10583d53d38d5e35386de4793162b9dd32e171927059Brian Paul printf("Sampled at %f, %f, %f:\n", s[0], t[0], p[0]); 10593d53d38d5e35386de4793162b9dd32e171927059Brian Paul for (i = 0; i < 4; i++) { 10603d53d38d5e35386de4793162b9dd32e171927059Brian Paul printf("Frag %d: %f %f %f %f\n", i, 10613d53d38d5e35386de4793162b9dd32e171927059Brian Paul rgba[0][i], 10623d53d38d5e35386de4793162b9dd32e171927059Brian Paul rgba[1][i], 10633d53d38d5e35386de4793162b9dd32e171927059Brian Paul rgba[2][i], 10643d53d38d5e35386de4793162b9dd32e171927059Brian Paul rgba[3][i]); 10653d53d38d5e35386de4793162b9dd32e171927059Brian Paul } 10663d53d38d5e35386de4793162b9dd32e171927059Brian Paul } 10673d53d38d5e35386de4793162b9dd32e171927059Brian Paul#endif 106834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul} 106934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian Paul 1070