sp_tex_sample.c revision 9935e3b7303da656e258d4bd5bc799ffbfbc737b
10dc4eea64f56cc93e5359372b08b99a2d600273cBrian/************************************************************************** 20dc4eea64f56cc93e5359372b08b99a2d600273cBrian * 30dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 40dc4eea64f56cc93e5359372b08b99a2d600273cBrian * All Rights Reserved. 50dc4eea64f56cc93e5359372b08b99a2d600273cBrian * 60dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Permission is hereby granted, free of charge, to any person obtaining a 70dc4eea64f56cc93e5359372b08b99a2d600273cBrian * copy of this software and associated documentation files (the 80dc4eea64f56cc93e5359372b08b99a2d600273cBrian * "Software"), to deal in the Software without restriction, including 90dc4eea64f56cc93e5359372b08b99a2d600273cBrian * without limitation the rights to use, copy, modify, merge, publish, 100dc4eea64f56cc93e5359372b08b99a2d600273cBrian * distribute, sub license, and/or sell copies of the Software, and to 110dc4eea64f56cc93e5359372b08b99a2d600273cBrian * permit persons to whom the Software is furnished to do so, subject to 120dc4eea64f56cc93e5359372b08b99a2d600273cBrian * the following conditions: 130dc4eea64f56cc93e5359372b08b99a2d600273cBrian * 140dc4eea64f56cc93e5359372b08b99a2d600273cBrian * The above copyright notice and this permission notice (including the 150dc4eea64f56cc93e5359372b08b99a2d600273cBrian * next paragraph) shall be included in all copies or substantial portions 160dc4eea64f56cc93e5359372b08b99a2d600273cBrian * of the Software. 170dc4eea64f56cc93e5359372b08b99a2d600273cBrian * 180dc4eea64f56cc93e5359372b08b99a2d600273cBrian * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 190dc4eea64f56cc93e5359372b08b99a2d600273cBrian * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 200dc4eea64f56cc93e5359372b08b99a2d600273cBrian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 210dc4eea64f56cc93e5359372b08b99a2d600273cBrian * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 220dc4eea64f56cc93e5359372b08b99a2d600273cBrian * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 230dc4eea64f56cc93e5359372b08b99a2d600273cBrian * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 240dc4eea64f56cc93e5359372b08b99a2d600273cBrian * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 250dc4eea64f56cc93e5359372b08b99a2d600273cBrian * 260dc4eea64f56cc93e5359372b08b99a2d600273cBrian **************************************************************************/ 270dc4eea64f56cc93e5359372b08b99a2d600273cBrian 280dc4eea64f56cc93e5359372b08b99a2d600273cBrian/** 290dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Texture sampling 300dc4eea64f56cc93e5359372b08b99a2d600273cBrian * 310dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Authors: 320dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Brian Paul 330dc4eea64f56cc93e5359372b08b99a2d600273cBrian */ 340dc4eea64f56cc93e5359372b08b99a2d600273cBrian 3508f33a025100dea2d951e6d628891fe294b18082Brian#include "sp_context.h" 36b91de8a6e7d74d38698b6dad9f34040e484e69afBrian#include "sp_headers.h" 370dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "sp_surface.h" 380dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "sp_tex_sample.h" 3970eb7996f265f3634dabda078f13d1be3533cc65Brian#include "sp_tile_cache.h" 400dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "pipe/p_context.h" 410dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "pipe/p_defines.h" 427de874ec2c7b9e3aff7f81b7e30045b45381fbadMichal Krol#include "pipe/p_util.h" 43c208a2c791fa24c7c5887fc496738cbddbfafc72José Fonseca#include "tgsi/tgsi_exec.h" 441a46dcc8a927dfb38ca1381e7b3dafb789f8257cBrian Paul#include "util/u_math.h" 450dc4eea64f56cc93e5359372b08b99a2d600273cBrian 460dc4eea64f56cc93e5359372b08b99a2d600273cBrian 4708f33a025100dea2d951e6d628891fe294b18082Brian/* 4808f33a025100dea2d951e6d628891fe294b18082Brian * Note, the FRAC macro has to work perfectly. Otherwise you'll sometimes 4908f33a025100dea2d951e6d628891fe294b18082Brian * see 1-pixel bands of improperly weighted linear-filtered textures. 5008f33a025100dea2d951e6d628891fe294b18082Brian * The tests/texwrap.c demo is a good test. 5108f33a025100dea2d951e6d628891fe294b18082Brian * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0. 5208f33a025100dea2d951e6d628891fe294b18082Brian * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x). 5308f33a025100dea2d951e6d628891fe294b18082Brian */ 549935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul#define FRAC(f) ((f) - util_ifloor(f)) 5508f33a025100dea2d951e6d628891fe294b18082Brian 5608f33a025100dea2d951e6d628891fe294b18082Brian 5708f33a025100dea2d951e6d628891fe294b18082Brian/** 5808f33a025100dea2d951e6d628891fe294b18082Brian * Linear interpolation macro 5908f33a025100dea2d951e6d628891fe294b18082Brian */ 600dc4eea64f56cc93e5359372b08b99a2d600273cBrian#define LERP(T, A, B) ( (A) + (T) * ((B) - (A)) ) 610dc4eea64f56cc93e5359372b08b99a2d600273cBrian 620dc4eea64f56cc93e5359372b08b99a2d600273cBrian 630dc4eea64f56cc93e5359372b08b99a2d600273cBrian/** 640dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Do 2D/biliner interpolation of float values. 650dc4eea64f56cc93e5359372b08b99a2d600273cBrian * v00, v10, v01 and v11 are typically four texture samples in a square/box. 660dc4eea64f56cc93e5359372b08b99a2d600273cBrian * a and b are the horizontal and vertical interpolants. 670dc4eea64f56cc93e5359372b08b99a2d600273cBrian * It's important that this function is inlined when compiled with 680dc4eea64f56cc93e5359372b08b99a2d600273cBrian * optimization! If we find that's not true on some systems, convert 690dc4eea64f56cc93e5359372b08b99a2d600273cBrian * to a macro. 700dc4eea64f56cc93e5359372b08b99a2d600273cBrian */ 71b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic INLINE float 72b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianlerp_2d(float a, float b, 73b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float v00, float v10, float v01, float v11) 740dc4eea64f56cc93e5359372b08b99a2d600273cBrian{ 75b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float temp0 = LERP(a, v00, v10); 76b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float temp1 = LERP(a, v01, v11); 770dc4eea64f56cc93e5359372b08b99a2d600273cBrian return LERP(b, temp0, temp1); 780dc4eea64f56cc93e5359372b08b99a2d600273cBrian} 790dc4eea64f56cc93e5359372b08b99a2d600273cBrian 800dc4eea64f56cc93e5359372b08b99a2d600273cBrian 810dc4eea64f56cc93e5359372b08b99a2d600273cBrian/** 82906768316d9521a32d9a7eebc9edaf76c06a98a7Brian * If A is a signed integer, A % B doesn't give the right value for A < 0 83906768316d9521a32d9a7eebc9edaf76c06a98a7Brian * (in terms of texture repeat). Just casting to unsigned fixes that. 840dc4eea64f56cc93e5359372b08b99a2d600273cBrian */ 85906768316d9521a32d9a7eebc9edaf76c06a98a7Brian#define REMAINDER(A, B) ((unsigned) (A) % (unsigned) (B)) 8608f33a025100dea2d951e6d628891fe294b18082Brian 8708f33a025100dea2d951e6d628891fe294b18082Brian 8808f33a025100dea2d951e6d628891fe294b18082Brian/** 8908f33a025100dea2d951e6d628891fe294b18082Brian * Apply texture coord wrapping mode and return integer texture index. 9008f33a025100dea2d951e6d628891fe294b18082Brian * \param wrapMode PIPE_TEX_WRAP_x 9108f33a025100dea2d951e6d628891fe294b18082Brian * \param s the texcoord 9208f33a025100dea2d951e6d628891fe294b18082Brian * \param size the texture image size 9308f33a025100dea2d951e6d628891fe294b18082Brian * \return integer texture index 9408f33a025100dea2d951e6d628891fe294b18082Brian */ 9570af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwellstatic INLINE int 9670af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwellnearest_texcoord(unsigned wrapMode, float s, unsigned size) 970dc4eea64f56cc93e5359372b08b99a2d600273cBrian{ 9870af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell int i; 990dc4eea64f56cc93e5359372b08b99a2d600273cBrian switch (wrapMode) { 1000dc4eea64f56cc93e5359372b08b99a2d600273cBrian case PIPE_TEX_WRAP_REPEAT: 10108f33a025100dea2d951e6d628891fe294b18082Brian /* s limited to [0,1) */ 10208f33a025100dea2d951e6d628891fe294b18082Brian /* i limited to [0,size-1] */ 1039935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul i = util_ifloor(s * size); 104906768316d9521a32d9a7eebc9edaf76c06a98a7Brian i = REMAINDER(i, size); 10508f33a025100dea2d951e6d628891fe294b18082Brian return i; 1060dc4eea64f56cc93e5359372b08b99a2d600273cBrian case PIPE_TEX_WRAP_CLAMP: 10708f33a025100dea2d951e6d628891fe294b18082Brian /* s limited to [0,1] */ 10808f33a025100dea2d951e6d628891fe294b18082Brian /* i limited to [0,size-1] */ 10908f33a025100dea2d951e6d628891fe294b18082Brian if (s <= 0.0F) 11008f33a025100dea2d951e6d628891fe294b18082Brian i = 0; 11108f33a025100dea2d951e6d628891fe294b18082Brian else if (s >= 1.0F) 11208f33a025100dea2d951e6d628891fe294b18082Brian i = size - 1; 11308f33a025100dea2d951e6d628891fe294b18082Brian else 1149935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul i = util_ifloor(s * size); 11508f33a025100dea2d951e6d628891fe294b18082Brian return i; 11608f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 11708f33a025100dea2d951e6d628891fe294b18082Brian { 11808f33a025100dea2d951e6d628891fe294b18082Brian /* s limited to [min,max] */ 11908f33a025100dea2d951e6d628891fe294b18082Brian /* i limited to [0, size-1] */ 120b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float min = 1.0F / (2.0F * size); 121b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float max = 1.0F - min; 12208f33a025100dea2d951e6d628891fe294b18082Brian if (s < min) 12308f33a025100dea2d951e6d628891fe294b18082Brian i = 0; 12408f33a025100dea2d951e6d628891fe294b18082Brian else if (s > max) 12508f33a025100dea2d951e6d628891fe294b18082Brian i = size - 1; 12608f33a025100dea2d951e6d628891fe294b18082Brian else 1279935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul i = util_ifloor(s * size); 12808f33a025100dea2d951e6d628891fe294b18082Brian } 12908f33a025100dea2d951e6d628891fe294b18082Brian return i; 13008f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 13108f33a025100dea2d951e6d628891fe294b18082Brian { 13208f33a025100dea2d951e6d628891fe294b18082Brian /* s limited to [min,max] */ 13308f33a025100dea2d951e6d628891fe294b18082Brian /* i limited to [-1, size] */ 134b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float min = -1.0F / (2.0F * size); 135b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float max = 1.0F - min; 13608f33a025100dea2d951e6d628891fe294b18082Brian if (s <= min) 13708f33a025100dea2d951e6d628891fe294b18082Brian i = -1; 13808f33a025100dea2d951e6d628891fe294b18082Brian else if (s >= max) 13908f33a025100dea2d951e6d628891fe294b18082Brian i = size; 14008f33a025100dea2d951e6d628891fe294b18082Brian else 1419935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul i = util_ifloor(s * size); 14208f33a025100dea2d951e6d628891fe294b18082Brian } 14308f33a025100dea2d951e6d628891fe294b18082Brian return i; 14408f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_REPEAT: 14508f33a025100dea2d951e6d628891fe294b18082Brian { 146b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float min = 1.0F / (2.0F * size); 147b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float max = 1.0F - min; 1489935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul const int flr = util_ifloor(s); 149b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float u; 15008f33a025100dea2d951e6d628891fe294b18082Brian if (flr & 1) 151b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian u = 1.0F - (s - (float) flr); 15208f33a025100dea2d951e6d628891fe294b18082Brian else 153b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian u = s - (float) flr; 15408f33a025100dea2d951e6d628891fe294b18082Brian if (u < min) 15508f33a025100dea2d951e6d628891fe294b18082Brian i = 0; 15608f33a025100dea2d951e6d628891fe294b18082Brian else if (u > max) 15708f33a025100dea2d951e6d628891fe294b18082Brian i = size - 1; 15808f33a025100dea2d951e6d628891fe294b18082Brian else 1599935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul i = util_ifloor(u * size); 16008f33a025100dea2d951e6d628891fe294b18082Brian } 16108f33a025100dea2d951e6d628891fe294b18082Brian return i; 16208f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_CLAMP: 16308f33a025100dea2d951e6d628891fe294b18082Brian { 16408f33a025100dea2d951e6d628891fe294b18082Brian /* s limited to [0,1] */ 16508f33a025100dea2d951e6d628891fe294b18082Brian /* i limited to [0,size-1] */ 1669935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul const float u = fabsf(s); 16708f33a025100dea2d951e6d628891fe294b18082Brian if (u <= 0.0F) 16808f33a025100dea2d951e6d628891fe294b18082Brian i = 0; 16908f33a025100dea2d951e6d628891fe294b18082Brian else if (u >= 1.0F) 17008f33a025100dea2d951e6d628891fe294b18082Brian i = size - 1; 17108f33a025100dea2d951e6d628891fe294b18082Brian else 1729935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul i = util_ifloor(u * size); 17308f33a025100dea2d951e6d628891fe294b18082Brian } 17408f33a025100dea2d951e6d628891fe294b18082Brian return i; 17508f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: 17608f33a025100dea2d951e6d628891fe294b18082Brian { 17708f33a025100dea2d951e6d628891fe294b18082Brian /* s limited to [min,max] */ 17808f33a025100dea2d951e6d628891fe294b18082Brian /* i limited to [0, size-1] */ 179b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float min = 1.0F / (2.0F * size); 180b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float max = 1.0F - min; 1819935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul const float u = fabsf(s); 18208f33a025100dea2d951e6d628891fe294b18082Brian if (u < min) 18308f33a025100dea2d951e6d628891fe294b18082Brian i = 0; 18408f33a025100dea2d951e6d628891fe294b18082Brian else if (u > max) 18508f33a025100dea2d951e6d628891fe294b18082Brian i = size - 1; 18608f33a025100dea2d951e6d628891fe294b18082Brian else 1879935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul i = util_ifloor(u * size); 18808f33a025100dea2d951e6d628891fe294b18082Brian } 18908f33a025100dea2d951e6d628891fe294b18082Brian return i; 19008f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: 19108f33a025100dea2d951e6d628891fe294b18082Brian { 19208f33a025100dea2d951e6d628891fe294b18082Brian /* s limited to [min,max] */ 19308f33a025100dea2d951e6d628891fe294b18082Brian /* i limited to [0, size-1] */ 194b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float min = -1.0F / (2.0F * size); 195b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float max = 1.0F - min; 1969935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul const float u = fabsf(s); 19708f33a025100dea2d951e6d628891fe294b18082Brian if (u < min) 19808f33a025100dea2d951e6d628891fe294b18082Brian i = -1; 19908f33a025100dea2d951e6d628891fe294b18082Brian else if (u > max) 20008f33a025100dea2d951e6d628891fe294b18082Brian i = size; 20108f33a025100dea2d951e6d628891fe294b18082Brian else 2029935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul i = util_ifloor(u * size); 20308f33a025100dea2d951e6d628891fe294b18082Brian } 20408f33a025100dea2d951e6d628891fe294b18082Brian return i; 2050dc4eea64f56cc93e5359372b08b99a2d600273cBrian default: 2060dc4eea64f56cc93e5359372b08b99a2d600273cBrian assert(0); 20708f33a025100dea2d951e6d628891fe294b18082Brian return 0; 2080dc4eea64f56cc93e5359372b08b99a2d600273cBrian } 2090dc4eea64f56cc93e5359372b08b99a2d600273cBrian} 2100dc4eea64f56cc93e5359372b08b99a2d600273cBrian 21108f33a025100dea2d951e6d628891fe294b18082Brian 21208f33a025100dea2d951e6d628891fe294b18082Brian/** 21308f33a025100dea2d951e6d628891fe294b18082Brian * Used to compute texel locations for linear sampling. 21408f33a025100dea2d951e6d628891fe294b18082Brian * \param wrapMode PIPE_TEX_WRAP_x 21508f33a025100dea2d951e6d628891fe294b18082Brian * \param s the texcoord 21608f33a025100dea2d951e6d628891fe294b18082Brian * \param size the texture image size 21708f33a025100dea2d951e6d628891fe294b18082Brian * \param i0 returns first texture index 21808f33a025100dea2d951e6d628891fe294b18082Brian * \param i1 returns second texture index (usually *i0 + 1) 21908f33a025100dea2d951e6d628891fe294b18082Brian * \param a returns blend factor/weight between texture indexes 22008f33a025100dea2d951e6d628891fe294b18082Brian */ 2210dc4eea64f56cc93e5359372b08b99a2d600273cBrianstatic INLINE void 22270af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwelllinear_texcoord(unsigned wrapMode, float s, unsigned size, 22370af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell int *i0, int *i1, float *a) 2240dc4eea64f56cc93e5359372b08b99a2d600273cBrian{ 225b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float u; 2260dc4eea64f56cc93e5359372b08b99a2d600273cBrian switch (wrapMode) { 2270dc4eea64f56cc93e5359372b08b99a2d600273cBrian case PIPE_TEX_WRAP_REPEAT: 22808f33a025100dea2d951e6d628891fe294b18082Brian u = s * size - 0.5F; 2299935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul *i0 = REMAINDER(util_ifloor(u), size); 230906768316d9521a32d9a7eebc9edaf76c06a98a7Brian *i1 = REMAINDER(*i0 + 1, size); 2310dc4eea64f56cc93e5359372b08b99a2d600273cBrian break; 2320dc4eea64f56cc93e5359372b08b99a2d600273cBrian case PIPE_TEX_WRAP_CLAMP: 23308f33a025100dea2d951e6d628891fe294b18082Brian if (s <= 0.0F) 23408f33a025100dea2d951e6d628891fe294b18082Brian u = 0.0F; 23508f33a025100dea2d951e6d628891fe294b18082Brian else if (s >= 1.0F) 236b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian u = (float) size; 23708f33a025100dea2d951e6d628891fe294b18082Brian else 23808f33a025100dea2d951e6d628891fe294b18082Brian u = s * size; 23908f33a025100dea2d951e6d628891fe294b18082Brian u -= 0.5F; 2409935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul *i0 = util_ifloor(u); 24108f33a025100dea2d951e6d628891fe294b18082Brian *i1 = *i0 + 1; 24208f33a025100dea2d951e6d628891fe294b18082Brian break; 24308f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 24408f33a025100dea2d951e6d628891fe294b18082Brian if (s <= 0.0F) 24508f33a025100dea2d951e6d628891fe294b18082Brian u = 0.0F; 24608f33a025100dea2d951e6d628891fe294b18082Brian else if (s >= 1.0F) 247b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian u = (float) size; 24808f33a025100dea2d951e6d628891fe294b18082Brian else 24908f33a025100dea2d951e6d628891fe294b18082Brian u = s * size; 25008f33a025100dea2d951e6d628891fe294b18082Brian u -= 0.5F; 2519935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul *i0 = util_ifloor(u); 25208f33a025100dea2d951e6d628891fe294b18082Brian *i1 = *i0 + 1; 25308f33a025100dea2d951e6d628891fe294b18082Brian if (*i0 < 0) 25408f33a025100dea2d951e6d628891fe294b18082Brian *i0 = 0; 25570af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell if (*i1 >= (int) size) 25608f33a025100dea2d951e6d628891fe294b18082Brian *i1 = size - 1; 25708f33a025100dea2d951e6d628891fe294b18082Brian break; 25808f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 25908f33a025100dea2d951e6d628891fe294b18082Brian { 260b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float min = -1.0F / (2.0F * size); 261b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float max = 1.0F - min; 26208f33a025100dea2d951e6d628891fe294b18082Brian if (s <= min) 26308f33a025100dea2d951e6d628891fe294b18082Brian u = min * size; 26408f33a025100dea2d951e6d628891fe294b18082Brian else if (s >= max) 26508f33a025100dea2d951e6d628891fe294b18082Brian u = max * size; 26608f33a025100dea2d951e6d628891fe294b18082Brian else 26708f33a025100dea2d951e6d628891fe294b18082Brian u = s * size; 26808f33a025100dea2d951e6d628891fe294b18082Brian u -= 0.5F; 2699935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul *i0 = util_ifloor(u); 27008f33a025100dea2d951e6d628891fe294b18082Brian *i1 = *i0 + 1; 27108f33a025100dea2d951e6d628891fe294b18082Brian } 27208f33a025100dea2d951e6d628891fe294b18082Brian break; 27308f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_REPEAT: 27408f33a025100dea2d951e6d628891fe294b18082Brian { 2759935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul const int flr = util_ifloor(s); 27608f33a025100dea2d951e6d628891fe294b18082Brian if (flr & 1) 277b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian u = 1.0F - (s - (float) flr); 27808f33a025100dea2d951e6d628891fe294b18082Brian else 279b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian u = s - (float) flr; 28008f33a025100dea2d951e6d628891fe294b18082Brian u = (u * size) - 0.5F; 2819935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul *i0 = util_ifloor(u); 28208f33a025100dea2d951e6d628891fe294b18082Brian *i1 = *i0 + 1; 28308f33a025100dea2d951e6d628891fe294b18082Brian if (*i0 < 0) 28408f33a025100dea2d951e6d628891fe294b18082Brian *i0 = 0; 28570af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell if (*i1 >= (int) size) 28608f33a025100dea2d951e6d628891fe294b18082Brian *i1 = size - 1; 28708f33a025100dea2d951e6d628891fe294b18082Brian } 28808f33a025100dea2d951e6d628891fe294b18082Brian break; 28908f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_CLAMP: 2909935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul u = fabsf(s); 29108f33a025100dea2d951e6d628891fe294b18082Brian if (u >= 1.0F) 292b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian u = (float) size; 29308f33a025100dea2d951e6d628891fe294b18082Brian else 29408f33a025100dea2d951e6d628891fe294b18082Brian u *= size; 29508f33a025100dea2d951e6d628891fe294b18082Brian u -= 0.5F; 2969935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul *i0 = util_ifloor(u); 29708f33a025100dea2d951e6d628891fe294b18082Brian *i1 = *i0 + 1; 29808f33a025100dea2d951e6d628891fe294b18082Brian break; 29908f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: 3009935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul u = fabsf(s); 30108f33a025100dea2d951e6d628891fe294b18082Brian if (u >= 1.0F) 302b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian u = (float) size; 30308f33a025100dea2d951e6d628891fe294b18082Brian else 30408f33a025100dea2d951e6d628891fe294b18082Brian u *= size; 30508f33a025100dea2d951e6d628891fe294b18082Brian u -= 0.5F; 3069935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul *i0 = util_ifloor(u); 30708f33a025100dea2d951e6d628891fe294b18082Brian *i1 = *i0 + 1; 30808f33a025100dea2d951e6d628891fe294b18082Brian if (*i0 < 0) 30908f33a025100dea2d951e6d628891fe294b18082Brian *i0 = 0; 31070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell if (*i1 >= (int) size) 31108f33a025100dea2d951e6d628891fe294b18082Brian *i1 = size - 1; 31208f33a025100dea2d951e6d628891fe294b18082Brian break; 31308f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: 31408f33a025100dea2d951e6d628891fe294b18082Brian { 315b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float min = -1.0F / (2.0F * size); 316b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float max = 1.0F - min; 3179935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul u = fabsf(s); 31808f33a025100dea2d951e6d628891fe294b18082Brian if (u <= min) 31908f33a025100dea2d951e6d628891fe294b18082Brian u = min * size; 32008f33a025100dea2d951e6d628891fe294b18082Brian else if (u >= max) 32108f33a025100dea2d951e6d628891fe294b18082Brian u = max * size; 32208f33a025100dea2d951e6d628891fe294b18082Brian else 32308f33a025100dea2d951e6d628891fe294b18082Brian u *= size; 32408f33a025100dea2d951e6d628891fe294b18082Brian u -= 0.5F; 3259935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul *i0 = util_ifloor(u); 32608f33a025100dea2d951e6d628891fe294b18082Brian *i1 = *i0 + 1; 32708f33a025100dea2d951e6d628891fe294b18082Brian } 3280dc4eea64f56cc93e5359372b08b99a2d600273cBrian break; 3290dc4eea64f56cc93e5359372b08b99a2d600273cBrian default: 3300dc4eea64f56cc93e5359372b08b99a2d600273cBrian assert(0); 3310dc4eea64f56cc93e5359372b08b99a2d600273cBrian } 33208f33a025100dea2d951e6d628891fe294b18082Brian *a = FRAC(u); 3330dc4eea64f56cc93e5359372b08b99a2d600273cBrian} 3340dc4eea64f56cc93e5359372b08b99a2d600273cBrian 3350dc4eea64f56cc93e5359372b08b99a2d600273cBrian 336b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian/** 337b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * For RECT textures / unnormalized texcoords 338b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * Only a subset of wrap modes supported. 339b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian */ 340b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrianstatic INLINE int 341b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBriannearest_texcoord_unnorm(unsigned wrapMode, float s, unsigned size) 342b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{ 343b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian int i; 344b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian switch (wrapMode) { 345b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_WRAP_CLAMP: 3469935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul i = util_ifloor(s); 34769a7c9739bc0f11e66e11ab410d813fa69fe5fc9Michal Krol return CLAMP(i, 0, (int) size-1); 348b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 349b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian /* fall-through */ 350b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 3519935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul return util_ifloor( CLAMP(s, 0.5F, (float) size - 0.5F) ); 352b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian default: 353b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(0); 354b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian return 0; 355b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 356b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian} 357b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 358b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 359b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian/** 360b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * For RECT textures / unnormalized texcoords. 361b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * Only a subset of wrap modes supported. 362b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian */ 363b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrianstatic INLINE void 364b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrianlinear_texcoord_unnorm(unsigned wrapMode, float s, unsigned size, 365b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian int *i0, int *i1, float *a) 366b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{ 367b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian switch (wrapMode) { 368b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_WRAP_CLAMP: 369b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian /* Not exactly what the spec says, but it matches NVIDIA output */ 37069a7c9739bc0f11e66e11ab410d813fa69fe5fc9Michal Krol s = CLAMP(s - 0.5F, 0.0f, (float) size - 1.0f); 3719935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul *i0 = util_ifloor(s); 372b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian *i1 = *i0 + 1; 373b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian break; 374b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 375b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian /* fall-through */ 376b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 3774ec46e4869b60b60c7ddf43168604713b5c4c359Brian s = CLAMP(s, 0.5F, (float) size - 0.5F); 378b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian s -= 0.5F; 3799935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul *i0 = util_ifloor(s); 380b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian *i1 = *i0 + 1; 38169a7c9739bc0f11e66e11ab410d813fa69fe5fc9Michal Krol if (*i1 > (int) size - 1) 382b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian *i1 = size - 1; 383b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian break; 384b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian default: 385b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(0); 386b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 387b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian *a = FRAC(s); 388b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian} 389b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 390b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 39170af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwellstatic unsigned 392a34b8594b7b2d00404bb639621ec1ce918ba0786Brianchoose_cube_face(float rx, float ry, float rz, float *newS, float *newT) 39334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{ 39434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian /* 39534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian major axis 39634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian direction target sc tc ma 39734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ---------- ------------------------------- --- --- --- 39834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian +rx TEXTURE_CUBE_MAP_POSITIVE_X_EXT -rz -ry rx 39934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian -rx TEXTURE_CUBE_MAP_NEGATIVE_X_EXT +rz -ry rx 40034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian +ry TEXTURE_CUBE_MAP_POSITIVE_Y_EXT +rx +rz ry 40134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian -ry TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT +rx -rz ry 40234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian +rz TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz 40334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian -rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz 40434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian */ 4059935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz); 40670af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell unsigned face; 407b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float sc, tc, ma; 40834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 40934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian if (arx > ary && arx > arz) { 41034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian if (rx >= 0.0F) { 41134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_POS_X; 41234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = -rz; 41334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = -ry; 41434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = arx; 41534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 41634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian else { 41734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_NEG_X; 41834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = rz; 41934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = -ry; 42034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = arx; 42134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 42234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 42334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian else if (ary > arx && ary > arz) { 42434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian if (ry >= 0.0F) { 42534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_POS_Y; 42634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = rx; 42734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = rz; 42834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = ary; 42934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 43034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian else { 43134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_NEG_Y; 43234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = rx; 43334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = -rz; 43434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = ary; 43534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 43634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 43734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian else { 43834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian if (rz > 0.0F) { 43934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_POS_Z; 44034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = rx; 44134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = -ry; 44234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = arz; 44334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 44434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian else { 44534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_NEG_Z; 44634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = -rx; 44734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = -ry; 44834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = arz; 44934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 45034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 45134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 452a34b8594b7b2d00404bb639621ec1ce918ba0786Brian *newS = ( sc / ma + 1.0F ) * 0.5F; 453a34b8594b7b2d00404bb639621ec1ce918ba0786Brian *newT = ( tc / ma + 1.0F ) * 0.5F; 45434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 45534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian return face; 45634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian} 45734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 45834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 459b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/** 460b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * Examine the quad's texture coordinates to compute the partial 461b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * derivatives w.r.t X and Y, then compute lambda (level of detail). 462b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * 463b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * This is only done for fragment shaders, not vertex shaders. 464b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian */ 465b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic float 466b4480285ed5098f1c862690ee105dd46f5e6cd1eBriancompute_lambda(struct tgsi_sampler *sampler, 467b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float s[QUAD_SIZE], 468b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float t[QUAD_SIZE], 469f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian const float p[QUAD_SIZE], 470f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian float lodbias) 471b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian{ 472b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float rho, lambda; 473b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 474b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(sampler->state->normalized_coords); 475b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 476b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian assert(s); 477b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian { 478b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dsdx = s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]; 479b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dsdy = s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]; 4809935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul dsdx = fabsf(dsdx); 4819935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul dsdy = fabsf(dsdy); 482b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian rho = MAX2(dsdx, dsdy) * sampler->texture->width[0]; 483b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian } 484b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian if (t) { 485b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]; 486b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dtdy = t[QUAD_TOP_LEFT] - t[QUAD_BOTTOM_LEFT]; 487b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float max; 4889935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul dtdx = fabsf(dtdx); 4899935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul dtdy = fabsf(dtdy); 490b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian max = MAX2(dtdx, dtdy) * sampler->texture->height[0]; 491b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian rho = MAX2(rho, max); 492b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian } 493b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian if (p) { 494b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dpdx = p[QUAD_BOTTOM_RIGHT] - p[QUAD_BOTTOM_LEFT]; 495b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dpdy = p[QUAD_TOP_LEFT] - p[QUAD_BOTTOM_LEFT]; 496b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float max; 4979935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul dpdx = fabsf(dpdx); 4989935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul dpdy = fabsf(dpdy); 499b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian max = MAX2(dpdx, dpdy) * sampler->texture->depth[0]; 500b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian rho = MAX2(rho, max); 501b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian } 502b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 5031a46dcc8a927dfb38ca1381e7b3dafb789f8257cBrian Paul lambda = util_fast_log2(rho); 504f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian lambda += lodbias + sampler->state->lod_bias; 505b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian lambda = CLAMP(lambda, sampler->state->min_lod, sampler->state->max_lod); 506b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 507b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian return lambda; 508b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian} 509b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 510b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 511f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian/** 512c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * Do several things here: 513c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 1. Compute lambda from the texcoords, if needed 514c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 2. Determine if we're minifying or magnifying 515c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 3. If minifying, choose mipmap levels 516c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 4. Return image filter to use within mipmap images 517f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian */ 518f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrianstatic void 519c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brianchoose_mipmap_levels(struct tgsi_sampler *sampler, 520c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian const float s[QUAD_SIZE], 521c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian const float t[QUAD_SIZE], 522c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian const float p[QUAD_SIZE], 523c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian float lodbias, 524c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian unsigned *level0, unsigned *level1, float *levelBlend, 525c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian unsigned *imgFilter) 52609a1b912605ff48c8782dcc5aae55ac77e27037bBrian{ 527c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) { 528c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* no mipmap selection needed */ 5290c6bbd41bd6dc1041eaca7c907d3768d107c1afaBrian *level0 = *level1 = CLAMP((int) sampler->state->min_lod, 5300c6bbd41bd6dc1041eaca7c907d3768d107c1afaBrian 0, (int) sampler->texture->last_level); 53108c9534107fcaf06f9b801551524ed5dc724db13Brian 53208c9534107fcaf06f9b801551524ed5dc724db13Brian if (sampler->state->min_img_filter != sampler->state->mag_img_filter) { 53308c9534107fcaf06f9b801551524ed5dc724db13Brian /* non-mipmapped texture, but still need to determine if doing 53408c9534107fcaf06f9b801551524ed5dc724db13Brian * minification or magnification. 53508c9534107fcaf06f9b801551524ed5dc724db13Brian */ 53608c9534107fcaf06f9b801551524ed5dc724db13Brian float lambda = compute_lambda(sampler, s, t, p, lodbias); 5373b2a291888d8e62787de03f8529806fb562bd186Brian if (lambda <= 0.0) { 53808c9534107fcaf06f9b801551524ed5dc724db13Brian *imgFilter = sampler->state->mag_img_filter; 53908c9534107fcaf06f9b801551524ed5dc724db13Brian } 54008c9534107fcaf06f9b801551524ed5dc724db13Brian else { 54108c9534107fcaf06f9b801551524ed5dc724db13Brian *imgFilter = sampler->state->min_img_filter; 54208c9534107fcaf06f9b801551524ed5dc724db13Brian } 54308c9534107fcaf06f9b801551524ed5dc724db13Brian } 5443b2a291888d8e62787de03f8529806fb562bd186Brian else { 5453b2a291888d8e62787de03f8529806fb562bd186Brian *imgFilter = sampler->state->mag_img_filter; 5463b2a291888d8e62787de03f8529806fb562bd186Brian } 547c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian } 548c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian else { 549c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian float lambda; 550c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian 551c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian if (1) 552c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* fragment shader */ 553c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian lambda = compute_lambda(sampler, s, t, p, lodbias); 554c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian else 555c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* vertex shader */ 556c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian lambda = lodbias; /* not really a bias, but absolute LOD */ 557c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian 5583b2a291888d8e62787de03f8529806fb562bd186Brian if (lambda <= 0.0) { /* XXX threshold depends on the filter */ 559c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* magnifying */ 560c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian *imgFilter = sampler->state->mag_img_filter; 5614da1cdf78fa3b954840650fa46cf72da5daf149fBrian *level0 = *level1 = 0; 562f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 563c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian else { 564c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* minifying */ 565c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian *imgFilter = sampler->state->min_img_filter; 566c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian 567c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* choose mipmap level(s) and compute the blend factor between them */ 568c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NEAREST) { 569c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* Nearest mipmap level */ 570c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian const int lvl = (int) (lambda + 0.5); 571c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian *level0 = 5724da1cdf78fa3b954840650fa46cf72da5daf149fBrian *level1 = CLAMP(lvl, 0, (int) sampler->texture->last_level); 573c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian } 574c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian else { 575c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* Linear interpolation between mipmap levels */ 576c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian const int lvl = (int) lambda; 5774da1cdf78fa3b954840650fa46cf72da5daf149fBrian *level0 = CLAMP(lvl, 0, (int) sampler->texture->last_level); 5784da1cdf78fa3b954840650fa46cf72da5daf149fBrian *level1 = CLAMP(lvl + 1, 0, (int) sampler->texture->last_level); 579c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian *levelBlend = FRAC(lambda); /* blending weight between levels */ 580c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian } 581f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 58209a1b912605ff48c8782dcc5aae55ac77e27037bBrian } 58309a1b912605ff48c8782dcc5aae55ac77e27037bBrian} 58409a1b912605ff48c8782dcc5aae55ac77e27037bBrian 58508f33a025100dea2d951e6d628891fe294b18082Brian 586b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/** 587a13de2464dd034ff117f9314df5757d068cae8e5Brian * Get a texel from a texture, using the texture tile cache. 588a13de2464dd034ff117f9314df5757d068cae8e5Brian * 589b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param face the cube face in 0..5 590b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param level the mipmap level 591b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param x the x coord of texel within 2D image 592b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param y the y coord of texel within 2D image 59370eb7996f265f3634dabda078f13d1be3533cc65Brian * \param z which slice of a 3D texture 594b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param rgba the quad to put the texel/color into 595b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param j which element of the rgba quad to write to 59670eb7996f265f3634dabda078f13d1be3533cc65Brian * 59770eb7996f265f3634dabda078f13d1be3533cc65Brian * XXX maybe move this into sp_tile_cache.c and merge with the 59870eb7996f265f3634dabda078f13d1be3533cc65Brian * sp_get_cached_tile_tex() function. Also, get 4 texels instead of 1... 599b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian */ 600b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic void 601b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianget_texel(struct tgsi_sampler *sampler, 60270eb7996f265f3634dabda078f13d1be3533cc65Brian unsigned face, unsigned level, int x, int y, int z, 603a13de2464dd034ff117f9314df5757d068cae8e5Brian float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j) 604b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian{ 605d50d7a54de89e602a9951264878dfe06924e1adbMichal Krol if (x < 0 || x >= (int) sampler->texture->width[level] || 606d50d7a54de89e602a9951264878dfe06924e1adbMichal Krol y < 0 || y >= (int) sampler->texture->height[level] || 607d50d7a54de89e602a9951264878dfe06924e1adbMichal Krol z < 0 || z >= (int) sampler->texture->depth[level]) { 608ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul rgba[0][j] = sampler->state->border_color[0]; 609ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul rgba[1][j] = sampler->state->border_color[1]; 610ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul rgba[2][j] = sampler->state->border_color[2]; 611ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul rgba[3][j] = sampler->state->border_color[3]; 612ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul } 613ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul else { 614ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul const int tx = x % TILE_SIZE; 615ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul const int ty = y % TILE_SIZE; 616ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul const struct softpipe_cached_tile *tile 617ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul = sp_get_cached_tile_tex(sampler->pipe, sampler->cache, 618ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul x, y, z, face, level); 619ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul rgba[0][j] = tile->data.color[ty][tx][0]; 620ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul rgba[1][j] = tile->data.color[ty][tx][1]; 621ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul rgba[2][j] = tile->data.color[ty][tx][2]; 622ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul rgba[3][j] = tile->data.color[ty][tx][3]; 623b1ff7dac537947d412bf423a73e7eacd76f90d84Brian Paul if (0) 624b1ff7dac537947d412bf423a73e7eacd76f90d84Brian Paul { 625ae2195caf56d2eb782475254c68858a25ee7c857Brian Paul debug_printf("Get texel %f %f %f %f from %s\n", 6268fb55dab783f2de5111e7440093e1458fce5fb3dBrian Paul rgba[0][j], rgba[1][j], rgba[2][j], rgba[3][j], 6278fb55dab783f2de5111e7440093e1458fce5fb3dBrian Paul pf_name(sampler->texture->format)); 628b1ff7dac537947d412bf423a73e7eacd76f90d84Brian Paul } 629ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul } 630b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian} 631b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 632b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 6333d8c05f7320151898dd224c1daaf3118e1f7ea34Brian/** 6343d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * Compare texcoord 'p' (aka R) against texture value 'rgba[0]' 6353d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * When we sampled the depth texture, the depth value was put into all 6363d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * RGBA channels. We look at the red channel here. 6373d8c05f7320151898dd224c1daaf3118e1f7ea34Brian */ 6383d8c05f7320151898dd224c1daaf3118e1f7ea34Brianstatic INLINE void 6393d8c05f7320151898dd224c1daaf3118e1f7ea34Brianshadow_compare(uint compare_func, 6403d8c05f7320151898dd224c1daaf3118e1f7ea34Brian float rgba[NUM_CHANNELS][QUAD_SIZE], 6413d8c05f7320151898dd224c1daaf3118e1f7ea34Brian const float p[QUAD_SIZE], 6423d8c05f7320151898dd224c1daaf3118e1f7ea34Brian uint j) 6433d8c05f7320151898dd224c1daaf3118e1f7ea34Brian{ 6443d8c05f7320151898dd224c1daaf3118e1f7ea34Brian int k; 6453d8c05f7320151898dd224c1daaf3118e1f7ea34Brian switch (compare_func) { 6463d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_LESS: 6473d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] < rgba[0][j]; 6483d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 6493d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_LEQUAL: 6503d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] <= rgba[0][j]; 6513d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 6523d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_GREATER: 6533d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] > rgba[0][j]; 6543d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 6553d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_GEQUAL: 6563d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] >= rgba[0][j]; 6573d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 6583d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_EQUAL: 6593d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] == rgba[0][j]; 6603d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 6613d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_NOTEQUAL: 6623d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] != rgba[0][j]; 6633d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 6643d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_ALWAYS: 6653d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = 1; 6663d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 6673d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_NEVER: 6683d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = 0; 6693d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 6703d8c05f7320151898dd224c1daaf3118e1f7ea34Brian default: 671f9b1d47d652778012fd35552ffc51717ac0b6f79Keith Whitwell k = 0; 6723d8c05f7320151898dd224c1daaf3118e1f7ea34Brian assert(0); 673f9b1d47d652778012fd35552ffc51717ac0b6f79Keith Whitwell break; 6743d8c05f7320151898dd224c1daaf3118e1f7ea34Brian } 6753d8c05f7320151898dd224c1daaf3118e1f7ea34Brian 6763d8c05f7320151898dd224c1daaf3118e1f7ea34Brian rgba[0][j] = rgba[1][j] = rgba[2][j] = (float) k; 6773d8c05f7320151898dd224c1daaf3118e1f7ea34Brian} 6783d8c05f7320151898dd224c1daaf3118e1f7ea34Brian 679b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 680b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/** 681a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Common code for sampling 1D/2D/cube textures. 682a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Could probably extend for 3D... 6830dc4eea64f56cc93e5359372b08b99a2d600273cBrian */ 684e12810d92ffb3547680b227bf88937c03018112bBrianstatic void 685a34b8594b7b2d00404bb639621ec1ce918ba0786Briansp_get_samples_2d_common(struct tgsi_sampler *sampler, 686a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float s[QUAD_SIZE], 687a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float t[QUAD_SIZE], 688a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float p[QUAD_SIZE], 689a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float lodbias, 690a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float rgba[NUM_CHANNELS][QUAD_SIZE], 691a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const unsigned faces[4]) 6920dc4eea64f56cc93e5359372b08b99a2d600273cBrian{ 6933d8c05f7320151898dd224c1daaf3118e1f7ea34Brian const uint compare_func = sampler->state->compare_func; 694f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian unsigned level0, level1, j, imgFilter; 695f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian int width, height; 696c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian float levelBlend; 697a34b8594b7b2d00404bb639621ec1ce918ba0786Brian 698c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian choose_mipmap_levels(sampler, s, t, p, lodbias, 699c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian &level0, &level1, &levelBlend, &imgFilter); 70009a1b912605ff48c8782dcc5aae55ac77e27037bBrian 701b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(sampler->state->normalized_coords); 702b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 703b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian width = sampler->texture->width[level0]; 704b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian height = sampler->texture->height[level0]; 70509a1b912605ff48c8782dcc5aae55ac77e27037bBrian 706b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian assert(width > 0); 707612cfb749c3526eeb446bbc631bf24716522f373Brian 708b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian switch (imgFilter) { 7090dc4eea64f56cc93e5359372b08b99a2d600273cBrian case PIPE_TEX_FILTER_NEAREST: 710b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian for (j = 0; j < QUAD_SIZE; j++) { 711b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian int x = nearest_texcoord(sampler->state->wrap_s, s[j], width); 712b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian int y = nearest_texcoord(sampler->state->wrap_t, t[j], height); 713df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level0, x, y, 0, rgba, j); 7143d8c05f7320151898dd224c1daaf3118e1f7ea34Brian if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { 7153d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, rgba, p, j); 7163d8c05f7320151898dd224c1daaf3118e1f7ea34Brian } 717f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian 718f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian if (level0 != level1) { 719f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian /* get texels from second mipmap level and blend */ 720f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian float rgba2[4][4]; 721f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian unsigned c; 722f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian x = x / 2; 723f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian y = y / 2; 724df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level1, x, y, 0, rgba2, j); 7253d8c05f7320151898dd224c1daaf3118e1f7ea34Brian if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){ 7263d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, rgba2, p, j); 7273d8c05f7320151898dd224c1daaf3118e1f7ea34Brian } 7283d8c05f7320151898dd224c1daaf3118e1f7ea34Brian 729f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian for (c = 0; c < NUM_CHANNELS; c++) { 73017c2f56dc3f2f58ba89d8e305e7d9b423e3cae16Brian rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]); 731f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 732f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 7330dc4eea64f56cc93e5359372b08b99a2d600273cBrian } 7340dc4eea64f56cc93e5359372b08b99a2d600273cBrian break; 7350dc4eea64f56cc93e5359372b08b99a2d600273cBrian case PIPE_TEX_FILTER_LINEAR: 73698ae83d5cc73b61826823c915b5c59746c2e85c7Keith Whitwell case PIPE_TEX_FILTER_ANISO: 737b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian for (j = 0; j < QUAD_SIZE; j++) { 738b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float tx[4][4], a, b; 739b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian int x0, y0, x1, y1, c; 740b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian linear_texcoord(sampler->state->wrap_s, s[j], width, &x0, &x1, &a); 741b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian linear_texcoord(sampler->state->wrap_t, t[j], height, &y0, &y1, &b); 742df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level0, x0, y0, 0, tx, 0); 743df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level0, x1, y0, 0, tx, 1); 744df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level0, x0, y1, 0, tx, 2); 745df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level0, x1, y1, 0, tx, 3); 7463d8c05f7320151898dd224c1daaf3118e1f7ea34Brian if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { 7473d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, tx, p, 0); 7483d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, tx, p, 1); 7493d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, tx, p, 2); 7503d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, tx, p, 3); 7513d8c05f7320151898dd224c1daaf3118e1f7ea34Brian } 7523d8c05f7320151898dd224c1daaf3118e1f7ea34Brian 753b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian for (c = 0; c < 4; c++) { 754b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian rgba[c][j] = lerp_2d(a, b, tx[c][0], tx[c][1], tx[c][2], tx[c][3]); 755b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian } 756f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian 757f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian if (level0 != level1) { 758f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian /* get texels from second mipmap level and blend */ 759f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian float rgba2[4][4]; 760f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian x0 = x0 / 2; 761f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian y0 = y0 / 2; 762f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian x1 = x1 / 2; 763f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian y1 = y1 / 2; 764df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level1, x0, y0, 0, tx, 0); 765df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level1, x1, y0, 0, tx, 1); 766df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level1, x0, y1, 0, tx, 2); 767df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level1, x1, y1, 0, tx, 3); 7683d8c05f7320151898dd224c1daaf3118e1f7ea34Brian if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){ 7693d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, tx, p, 0); 7703d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, tx, p, 1); 7713d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, tx, p, 2); 7723d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, tx, p, 3); 7733d8c05f7320151898dd224c1daaf3118e1f7ea34Brian } 7743d8c05f7320151898dd224c1daaf3118e1f7ea34Brian 775f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian for (c = 0; c < 4; c++) { 776f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian rgba2[c][j] = lerp_2d(a, b, 777f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian tx[c][0], tx[c][1], tx[c][2], tx[c][3]); 778f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 779f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian 780f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian for (c = 0; c < NUM_CHANNELS; c++) { 781c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]); 782f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 783f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 78409a1b912605ff48c8782dcc5aae55ac77e27037bBrian } 78509a1b912605ff48c8782dcc5aae55ac77e27037bBrian break; 7860dc4eea64f56cc93e5359372b08b99a2d600273cBrian default: 7870dc4eea64f56cc93e5359372b08b99a2d600273cBrian assert(0); 7880dc4eea64f56cc93e5359372b08b99a2d600273cBrian } 7890dc4eea64f56cc93e5359372b08b99a2d600273cBrian} 79034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 79134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 79234a48abd5ff82ce9748fc29191e35a0985d47c5fBrianstatic void 793a34b8594b7b2d00404bb639621ec1ce918ba0786Briansp_get_samples_1d(struct tgsi_sampler *sampler, 794a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float s[QUAD_SIZE], 795a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float t[QUAD_SIZE], 796a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float p[QUAD_SIZE], 797a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float lodbias, 798a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float rgba[NUM_CHANNELS][QUAD_SIZE]) 799a34b8594b7b2d00404bb639621ec1ce918ba0786Brian{ 800a34b8594b7b2d00404bb639621ec1ce918ba0786Brian static const unsigned faces[4] = {0, 0, 0, 0}; 801d16b4bc32a731cb6ae320e8c187af3bc751d4138Brian static const float tzero[4] = {0, 0, 0, 0}; 802d16b4bc32a731cb6ae320e8c187af3bc751d4138Brian sp_get_samples_2d_common(sampler, s, tzero, NULL, lodbias, rgba, faces); 803a34b8594b7b2d00404bb639621ec1ce918ba0786Brian} 804a34b8594b7b2d00404bb639621ec1ce918ba0786Brian 805a34b8594b7b2d00404bb639621ec1ce918ba0786Brian 806a34b8594b7b2d00404bb639621ec1ce918ba0786Brianstatic void 807a34b8594b7b2d00404bb639621ec1ce918ba0786Briansp_get_samples_2d(struct tgsi_sampler *sampler, 808a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float s[QUAD_SIZE], 809a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float t[QUAD_SIZE], 810a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float p[QUAD_SIZE], 811a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float lodbias, 812a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float rgba[NUM_CHANNELS][QUAD_SIZE]) 813a34b8594b7b2d00404bb639621ec1ce918ba0786Brian{ 814a34b8594b7b2d00404bb639621ec1ce918ba0786Brian static const unsigned faces[4] = {0, 0, 0, 0}; 8153d8c05f7320151898dd224c1daaf3118e1f7ea34Brian sp_get_samples_2d_common(sampler, s, t, p, lodbias, rgba, faces); 816a34b8594b7b2d00404bb639621ec1ce918ba0786Brian} 817a34b8594b7b2d00404bb639621ec1ce918ba0786Brian 818a34b8594b7b2d00404bb639621ec1ce918ba0786Brian 819a34b8594b7b2d00404bb639621ec1ce918ba0786Brianstatic void 820b4480285ed5098f1c862690ee105dd46f5e6cd1eBriansp_get_samples_3d(struct tgsi_sampler *sampler, 821b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float s[QUAD_SIZE], 822b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float t[QUAD_SIZE], 823b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float p[QUAD_SIZE], 824f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian float lodbias, 825b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float rgba[NUM_CHANNELS][QUAD_SIZE]) 82634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{ 82734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian /* get/map pipe_surfaces corresponding to 3D tex slices */ 8283d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian unsigned level0, level1, j, imgFilter; 8293d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian int width, height, depth; 8303d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian float levelBlend; 8313d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian const uint face = 0; 8323d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 8333d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian choose_mipmap_levels(sampler, s, t, p, lodbias, 8343d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian &level0, &level1, &levelBlend, &imgFilter); 8353d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 836b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(sampler->state->normalized_coords); 837b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 838b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian width = sampler->texture->width[level0]; 839b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian height = sampler->texture->height[level0]; 840b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian depth = sampler->texture->depth[level0]; 8413d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 8423d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian assert(width > 0); 8433d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian assert(height > 0); 8443d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian assert(depth > 0); 8453d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 8463d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian switch (imgFilter) { 8473d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian case PIPE_TEX_FILTER_NEAREST: 8483d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian for (j = 0; j < QUAD_SIZE; j++) { 8493d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian int x = nearest_texcoord(sampler->state->wrap_s, s[j], width); 8503d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian int y = nearest_texcoord(sampler->state->wrap_t, t[j], height); 8513d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian int z = nearest_texcoord(sampler->state->wrap_r, p[j], depth); 852df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level0, x, y, z, rgba, j); 8533d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 8543d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian if (level0 != level1) { 8553d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian /* get texels from second mipmap level and blend */ 8563d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian float rgba2[4][4]; 8573d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian unsigned c; 8583d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian x /= 2; 8593d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian y /= 2; 8603d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian z /= 2; 861df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level1, x, y, z, rgba2, j); 8623d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian for (c = 0; c < NUM_CHANNELS; c++) { 8633d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian rgba[c][j] = LERP(levelBlend, rgba2[c][j], rgba[c][j]); 8643d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 8653d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 8663d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 8673d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian break; 8683d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian case PIPE_TEX_FILTER_LINEAR: 86998ae83d5cc73b61826823c915b5c59746c2e85c7Keith Whitwell case PIPE_TEX_FILTER_ANISO: 8703d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian for (j = 0; j < QUAD_SIZE; j++) { 871df4410a59784482fcbd48f82788dd0a9f5a62c15Brian float texel0[4][4], texel1[4][4]; 872df4410a59784482fcbd48f82788dd0a9f5a62c15Brian float xw, yw, zw; /* interpolation weights */ 8733d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian int x0, x1, y0, y1, z0, z1, c; 8743d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian linear_texcoord(sampler->state->wrap_s, s[j], width, &x0, &x1, &xw); 8753d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian linear_texcoord(sampler->state->wrap_t, t[j], height, &y0, &y1, &yw); 8763d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian linear_texcoord(sampler->state->wrap_r, p[j], depth, &z0, &z1, &zw); 877df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level0, x0, y0, z0, texel0, 0); 878df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level0, x1, y0, z0, texel0, 1); 879df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level0, x0, y1, z0, texel0, 2); 880df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level0, x1, y1, z0, texel0, 3); 881df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level0, x0, y0, z1, texel1, 0); 882df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level0, x1, y0, z1, texel1, 1); 883df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level0, x0, y1, z1, texel1, 2); 884df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level0, x1, y1, z1, texel1, 3); 8853d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 8863d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian /* 3D lerp */ 8873d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian for (c = 0; c < 4; c++) { 8883d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian float ctemp0[4][4], ctemp1[4][4]; 8893d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian ctemp0[c][j] = lerp_2d(xw, yw, 8903d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian texel0[c][0], texel0[c][1], 8913d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian texel0[c][2], texel0[c][3]); 8923d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian ctemp1[c][j] = lerp_2d(xw, yw, 8933d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian texel1[c][0], texel1[c][1], 8943d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian texel1[c][2], texel1[c][3]); 8953d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian rgba[c][j] = LERP(zw, ctemp0[c][j], ctemp1[c][j]); 8963d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 8973d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 8983d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian if (level0 != level1) { 8993d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian /* get texels from second mipmap level and blend */ 9003d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian float rgba2[4][4]; 9013d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian x0 /= 2; 9023d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian y0 /= 2; 9033d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian z0 /= 2; 9043d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian x1 /= 2; 9053d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian y1 /= 2; 9063d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian z1 /= 2; 907df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level1, x0, y0, z0, texel0, 0); 908df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level1, x1, y0, z0, texel0, 1); 909df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level1, x0, y1, z0, texel0, 2); 910df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level1, x1, y1, z0, texel0, 3); 911df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level1, x0, y0, z1, texel1, 0); 912df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level1, x1, y0, z1, texel1, 1); 913df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level1, x0, y1, z1, texel1, 2); 914df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level1, x1, y1, z1, texel1, 3); 9153d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 9163d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian /* 3D lerp */ 9173d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian for (c = 0; c < 4; c++) { 9183d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian float ctemp0[4][4], ctemp1[4][4]; 9193d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian ctemp0[c][j] = lerp_2d(xw, yw, 9203d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian texel0[c][0], texel0[c][1], 9213d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian texel0[c][2], texel0[c][3]); 9223d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian ctemp1[c][j] = lerp_2d(xw, yw, 9233d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian texel1[c][0], texel1[c][1], 9243d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian texel1[c][2], texel1[c][3]); 9253d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian rgba2[c][j] = LERP(zw, ctemp0[c][j], ctemp1[c][j]); 9263d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 9273d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 9283d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian /* blend mipmap levels */ 9293d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian for (c = 0; c < NUM_CHANNELS; c++) { 9303d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]); 9313d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 9323d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 9333d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 9343d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian break; 9353d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian default: 9363d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian assert(0); 9373d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 93834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian} 93934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 94034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 94134a48abd5ff82ce9748fc29191e35a0985d47c5fBrianstatic void 942b4480285ed5098f1c862690ee105dd46f5e6cd1eBriansp_get_samples_cube(struct tgsi_sampler *sampler, 943b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float s[QUAD_SIZE], 944b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float t[QUAD_SIZE], 945b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float p[QUAD_SIZE], 946f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian float lodbias, 947b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float rgba[NUM_CHANNELS][QUAD_SIZE]) 94834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{ 949a34b8594b7b2d00404bb639621ec1ce918ba0786Brian unsigned faces[QUAD_SIZE], j; 950a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float ssss[4], tttt[4]; 951b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian for (j = 0; j < QUAD_SIZE; j++) { 952a34b8594b7b2d00404bb639621ec1ce918ba0786Brian faces[j] = choose_cube_face(s[j], t[j], p[j], ssss + j, tttt + j); 953b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian } 954a34b8594b7b2d00404bb639621ec1ce918ba0786Brian sp_get_samples_2d_common(sampler, ssss, tttt, NULL, lodbias, rgba, faces); 95534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian} 95634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 95734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 958b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrianstatic void 959b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBriansp_get_samples_rect(struct tgsi_sampler *sampler, 960b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian const float s[QUAD_SIZE], 961b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian const float t[QUAD_SIZE], 962b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian const float p[QUAD_SIZE], 963b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian float lodbias, 964b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian float rgba[NUM_CHANNELS][QUAD_SIZE]) 965b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{ 966b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian //sp_get_samples_2d_common(sampler, s, t, p, lodbias, rgba, faces); 967b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian static const uint face = 0; 968b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian const uint compare_func = sampler->state->compare_func; 969b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian unsigned level0, level1, j, imgFilter; 970b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian int width, height; 971b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian float levelBlend; 972b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 973b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian choose_mipmap_levels(sampler, s, t, p, lodbias, 974b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian &level0, &level1, &levelBlend, &imgFilter); 975b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 976b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian /* texture RECTS cannot be mipmapped */ 977b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(level0 == level1); 978b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 979b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian width = sampler->texture->width[level0]; 980b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian height = sampler->texture->height[level0]; 981b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 982b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(width > 0); 983b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 984b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian switch (imgFilter) { 985b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_FILTER_NEAREST: 986b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian for (j = 0; j < QUAD_SIZE; j++) { 987b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian int x = nearest_texcoord_unnorm(sampler->state->wrap_s, s[j], width); 988b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian int y = nearest_texcoord_unnorm(sampler->state->wrap_t, t[j], height); 989b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian get_texel(sampler, face, level0, x, y, 0, rgba, j); 990b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { 991b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian shadow_compare(compare_func, rgba, p, j); 992b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 993b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 994b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian break; 995b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_FILTER_LINEAR: 99698ae83d5cc73b61826823c915b5c59746c2e85c7Keith Whitwell case PIPE_TEX_FILTER_ANISO: 997b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian for (j = 0; j < QUAD_SIZE; j++) { 998b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian float tx[4][4], a, b; 999b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian int x0, y0, x1, y1, c; 1000b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian linear_texcoord_unnorm(sampler->state->wrap_s, s[j], width, &x0, &x1, &a); 1001b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian linear_texcoord_unnorm(sampler->state->wrap_t, t[j], height, &y0, &y1, &b); 1002b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian get_texel(sampler, face, level0, x0, y0, 0, tx, 0); 1003b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian get_texel(sampler, face, level0, x1, y0, 0, tx, 1); 1004b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian get_texel(sampler, face, level0, x0, y1, 0, tx, 2); 1005b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian get_texel(sampler, face, level0, x1, y1, 0, tx, 3); 1006b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { 1007b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian shadow_compare(compare_func, tx, p, 0); 1008b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian shadow_compare(compare_func, tx, p, 1); 1009b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian shadow_compare(compare_func, tx, p, 2); 1010b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian shadow_compare(compare_func, tx, p, 3); 1011b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 1012b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 1013b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian for (c = 0; c < 4; c++) { 1014b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian rgba[c][j] = lerp_2d(a, b, tx[c][0], tx[c][1], tx[c][2], tx[c][3]); 1015b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 1016b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 1017b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian break; 1018b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian default: 1019b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(0); 1020b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 1021b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian} 1022b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 1023b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 1024b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 1025b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 1026a34b8594b7b2d00404bb639621ec1ce918ba0786Brian/** 1027a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Called via tgsi_sampler::get_samples() 1028a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Use the sampler's state setting to get a filtered RGBA value 1029753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * from the sampler's texture. 1030a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * 1031a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * XXX we can implement many versions of this function, each 1032a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * tightly coded for a specific combination of sampler state 1033a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * (nearest + repeat), (bilinear mipmap + clamp), etc. 1034a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * 1035a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * The update_samplers() function in st_atom_sampler.c could create 1036a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * a new tgsi_sampler object for each state combo it finds.... 1037a34b8594b7b2d00404bb639621ec1ce918ba0786Brian */ 103834a48abd5ff82ce9748fc29191e35a0985d47c5fBrianvoid 1039b4480285ed5098f1c862690ee105dd46f5e6cd1eBriansp_get_samples(struct tgsi_sampler *sampler, 1040b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float s[QUAD_SIZE], 1041b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float t[QUAD_SIZE], 1042b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float p[QUAD_SIZE], 1043f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian float lodbias, 1044b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float rgba[NUM_CHANNELS][QUAD_SIZE]) 104534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{ 10464f23468bd0d14b8ed687a641003d587b91ad39a7Brian if (!sampler->texture) 10474f23468bd0d14b8ed687a641003d587b91ad39a7Brian return; 10484f23468bd0d14b8ed687a641003d587b91ad39a7Brian 104934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian switch (sampler->texture->target) { 105070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell case PIPE_TEXTURE_1D: 1051b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(sampler->state->normalized_coords); 1052f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian sp_get_samples_1d(sampler, s, t, p, lodbias, rgba); 105334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian break; 105470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell case PIPE_TEXTURE_2D: 1055b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian if (sampler->state->normalized_coords) 1056b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian sp_get_samples_2d(sampler, s, t, p, lodbias, rgba); 1057b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian else 1058b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian sp_get_samples_rect(sampler, s, t, p, lodbias, rgba); 105934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian break; 106070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell case PIPE_TEXTURE_3D: 1061b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(sampler->state->normalized_coords); 1062f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian sp_get_samples_3d(sampler, s, t, p, lodbias, rgba); 106334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian break; 106470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell case PIPE_TEXTURE_CUBE: 1065b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(sampler->state->normalized_coords); 1066f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian sp_get_samples_cube(sampler, s, t, p, lodbias, rgba); 106734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian break; 106834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian default: 106934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian assert(0); 107034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 10713d53d38d5e35386de4793162b9dd32e171927059Brian Paul 10723d53d38d5e35386de4793162b9dd32e171927059Brian Paul#if 0 /* DEBUG */ 10733d53d38d5e35386de4793162b9dd32e171927059Brian Paul { 10743d53d38d5e35386de4793162b9dd32e171927059Brian Paul int i; 10753d53d38d5e35386de4793162b9dd32e171927059Brian Paul printf("Sampled at %f, %f, %f:\n", s[0], t[0], p[0]); 10763d53d38d5e35386de4793162b9dd32e171927059Brian Paul for (i = 0; i < 4; i++) { 10773d53d38d5e35386de4793162b9dd32e171927059Brian Paul printf("Frag %d: %f %f %f %f\n", i, 10783d53d38d5e35386de4793162b9dd32e171927059Brian Paul rgba[0][i], 10793d53d38d5e35386de4793162b9dd32e171927059Brian Paul rgba[1][i], 10803d53d38d5e35386de4793162b9dd32e171927059Brian Paul rgba[2][i], 10813d53d38d5e35386de4793162b9dd32e171927059Brian Paul rgba[3][i]); 10823d53d38d5e35386de4793162b9dd32e171927059Brian Paul } 10833d53d38d5e35386de4793162b9dd32e171927059Brian Paul } 10843d53d38d5e35386de4793162b9dd32e171927059Brian Paul#endif 108534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian} 108634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 1087