sp_tex_sample.c revision 6acd63a4980951727939c0dd545a0324965b3834
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" 436acd63a4980951727939c0dd545a0324965b3834José Fonseca#include "tgsi/exec/tgsi_exec.h" 440dc4eea64f56cc93e5359372b08b99a2d600273cBrian 450dc4eea64f56cc93e5359372b08b99a2d600273cBrian 4608f33a025100dea2d951e6d628891fe294b18082Brian/* 4708f33a025100dea2d951e6d628891fe294b18082Brian * Note, the FRAC macro has to work perfectly. Otherwise you'll sometimes 4808f33a025100dea2d951e6d628891fe294b18082Brian * see 1-pixel bands of improperly weighted linear-filtered textures. 4908f33a025100dea2d951e6d628891fe294b18082Brian * The tests/texwrap.c demo is a good test. 5008f33a025100dea2d951e6d628891fe294b18082Brian * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0. 5108f33a025100dea2d951e6d628891fe294b18082Brian * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x). 5208f33a025100dea2d951e6d628891fe294b18082Brian */ 5370af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell#define FRAC(f) ((f) - ifloor(f)) 5408f33a025100dea2d951e6d628891fe294b18082Brian 5508f33a025100dea2d951e6d628891fe294b18082Brian 5608f33a025100dea2d951e6d628891fe294b18082Brian/** 5708f33a025100dea2d951e6d628891fe294b18082Brian * Linear interpolation macro 5808f33a025100dea2d951e6d628891fe294b18082Brian */ 590dc4eea64f56cc93e5359372b08b99a2d600273cBrian#define LERP(T, A, B) ( (A) + (T) * ((B) - (A)) ) 600dc4eea64f56cc93e5359372b08b99a2d600273cBrian 610dc4eea64f56cc93e5359372b08b99a2d600273cBrian 620dc4eea64f56cc93e5359372b08b99a2d600273cBrian/** 630dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Do 2D/biliner interpolation of float values. 640dc4eea64f56cc93e5359372b08b99a2d600273cBrian * v00, v10, v01 and v11 are typically four texture samples in a square/box. 650dc4eea64f56cc93e5359372b08b99a2d600273cBrian * a and b are the horizontal and vertical interpolants. 660dc4eea64f56cc93e5359372b08b99a2d600273cBrian * It's important that this function is inlined when compiled with 670dc4eea64f56cc93e5359372b08b99a2d600273cBrian * optimization! If we find that's not true on some systems, convert 680dc4eea64f56cc93e5359372b08b99a2d600273cBrian * to a macro. 690dc4eea64f56cc93e5359372b08b99a2d600273cBrian */ 70b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic INLINE float 71b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianlerp_2d(float a, float b, 72b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float v00, float v10, float v01, float v11) 730dc4eea64f56cc93e5359372b08b99a2d600273cBrian{ 74b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float temp0 = LERP(a, v00, v10); 75b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float temp1 = LERP(a, v01, v11); 760dc4eea64f56cc93e5359372b08b99a2d600273cBrian return LERP(b, temp0, temp1); 770dc4eea64f56cc93e5359372b08b99a2d600273cBrian} 780dc4eea64f56cc93e5359372b08b99a2d600273cBrian 790dc4eea64f56cc93e5359372b08b99a2d600273cBrian 800dc4eea64f56cc93e5359372b08b99a2d600273cBrian/** 81906768316d9521a32d9a7eebc9edaf76c06a98a7Brian * If A is a signed integer, A % B doesn't give the right value for A < 0 82906768316d9521a32d9a7eebc9edaf76c06a98a7Brian * (in terms of texture repeat). Just casting to unsigned fixes that. 830dc4eea64f56cc93e5359372b08b99a2d600273cBrian */ 84906768316d9521a32d9a7eebc9edaf76c06a98a7Brian#define REMAINDER(A, B) ((unsigned) (A) % (unsigned) (B)) 8508f33a025100dea2d951e6d628891fe294b18082Brian 8608f33a025100dea2d951e6d628891fe294b18082Brian 8708f33a025100dea2d951e6d628891fe294b18082Brian/** 8808f33a025100dea2d951e6d628891fe294b18082Brian * Apply texture coord wrapping mode and return integer texture index. 8908f33a025100dea2d951e6d628891fe294b18082Brian * \param wrapMode PIPE_TEX_WRAP_x 9008f33a025100dea2d951e6d628891fe294b18082Brian * \param s the texcoord 9108f33a025100dea2d951e6d628891fe294b18082Brian * \param size the texture image size 9208f33a025100dea2d951e6d628891fe294b18082Brian * \return integer texture index 9308f33a025100dea2d951e6d628891fe294b18082Brian */ 9470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwellstatic INLINE int 9570af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwellnearest_texcoord(unsigned wrapMode, float s, unsigned size) 960dc4eea64f56cc93e5359372b08b99a2d600273cBrian{ 9770af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell int i; 980dc4eea64f56cc93e5359372b08b99a2d600273cBrian switch (wrapMode) { 990dc4eea64f56cc93e5359372b08b99a2d600273cBrian case PIPE_TEX_WRAP_REPEAT: 10008f33a025100dea2d951e6d628891fe294b18082Brian /* s limited to [0,1) */ 10108f33a025100dea2d951e6d628891fe294b18082Brian /* i limited to [0,size-1] */ 10270af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell i = ifloor(s * size); 103906768316d9521a32d9a7eebc9edaf76c06a98a7Brian i = REMAINDER(i, size); 10408f33a025100dea2d951e6d628891fe294b18082Brian return i; 1050dc4eea64f56cc93e5359372b08b99a2d600273cBrian case PIPE_TEX_WRAP_CLAMP: 10608f33a025100dea2d951e6d628891fe294b18082Brian /* s limited to [0,1] */ 10708f33a025100dea2d951e6d628891fe294b18082Brian /* i limited to [0,size-1] */ 10808f33a025100dea2d951e6d628891fe294b18082Brian if (s <= 0.0F) 10908f33a025100dea2d951e6d628891fe294b18082Brian i = 0; 11008f33a025100dea2d951e6d628891fe294b18082Brian else if (s >= 1.0F) 11108f33a025100dea2d951e6d628891fe294b18082Brian i = size - 1; 11208f33a025100dea2d951e6d628891fe294b18082Brian else 11370af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell i = ifloor(s * size); 11408f33a025100dea2d951e6d628891fe294b18082Brian return i; 11508f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 11608f33a025100dea2d951e6d628891fe294b18082Brian { 11708f33a025100dea2d951e6d628891fe294b18082Brian /* s limited to [min,max] */ 11808f33a025100dea2d951e6d628891fe294b18082Brian /* i limited to [0, size-1] */ 119b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float min = 1.0F / (2.0F * size); 120b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float max = 1.0F - min; 12108f33a025100dea2d951e6d628891fe294b18082Brian if (s < min) 12208f33a025100dea2d951e6d628891fe294b18082Brian i = 0; 12308f33a025100dea2d951e6d628891fe294b18082Brian else if (s > max) 12408f33a025100dea2d951e6d628891fe294b18082Brian i = size - 1; 12508f33a025100dea2d951e6d628891fe294b18082Brian else 12670af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell i = ifloor(s * size); 12708f33a025100dea2d951e6d628891fe294b18082Brian } 12808f33a025100dea2d951e6d628891fe294b18082Brian return i; 12908f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 13008f33a025100dea2d951e6d628891fe294b18082Brian { 13108f33a025100dea2d951e6d628891fe294b18082Brian /* s limited to [min,max] */ 13208f33a025100dea2d951e6d628891fe294b18082Brian /* i limited to [-1, size] */ 133b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float min = -1.0F / (2.0F * size); 134b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float max = 1.0F - min; 13508f33a025100dea2d951e6d628891fe294b18082Brian if (s <= min) 13608f33a025100dea2d951e6d628891fe294b18082Brian i = -1; 13708f33a025100dea2d951e6d628891fe294b18082Brian else if (s >= max) 13808f33a025100dea2d951e6d628891fe294b18082Brian i = size; 13908f33a025100dea2d951e6d628891fe294b18082Brian else 14070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell i = ifloor(s * size); 14108f33a025100dea2d951e6d628891fe294b18082Brian } 14208f33a025100dea2d951e6d628891fe294b18082Brian return i; 14308f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_REPEAT: 14408f33a025100dea2d951e6d628891fe294b18082Brian { 145b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float min = 1.0F / (2.0F * size); 146b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float max = 1.0F - min; 14770af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell const int flr = ifloor(s); 148b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float u; 14908f33a025100dea2d951e6d628891fe294b18082Brian if (flr & 1) 150b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian u = 1.0F - (s - (float) flr); 15108f33a025100dea2d951e6d628891fe294b18082Brian else 152b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian u = s - (float) flr; 15308f33a025100dea2d951e6d628891fe294b18082Brian if (u < min) 15408f33a025100dea2d951e6d628891fe294b18082Brian i = 0; 15508f33a025100dea2d951e6d628891fe294b18082Brian else if (u > max) 15608f33a025100dea2d951e6d628891fe294b18082Brian i = size - 1; 15708f33a025100dea2d951e6d628891fe294b18082Brian else 15870af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell i = ifloor(u * size); 15908f33a025100dea2d951e6d628891fe294b18082Brian } 16008f33a025100dea2d951e6d628891fe294b18082Brian return i; 16108f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_CLAMP: 16208f33a025100dea2d951e6d628891fe294b18082Brian { 16308f33a025100dea2d951e6d628891fe294b18082Brian /* s limited to [0,1] */ 16408f33a025100dea2d951e6d628891fe294b18082Brian /* i limited to [0,size-1] */ 165b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float u = FABSF(s); 16608f33a025100dea2d951e6d628891fe294b18082Brian if (u <= 0.0F) 16708f33a025100dea2d951e6d628891fe294b18082Brian i = 0; 16808f33a025100dea2d951e6d628891fe294b18082Brian else if (u >= 1.0F) 16908f33a025100dea2d951e6d628891fe294b18082Brian i = size - 1; 17008f33a025100dea2d951e6d628891fe294b18082Brian else 17170af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell i = ifloor(u * size); 17208f33a025100dea2d951e6d628891fe294b18082Brian } 17308f33a025100dea2d951e6d628891fe294b18082Brian return i; 17408f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: 17508f33a025100dea2d951e6d628891fe294b18082Brian { 17608f33a025100dea2d951e6d628891fe294b18082Brian /* s limited to [min,max] */ 17708f33a025100dea2d951e6d628891fe294b18082Brian /* i limited to [0, size-1] */ 178b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float min = 1.0F / (2.0F * size); 179b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float max = 1.0F - min; 180b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float u = FABSF(s); 18108f33a025100dea2d951e6d628891fe294b18082Brian if (u < min) 18208f33a025100dea2d951e6d628891fe294b18082Brian i = 0; 18308f33a025100dea2d951e6d628891fe294b18082Brian else if (u > max) 18408f33a025100dea2d951e6d628891fe294b18082Brian i = size - 1; 18508f33a025100dea2d951e6d628891fe294b18082Brian else 18670af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell i = ifloor(u * size); 18708f33a025100dea2d951e6d628891fe294b18082Brian } 18808f33a025100dea2d951e6d628891fe294b18082Brian return i; 18908f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: 19008f33a025100dea2d951e6d628891fe294b18082Brian { 19108f33a025100dea2d951e6d628891fe294b18082Brian /* s limited to [min,max] */ 19208f33a025100dea2d951e6d628891fe294b18082Brian /* i limited to [0, size-1] */ 193b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float min = -1.0F / (2.0F * size); 194b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float max = 1.0F - min; 195b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float u = FABSF(s); 19608f33a025100dea2d951e6d628891fe294b18082Brian if (u < min) 19708f33a025100dea2d951e6d628891fe294b18082Brian i = -1; 19808f33a025100dea2d951e6d628891fe294b18082Brian else if (u > max) 19908f33a025100dea2d951e6d628891fe294b18082Brian i = size; 20008f33a025100dea2d951e6d628891fe294b18082Brian else 20170af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell i = ifloor(u * size); 20208f33a025100dea2d951e6d628891fe294b18082Brian } 20308f33a025100dea2d951e6d628891fe294b18082Brian return i; 2040dc4eea64f56cc93e5359372b08b99a2d600273cBrian default: 2050dc4eea64f56cc93e5359372b08b99a2d600273cBrian assert(0); 20608f33a025100dea2d951e6d628891fe294b18082Brian return 0; 2070dc4eea64f56cc93e5359372b08b99a2d600273cBrian } 2080dc4eea64f56cc93e5359372b08b99a2d600273cBrian} 2090dc4eea64f56cc93e5359372b08b99a2d600273cBrian 21008f33a025100dea2d951e6d628891fe294b18082Brian 21108f33a025100dea2d951e6d628891fe294b18082Brian/** 21208f33a025100dea2d951e6d628891fe294b18082Brian * Used to compute texel locations for linear sampling. 21308f33a025100dea2d951e6d628891fe294b18082Brian * \param wrapMode PIPE_TEX_WRAP_x 21408f33a025100dea2d951e6d628891fe294b18082Brian * \param s the texcoord 21508f33a025100dea2d951e6d628891fe294b18082Brian * \param size the texture image size 21608f33a025100dea2d951e6d628891fe294b18082Brian * \param i0 returns first texture index 21708f33a025100dea2d951e6d628891fe294b18082Brian * \param i1 returns second texture index (usually *i0 + 1) 21808f33a025100dea2d951e6d628891fe294b18082Brian * \param a returns blend factor/weight between texture indexes 21908f33a025100dea2d951e6d628891fe294b18082Brian */ 2200dc4eea64f56cc93e5359372b08b99a2d600273cBrianstatic INLINE void 22170af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwelllinear_texcoord(unsigned wrapMode, float s, unsigned size, 22270af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell int *i0, int *i1, float *a) 2230dc4eea64f56cc93e5359372b08b99a2d600273cBrian{ 224b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float u; 2250dc4eea64f56cc93e5359372b08b99a2d600273cBrian switch (wrapMode) { 2260dc4eea64f56cc93e5359372b08b99a2d600273cBrian case PIPE_TEX_WRAP_REPEAT: 22708f33a025100dea2d951e6d628891fe294b18082Brian u = s * size - 0.5F; 228906768316d9521a32d9a7eebc9edaf76c06a98a7Brian *i0 = REMAINDER(ifloor(u), size); 229906768316d9521a32d9a7eebc9edaf76c06a98a7Brian *i1 = REMAINDER(*i0 + 1, size); 2300dc4eea64f56cc93e5359372b08b99a2d600273cBrian break; 2310dc4eea64f56cc93e5359372b08b99a2d600273cBrian case PIPE_TEX_WRAP_CLAMP: 23208f33a025100dea2d951e6d628891fe294b18082Brian if (s <= 0.0F) 23308f33a025100dea2d951e6d628891fe294b18082Brian u = 0.0F; 23408f33a025100dea2d951e6d628891fe294b18082Brian else if (s >= 1.0F) 235b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian u = (float) size; 23608f33a025100dea2d951e6d628891fe294b18082Brian else 23708f33a025100dea2d951e6d628891fe294b18082Brian u = s * size; 23808f33a025100dea2d951e6d628891fe294b18082Brian u -= 0.5F; 23970af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell *i0 = ifloor(u); 24008f33a025100dea2d951e6d628891fe294b18082Brian *i1 = *i0 + 1; 24108f33a025100dea2d951e6d628891fe294b18082Brian break; 24208f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 24308f33a025100dea2d951e6d628891fe294b18082Brian if (s <= 0.0F) 24408f33a025100dea2d951e6d628891fe294b18082Brian u = 0.0F; 24508f33a025100dea2d951e6d628891fe294b18082Brian else if (s >= 1.0F) 246b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian u = (float) size; 24708f33a025100dea2d951e6d628891fe294b18082Brian else 24808f33a025100dea2d951e6d628891fe294b18082Brian u = s * size; 24908f33a025100dea2d951e6d628891fe294b18082Brian u -= 0.5F; 25070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell *i0 = ifloor(u); 25108f33a025100dea2d951e6d628891fe294b18082Brian *i1 = *i0 + 1; 25208f33a025100dea2d951e6d628891fe294b18082Brian if (*i0 < 0) 25308f33a025100dea2d951e6d628891fe294b18082Brian *i0 = 0; 25470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell if (*i1 >= (int) size) 25508f33a025100dea2d951e6d628891fe294b18082Brian *i1 = size - 1; 25608f33a025100dea2d951e6d628891fe294b18082Brian break; 25708f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 25808f33a025100dea2d951e6d628891fe294b18082Brian { 259b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float min = -1.0F / (2.0F * size); 260b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float max = 1.0F - min; 26108f33a025100dea2d951e6d628891fe294b18082Brian if (s <= min) 26208f33a025100dea2d951e6d628891fe294b18082Brian u = min * size; 26308f33a025100dea2d951e6d628891fe294b18082Brian else if (s >= max) 26408f33a025100dea2d951e6d628891fe294b18082Brian u = max * size; 26508f33a025100dea2d951e6d628891fe294b18082Brian else 26608f33a025100dea2d951e6d628891fe294b18082Brian u = s * size; 26708f33a025100dea2d951e6d628891fe294b18082Brian u -= 0.5F; 26870af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell *i0 = ifloor(u); 26908f33a025100dea2d951e6d628891fe294b18082Brian *i1 = *i0 + 1; 27008f33a025100dea2d951e6d628891fe294b18082Brian } 27108f33a025100dea2d951e6d628891fe294b18082Brian break; 27208f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_REPEAT: 27308f33a025100dea2d951e6d628891fe294b18082Brian { 27470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell const int flr = ifloor(s); 27508f33a025100dea2d951e6d628891fe294b18082Brian if (flr & 1) 276b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian u = 1.0F - (s - (float) flr); 27708f33a025100dea2d951e6d628891fe294b18082Brian else 278b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian u = s - (float) flr; 27908f33a025100dea2d951e6d628891fe294b18082Brian u = (u * size) - 0.5F; 28070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell *i0 = ifloor(u); 28108f33a025100dea2d951e6d628891fe294b18082Brian *i1 = *i0 + 1; 28208f33a025100dea2d951e6d628891fe294b18082Brian if (*i0 < 0) 28308f33a025100dea2d951e6d628891fe294b18082Brian *i0 = 0; 28470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell if (*i1 >= (int) size) 28508f33a025100dea2d951e6d628891fe294b18082Brian *i1 = size - 1; 28608f33a025100dea2d951e6d628891fe294b18082Brian } 28708f33a025100dea2d951e6d628891fe294b18082Brian break; 28808f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_CLAMP: 28908f33a025100dea2d951e6d628891fe294b18082Brian u = FABSF(s); 29008f33a025100dea2d951e6d628891fe294b18082Brian if (u >= 1.0F) 291b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian u = (float) size; 29208f33a025100dea2d951e6d628891fe294b18082Brian else 29308f33a025100dea2d951e6d628891fe294b18082Brian u *= size; 29408f33a025100dea2d951e6d628891fe294b18082Brian u -= 0.5F; 29570af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell *i0 = ifloor(u); 29608f33a025100dea2d951e6d628891fe294b18082Brian *i1 = *i0 + 1; 29708f33a025100dea2d951e6d628891fe294b18082Brian break; 29808f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: 29908f33a025100dea2d951e6d628891fe294b18082Brian u = FABSF(s); 30008f33a025100dea2d951e6d628891fe294b18082Brian if (u >= 1.0F) 301b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian u = (float) size; 30208f33a025100dea2d951e6d628891fe294b18082Brian else 30308f33a025100dea2d951e6d628891fe294b18082Brian u *= size; 30408f33a025100dea2d951e6d628891fe294b18082Brian u -= 0.5F; 30570af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell *i0 = ifloor(u); 30608f33a025100dea2d951e6d628891fe294b18082Brian *i1 = *i0 + 1; 30708f33a025100dea2d951e6d628891fe294b18082Brian if (*i0 < 0) 30808f33a025100dea2d951e6d628891fe294b18082Brian *i0 = 0; 30970af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell if (*i1 >= (int) size) 31008f33a025100dea2d951e6d628891fe294b18082Brian *i1 = size - 1; 31108f33a025100dea2d951e6d628891fe294b18082Brian break; 31208f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: 31308f33a025100dea2d951e6d628891fe294b18082Brian { 314b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float min = -1.0F / (2.0F * size); 315b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float max = 1.0F - min; 31608f33a025100dea2d951e6d628891fe294b18082Brian u = FABSF(s); 31708f33a025100dea2d951e6d628891fe294b18082Brian if (u <= min) 31808f33a025100dea2d951e6d628891fe294b18082Brian u = min * size; 31908f33a025100dea2d951e6d628891fe294b18082Brian else if (u >= max) 32008f33a025100dea2d951e6d628891fe294b18082Brian u = max * size; 32108f33a025100dea2d951e6d628891fe294b18082Brian else 32208f33a025100dea2d951e6d628891fe294b18082Brian u *= size; 32308f33a025100dea2d951e6d628891fe294b18082Brian u -= 0.5F; 32470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell *i0 = ifloor(u); 32508f33a025100dea2d951e6d628891fe294b18082Brian *i1 = *i0 + 1; 32608f33a025100dea2d951e6d628891fe294b18082Brian } 3270dc4eea64f56cc93e5359372b08b99a2d600273cBrian break; 3280dc4eea64f56cc93e5359372b08b99a2d600273cBrian default: 3290dc4eea64f56cc93e5359372b08b99a2d600273cBrian assert(0); 3300dc4eea64f56cc93e5359372b08b99a2d600273cBrian } 33108f33a025100dea2d951e6d628891fe294b18082Brian *a = FRAC(u); 3320dc4eea64f56cc93e5359372b08b99a2d600273cBrian} 3330dc4eea64f56cc93e5359372b08b99a2d600273cBrian 3340dc4eea64f56cc93e5359372b08b99a2d600273cBrian 33570af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwellstatic unsigned 336a34b8594b7b2d00404bb639621ec1ce918ba0786Brianchoose_cube_face(float rx, float ry, float rz, float *newS, float *newT) 33734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{ 33834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian /* 33934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian major axis 34034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian direction target sc tc ma 34134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ---------- ------------------------------- --- --- --- 34234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian +rx TEXTURE_CUBE_MAP_POSITIVE_X_EXT -rz -ry rx 34334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian -rx TEXTURE_CUBE_MAP_NEGATIVE_X_EXT +rz -ry rx 34434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian +ry TEXTURE_CUBE_MAP_POSITIVE_Y_EXT +rx +rz ry 34534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian -ry TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT +rx -rz ry 34634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian +rz TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz 34734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian -rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz 34834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian */ 349b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float arx = FABSF(rx), ary = FABSF(ry), arz = FABSF(rz); 35070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell unsigned face; 351b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float sc, tc, ma; 35234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 35334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian if (arx > ary && arx > arz) { 35434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian if (rx >= 0.0F) { 35534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_POS_X; 35634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = -rz; 35734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = -ry; 35834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = arx; 35934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 36034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian else { 36134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_NEG_X; 36234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = rz; 36334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = -ry; 36434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = arx; 36534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 36634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 36734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian else if (ary > arx && ary > arz) { 36834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian if (ry >= 0.0F) { 36934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_POS_Y; 37034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = rx; 37134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = rz; 37234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = ary; 37334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 37434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian else { 37534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_NEG_Y; 37634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = rx; 37734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = -rz; 37834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = ary; 37934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 38034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 38134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian else { 38234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian if (rz > 0.0F) { 38334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_POS_Z; 38434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = rx; 38534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = -ry; 38634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = arz; 38734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 38834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian else { 38934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_NEG_Z; 39034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = -rx; 39134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = -ry; 39234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = arz; 39334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 39434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 39534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 396a34b8594b7b2d00404bb639621ec1ce918ba0786Brian *newS = ( sc / ma + 1.0F ) * 0.5F; 397a34b8594b7b2d00404bb639621ec1ce918ba0786Brian *newT = ( tc / ma + 1.0F ) * 0.5F; 39834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 39934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian return face; 40034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian} 40134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 40234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 403b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/** 404b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * Examine the quad's texture coordinates to compute the partial 405b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * derivatives w.r.t X and Y, then compute lambda (level of detail). 406b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * 407b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * This is only done for fragment shaders, not vertex shaders. 408b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian */ 409b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic float 410b4480285ed5098f1c862690ee105dd46f5e6cd1eBriancompute_lambda(struct tgsi_sampler *sampler, 411b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float s[QUAD_SIZE], 412b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float t[QUAD_SIZE], 413f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian const float p[QUAD_SIZE], 414f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian float lodbias) 415b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian{ 416b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float rho, lambda; 417b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 418b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian assert(s); 419b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian { 420b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dsdx = s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]; 421b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dsdy = s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]; 422b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian dsdx = FABSF(dsdx); 423b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian dsdy = FABSF(dsdy); 424369eefc34c8d7acdb881ea5b0516406d71344fc4Brian rho = MAX2(dsdx, dsdy); 425369eefc34c8d7acdb881ea5b0516406d71344fc4Brian if (sampler->state->normalized_coords) 426753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer rho *= sampler->texture->width[0]; 427b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian } 428b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian if (t) { 429b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]; 430b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dtdy = t[QUAD_TOP_LEFT] - t[QUAD_BOTTOM_LEFT]; 431b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float max; 432b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian dtdx = FABSF(dtdx); 433b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian dtdy = FABSF(dtdy); 434369eefc34c8d7acdb881ea5b0516406d71344fc4Brian max = MAX2(dtdx, dtdy); 435369eefc34c8d7acdb881ea5b0516406d71344fc4Brian if (sampler->state->normalized_coords) 436753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer max *= sampler->texture->height[0]; 437b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian rho = MAX2(rho, max); 438b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian } 439b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian if (p) { 440b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dpdx = p[QUAD_BOTTOM_RIGHT] - p[QUAD_BOTTOM_LEFT]; 441b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dpdy = p[QUAD_TOP_LEFT] - p[QUAD_BOTTOM_LEFT]; 442b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float max; 443b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian dpdx = FABSF(dpdx); 444b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian dpdy = FABSF(dpdy); 445369eefc34c8d7acdb881ea5b0516406d71344fc4Brian max = MAX2(dpdx, dpdy); 446369eefc34c8d7acdb881ea5b0516406d71344fc4Brian if (sampler->state->normalized_coords) 447753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer max *= sampler->texture->depth[0]; 448b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian rho = MAX2(rho, max); 449b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian } 450b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 451b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian lambda = LOG2(rho); 452f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian lambda += lodbias + sampler->state->lod_bias; 453b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian lambda = CLAMP(lambda, sampler->state->min_lod, sampler->state->max_lod); 454b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 455b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian return lambda; 456b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian} 457b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 458b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 459f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian/** 460c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * Do several things here: 461c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 1. Compute lambda from the texcoords, if needed 462c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 2. Determine if we're minifying or magnifying 463c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 3. If minifying, choose mipmap levels 464c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 4. Return image filter to use within mipmap images 465f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian */ 466f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrianstatic void 467c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brianchoose_mipmap_levels(struct tgsi_sampler *sampler, 468c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian const float s[QUAD_SIZE], 469c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian const float t[QUAD_SIZE], 470c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian const float p[QUAD_SIZE], 471c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian float lodbias, 472c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian unsigned *level0, unsigned *level1, float *levelBlend, 473c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian unsigned *imgFilter) 47409a1b912605ff48c8782dcc5aae55ac77e27037bBrian{ 475c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) { 476c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* no mipmap selection needed */ 477c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian *imgFilter = sampler->state->mag_img_filter; 4784da1cdf78fa3b954840650fa46cf72da5daf149fBrian *level0 = *level1 = (int) sampler->state->min_lod; 479c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian } 480c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian else { 481c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian float lambda; 482c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian 483c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian if (1) 484c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* fragment shader */ 485c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian lambda = compute_lambda(sampler, s, t, p, lodbias); 486c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian else 487c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* vertex shader */ 488c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian lambda = lodbias; /* not really a bias, but absolute LOD */ 489c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian 490c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian if (lambda < 0.0) { /* XXX threshold depends on the filter */ 491c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* magnifying */ 492c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian *imgFilter = sampler->state->mag_img_filter; 4934da1cdf78fa3b954840650fa46cf72da5daf149fBrian *level0 = *level1 = 0; 494f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 495c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian else { 496c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* minifying */ 497c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian *imgFilter = sampler->state->min_img_filter; 498c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian 499c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* choose mipmap level(s) and compute the blend factor between them */ 500c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NEAREST) { 501c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* Nearest mipmap level */ 502c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian const int lvl = (int) (lambda + 0.5); 503c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian *level0 = 5044da1cdf78fa3b954840650fa46cf72da5daf149fBrian *level1 = CLAMP(lvl, 0, (int) sampler->texture->last_level); 505c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian } 506c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian else { 507c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* Linear interpolation between mipmap levels */ 508c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian const int lvl = (int) lambda; 5094da1cdf78fa3b954840650fa46cf72da5daf149fBrian *level0 = CLAMP(lvl, 0, (int) sampler->texture->last_level); 5104da1cdf78fa3b954840650fa46cf72da5daf149fBrian *level1 = CLAMP(lvl + 1, 0, (int) sampler->texture->last_level); 511c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian *levelBlend = FRAC(lambda); /* blending weight between levels */ 512c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian } 513f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 51409a1b912605ff48c8782dcc5aae55ac77e27037bBrian } 51509a1b912605ff48c8782dcc5aae55ac77e27037bBrian} 51609a1b912605ff48c8782dcc5aae55ac77e27037bBrian 51708f33a025100dea2d951e6d628891fe294b18082Brian 518b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/** 519a13de2464dd034ff117f9314df5757d068cae8e5Brian * Get a texel from a texture, using the texture tile cache. 520a13de2464dd034ff117f9314df5757d068cae8e5Brian * 521b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param face the cube face in 0..5 522b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param level the mipmap level 523b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param x the x coord of texel within 2D image 524b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param y the y coord of texel within 2D image 52570eb7996f265f3634dabda078f13d1be3533cc65Brian * \param z which slice of a 3D texture 526b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param rgba the quad to put the texel/color into 527b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param j which element of the rgba quad to write to 52870eb7996f265f3634dabda078f13d1be3533cc65Brian * 52970eb7996f265f3634dabda078f13d1be3533cc65Brian * XXX maybe move this into sp_tile_cache.c and merge with the 53070eb7996f265f3634dabda078f13d1be3533cc65Brian * sp_get_cached_tile_tex() function. Also, get 4 texels instead of 1... 531b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian */ 532b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic void 533b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianget_texel(struct tgsi_sampler *sampler, 53470eb7996f265f3634dabda078f13d1be3533cc65Brian unsigned face, unsigned level, int x, int y, int z, 535a13de2464dd034ff117f9314df5757d068cae8e5Brian float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j) 536b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian{ 53770eb7996f265f3634dabda078f13d1be3533cc65Brian const int tx = x % TILE_SIZE; 53870eb7996f265f3634dabda078f13d1be3533cc65Brian const int ty = y % TILE_SIZE; 53970eb7996f265f3634dabda078f13d1be3533cc65Brian const struct softpipe_cached_tile *tile 54070eb7996f265f3634dabda078f13d1be3533cc65Brian = sp_get_cached_tile_tex(sampler->pipe, sampler->cache, 54170eb7996f265f3634dabda078f13d1be3533cc65Brian x, y, z, face, level); 54270eb7996f265f3634dabda078f13d1be3533cc65Brian rgba[0][j] = tile->data.color[ty][tx][0]; 54370eb7996f265f3634dabda078f13d1be3533cc65Brian rgba[1][j] = tile->data.color[ty][tx][1]; 54470eb7996f265f3634dabda078f13d1be3533cc65Brian rgba[2][j] = tile->data.color[ty][tx][2]; 54570eb7996f265f3634dabda078f13d1be3533cc65Brian rgba[3][j] = tile->data.color[ty][tx][3]; 546b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian} 547b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 548b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 5493d8c05f7320151898dd224c1daaf3118e1f7ea34Brian/** 5503d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * Compare texcoord 'p' (aka R) against texture value 'rgba[0]' 5513d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * When we sampled the depth texture, the depth value was put into all 5523d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * RGBA channels. We look at the red channel here. 5533d8c05f7320151898dd224c1daaf3118e1f7ea34Brian */ 5543d8c05f7320151898dd224c1daaf3118e1f7ea34Brianstatic INLINE void 5553d8c05f7320151898dd224c1daaf3118e1f7ea34Brianshadow_compare(uint compare_func, 5563d8c05f7320151898dd224c1daaf3118e1f7ea34Brian float rgba[NUM_CHANNELS][QUAD_SIZE], 5573d8c05f7320151898dd224c1daaf3118e1f7ea34Brian const float p[QUAD_SIZE], 5583d8c05f7320151898dd224c1daaf3118e1f7ea34Brian uint j) 5593d8c05f7320151898dd224c1daaf3118e1f7ea34Brian{ 5603d8c05f7320151898dd224c1daaf3118e1f7ea34Brian int k; 5613d8c05f7320151898dd224c1daaf3118e1f7ea34Brian switch (compare_func) { 5623d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_LESS: 5633d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] < rgba[0][j]; 5643d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 5653d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_LEQUAL: 5663d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] <= rgba[0][j]; 5673d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 5683d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_GREATER: 5693d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] > rgba[0][j]; 5703d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 5713d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_GEQUAL: 5723d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] >= rgba[0][j]; 5733d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 5743d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_EQUAL: 5753d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] == rgba[0][j]; 5763d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 5773d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_NOTEQUAL: 5783d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] != rgba[0][j]; 5793d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 5803d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_ALWAYS: 5813d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = 1; 5823d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 5833d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_NEVER: 5843d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = 0; 5853d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 5863d8c05f7320151898dd224c1daaf3118e1f7ea34Brian default: 5873d8c05f7320151898dd224c1daaf3118e1f7ea34Brian assert(0); 5883d8c05f7320151898dd224c1daaf3118e1f7ea34Brian } 5893d8c05f7320151898dd224c1daaf3118e1f7ea34Brian 5903d8c05f7320151898dd224c1daaf3118e1f7ea34Brian rgba[0][j] = rgba[1][j] = rgba[2][j] = (float) k; 5913d8c05f7320151898dd224c1daaf3118e1f7ea34Brian} 5923d8c05f7320151898dd224c1daaf3118e1f7ea34Brian 593b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 594b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/** 595a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Common code for sampling 1D/2D/cube textures. 596a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Could probably extend for 3D... 5970dc4eea64f56cc93e5359372b08b99a2d600273cBrian */ 598e12810d92ffb3547680b227bf88937c03018112bBrianstatic void 599a34b8594b7b2d00404bb639621ec1ce918ba0786Briansp_get_samples_2d_common(struct tgsi_sampler *sampler, 600a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float s[QUAD_SIZE], 601a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float t[QUAD_SIZE], 602a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float p[QUAD_SIZE], 603a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float lodbias, 604a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float rgba[NUM_CHANNELS][QUAD_SIZE], 605a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const unsigned faces[4]) 6060dc4eea64f56cc93e5359372b08b99a2d600273cBrian{ 6073d8c05f7320151898dd224c1daaf3118e1f7ea34Brian const uint compare_func = sampler->state->compare_func; 608f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian unsigned level0, level1, j, imgFilter; 609f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian int width, height; 610c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian float levelBlend; 611a34b8594b7b2d00404bb639621ec1ce918ba0786Brian 612c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian choose_mipmap_levels(sampler, s, t, p, lodbias, 613c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian &level0, &level1, &levelBlend, &imgFilter); 61409a1b912605ff48c8782dcc5aae55ac77e27037bBrian 615369eefc34c8d7acdb881ea5b0516406d71344fc4Brian if (sampler->state->normalized_coords) { 616753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer width = sampler->texture->width[level0]; 617753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer height = sampler->texture->height[level0]; 618369eefc34c8d7acdb881ea5b0516406d71344fc4Brian } 619369eefc34c8d7acdb881ea5b0516406d71344fc4Brian else { 620ee295fccdd0c94cb6b8af4dfb30283e39f548223Michal Krol width = height = 1; 621369eefc34c8d7acdb881ea5b0516406d71344fc4Brian } 62209a1b912605ff48c8782dcc5aae55ac77e27037bBrian 623b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian assert(width > 0); 624612cfb749c3526eeb446bbc631bf24716522f373Brian 625b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian switch (imgFilter) { 6260dc4eea64f56cc93e5359372b08b99a2d600273cBrian case PIPE_TEX_FILTER_NEAREST: 627b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian for (j = 0; j < QUAD_SIZE; j++) { 628b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian int x = nearest_texcoord(sampler->state->wrap_s, s[j], width); 629b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian int y = nearest_texcoord(sampler->state->wrap_t, t[j], height); 630df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level0, x, y, 0, rgba, j); 6313d8c05f7320151898dd224c1daaf3118e1f7ea34Brian if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { 6323d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, rgba, p, j); 6333d8c05f7320151898dd224c1daaf3118e1f7ea34Brian } 634f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian 635f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian if (level0 != level1) { 636f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian /* get texels from second mipmap level and blend */ 637f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian float rgba2[4][4]; 638f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian unsigned c; 639f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian x = x / 2; 640f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian y = y / 2; 641df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level1, x, y, 0, rgba2, j); 6423d8c05f7320151898dd224c1daaf3118e1f7ea34Brian if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){ 6433d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, rgba2, p, j); 6443d8c05f7320151898dd224c1daaf3118e1f7ea34Brian } 6453d8c05f7320151898dd224c1daaf3118e1f7ea34Brian 646f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian for (c = 0; c < NUM_CHANNELS; c++) { 64717c2f56dc3f2f58ba89d8e305e7d9b423e3cae16Brian rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]); 648f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 649f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 6500dc4eea64f56cc93e5359372b08b99a2d600273cBrian } 6510dc4eea64f56cc93e5359372b08b99a2d600273cBrian break; 6520dc4eea64f56cc93e5359372b08b99a2d600273cBrian case PIPE_TEX_FILTER_LINEAR: 653b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian for (j = 0; j < QUAD_SIZE; j++) { 654b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float tx[4][4], a, b; 655b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian int x0, y0, x1, y1, c; 656b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian linear_texcoord(sampler->state->wrap_s, s[j], width, &x0, &x1, &a); 657b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian linear_texcoord(sampler->state->wrap_t, t[j], height, &y0, &y1, &b); 658df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level0, x0, y0, 0, tx, 0); 659df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level0, x1, y0, 0, tx, 1); 660df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level0, x0, y1, 0, tx, 2); 661df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level0, x1, y1, 0, tx, 3); 6623d8c05f7320151898dd224c1daaf3118e1f7ea34Brian if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { 6633d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, tx, p, 0); 6643d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, tx, p, 1); 6653d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, tx, p, 2); 6663d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, tx, p, 3); 6673d8c05f7320151898dd224c1daaf3118e1f7ea34Brian } 6683d8c05f7320151898dd224c1daaf3118e1f7ea34Brian 669b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian for (c = 0; c < 4; c++) { 670b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian rgba[c][j] = lerp_2d(a, b, tx[c][0], tx[c][1], tx[c][2], tx[c][3]); 671b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian } 672f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian 673f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian if (level0 != level1) { 674f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian /* get texels from second mipmap level and blend */ 675f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian float rgba2[4][4]; 676f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian x0 = x0 / 2; 677f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian y0 = y0 / 2; 678f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian x1 = x1 / 2; 679f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian y1 = y1 / 2; 680df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level1, x0, y0, 0, tx, 0); 681df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level1, x1, y0, 0, tx, 1); 682df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level1, x0, y1, 0, tx, 2); 683df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level1, x1, y1, 0, tx, 3); 6843d8c05f7320151898dd224c1daaf3118e1f7ea34Brian if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){ 6853d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, tx, p, 0); 6863d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, tx, p, 1); 6873d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, tx, p, 2); 6883d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, tx, p, 3); 6893d8c05f7320151898dd224c1daaf3118e1f7ea34Brian } 6903d8c05f7320151898dd224c1daaf3118e1f7ea34Brian 691f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian for (c = 0; c < 4; c++) { 692f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian rgba2[c][j] = lerp_2d(a, b, 693f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian tx[c][0], tx[c][1], tx[c][2], tx[c][3]); 694f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 695f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian 696f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian for (c = 0; c < NUM_CHANNELS; c++) { 697c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]); 698f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 699f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 70009a1b912605ff48c8782dcc5aae55ac77e27037bBrian } 70109a1b912605ff48c8782dcc5aae55ac77e27037bBrian break; 7020dc4eea64f56cc93e5359372b08b99a2d600273cBrian default: 7030dc4eea64f56cc93e5359372b08b99a2d600273cBrian assert(0); 7040dc4eea64f56cc93e5359372b08b99a2d600273cBrian } 7050dc4eea64f56cc93e5359372b08b99a2d600273cBrian} 70634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 70734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 70834a48abd5ff82ce9748fc29191e35a0985d47c5fBrianstatic void 709a34b8594b7b2d00404bb639621ec1ce918ba0786Briansp_get_samples_1d(struct tgsi_sampler *sampler, 710a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float s[QUAD_SIZE], 711a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float t[QUAD_SIZE], 712a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float p[QUAD_SIZE], 713a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float lodbias, 714a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float rgba[NUM_CHANNELS][QUAD_SIZE]) 715a34b8594b7b2d00404bb639621ec1ce918ba0786Brian{ 716a34b8594b7b2d00404bb639621ec1ce918ba0786Brian static const unsigned faces[4] = {0, 0, 0, 0}; 717d16b4bc32a731cb6ae320e8c187af3bc751d4138Brian static const float tzero[4] = {0, 0, 0, 0}; 718d16b4bc32a731cb6ae320e8c187af3bc751d4138Brian sp_get_samples_2d_common(sampler, s, tzero, NULL, lodbias, rgba, faces); 719a34b8594b7b2d00404bb639621ec1ce918ba0786Brian} 720a34b8594b7b2d00404bb639621ec1ce918ba0786Brian 721a34b8594b7b2d00404bb639621ec1ce918ba0786Brian 722a34b8594b7b2d00404bb639621ec1ce918ba0786Brianstatic void 723a34b8594b7b2d00404bb639621ec1ce918ba0786Briansp_get_samples_2d(struct tgsi_sampler *sampler, 724a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float s[QUAD_SIZE], 725a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float t[QUAD_SIZE], 726a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float p[QUAD_SIZE], 727a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float lodbias, 728a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float rgba[NUM_CHANNELS][QUAD_SIZE]) 729a34b8594b7b2d00404bb639621ec1ce918ba0786Brian{ 730a34b8594b7b2d00404bb639621ec1ce918ba0786Brian static const unsigned faces[4] = {0, 0, 0, 0}; 7313d8c05f7320151898dd224c1daaf3118e1f7ea34Brian sp_get_samples_2d_common(sampler, s, t, p, lodbias, rgba, faces); 732a34b8594b7b2d00404bb639621ec1ce918ba0786Brian} 733a34b8594b7b2d00404bb639621ec1ce918ba0786Brian 734a34b8594b7b2d00404bb639621ec1ce918ba0786Brian 735a34b8594b7b2d00404bb639621ec1ce918ba0786Brianstatic void 736b4480285ed5098f1c862690ee105dd46f5e6cd1eBriansp_get_samples_3d(struct tgsi_sampler *sampler, 737b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float s[QUAD_SIZE], 738b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float t[QUAD_SIZE], 739b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float p[QUAD_SIZE], 740f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian float lodbias, 741b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float rgba[NUM_CHANNELS][QUAD_SIZE]) 74234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{ 74334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian /* get/map pipe_surfaces corresponding to 3D tex slices */ 7443d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian unsigned level0, level1, j, imgFilter; 7453d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian int width, height, depth; 7463d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian float levelBlend; 7473d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian const uint face = 0; 7483d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 7493d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian choose_mipmap_levels(sampler, s, t, p, lodbias, 7503d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian &level0, &level1, &levelBlend, &imgFilter); 7513d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 7523d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian if (sampler->state->normalized_coords) { 753753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer width = sampler->texture->width[level0]; 754753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer height = sampler->texture->height[level0]; 755753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer depth = sampler->texture->depth[level0]; 7563d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 7573d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian else { 758ee295fccdd0c94cb6b8af4dfb30283e39f548223Michal Krol width = height = depth = 1; 7593d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 7603d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 7613d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian assert(width > 0); 7623d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian assert(height > 0); 7633d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian assert(depth > 0); 7643d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 7653d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian switch (imgFilter) { 7663d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian case PIPE_TEX_FILTER_NEAREST: 7673d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian for (j = 0; j < QUAD_SIZE; j++) { 7683d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian int x = nearest_texcoord(sampler->state->wrap_s, s[j], width); 7693d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian int y = nearest_texcoord(sampler->state->wrap_t, t[j], height); 7703d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian int z = nearest_texcoord(sampler->state->wrap_r, p[j], depth); 771df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level0, x, y, z, rgba, j); 7723d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 7733d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian if (level0 != level1) { 7743d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian /* get texels from second mipmap level and blend */ 7753d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian float rgba2[4][4]; 7763d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian unsigned c; 7773d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian x /= 2; 7783d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian y /= 2; 7793d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian z /= 2; 780df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level1, x, y, z, rgba2, j); 7813d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian for (c = 0; c < NUM_CHANNELS; c++) { 7823d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian rgba[c][j] = LERP(levelBlend, rgba2[c][j], rgba[c][j]); 7833d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 7843d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 7853d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 7863d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian break; 7873d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian case PIPE_TEX_FILTER_LINEAR: 7883d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian for (j = 0; j < QUAD_SIZE; j++) { 789df4410a59784482fcbd48f82788dd0a9f5a62c15Brian float texel0[4][4], texel1[4][4]; 790df4410a59784482fcbd48f82788dd0a9f5a62c15Brian float xw, yw, zw; /* interpolation weights */ 7913d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian int x0, x1, y0, y1, z0, z1, c; 7923d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian linear_texcoord(sampler->state->wrap_s, s[j], width, &x0, &x1, &xw); 7933d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian linear_texcoord(sampler->state->wrap_t, t[j], height, &y0, &y1, &yw); 7943d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian linear_texcoord(sampler->state->wrap_r, p[j], depth, &z0, &z1, &zw); 795df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level0, x0, y0, z0, texel0, 0); 796df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level0, x1, y0, z0, texel0, 1); 797df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level0, x0, y1, z0, texel0, 2); 798df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level0, x1, y1, z0, texel0, 3); 799df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level0, x0, y0, z1, texel1, 0); 800df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level0, x1, y0, z1, texel1, 1); 801df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level0, x0, y1, z1, texel1, 2); 802df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level0, x1, y1, z1, texel1, 3); 8033d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 8043d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian /* 3D lerp */ 8053d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian for (c = 0; c < 4; c++) { 8063d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian float ctemp0[4][4], ctemp1[4][4]; 8073d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian ctemp0[c][j] = lerp_2d(xw, yw, 8083d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian texel0[c][0], texel0[c][1], 8093d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian texel0[c][2], texel0[c][3]); 8103d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian ctemp1[c][j] = lerp_2d(xw, yw, 8113d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian texel1[c][0], texel1[c][1], 8123d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian texel1[c][2], texel1[c][3]); 8133d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian rgba[c][j] = LERP(zw, ctemp0[c][j], ctemp1[c][j]); 8143d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 8153d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 8163d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian if (level0 != level1) { 8173d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian /* get texels from second mipmap level and blend */ 8183d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian float rgba2[4][4]; 8193d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian x0 /= 2; 8203d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian y0 /= 2; 8213d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian z0 /= 2; 8223d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian x1 /= 2; 8233d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian y1 /= 2; 8243d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian z1 /= 2; 825df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level1, x0, y0, z0, texel0, 0); 826df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level1, x1, y0, z0, texel0, 1); 827df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level1, x0, y1, z0, texel0, 2); 828df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level1, x1, y1, z0, texel0, 3); 829df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level1, x0, y0, z1, texel1, 0); 830df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level1, x1, y0, z1, texel1, 1); 831df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level1, x0, y1, z1, texel1, 2); 832df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level1, x1, y1, z1, texel1, 3); 8333d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 8343d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian /* 3D lerp */ 8353d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian for (c = 0; c < 4; c++) { 8363d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian float ctemp0[4][4], ctemp1[4][4]; 8373d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian ctemp0[c][j] = lerp_2d(xw, yw, 8383d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian texel0[c][0], texel0[c][1], 8393d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian texel0[c][2], texel0[c][3]); 8403d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian ctemp1[c][j] = lerp_2d(xw, yw, 8413d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian texel1[c][0], texel1[c][1], 8423d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian texel1[c][2], texel1[c][3]); 8433d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian rgba2[c][j] = LERP(zw, ctemp0[c][j], ctemp1[c][j]); 8443d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 8453d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 8463d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian /* blend mipmap levels */ 8473d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian for (c = 0; c < NUM_CHANNELS; c++) { 8483d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]); 8493d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 8503d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 8513d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 8523d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian break; 8533d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian default: 8543d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian assert(0); 8553d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 85634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian} 85734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 85834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 85934a48abd5ff82ce9748fc29191e35a0985d47c5fBrianstatic void 860b4480285ed5098f1c862690ee105dd46f5e6cd1eBriansp_get_samples_cube(struct tgsi_sampler *sampler, 861b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float s[QUAD_SIZE], 862b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float t[QUAD_SIZE], 863b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float p[QUAD_SIZE], 864f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian float lodbias, 865b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float rgba[NUM_CHANNELS][QUAD_SIZE]) 86634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{ 867a34b8594b7b2d00404bb639621ec1ce918ba0786Brian unsigned faces[QUAD_SIZE], j; 868a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float ssss[4], tttt[4]; 869b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian for (j = 0; j < QUAD_SIZE; j++) { 870a34b8594b7b2d00404bb639621ec1ce918ba0786Brian faces[j] = choose_cube_face(s[j], t[j], p[j], ssss + j, tttt + j); 871b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian } 872a34b8594b7b2d00404bb639621ec1ce918ba0786Brian sp_get_samples_2d_common(sampler, ssss, tttt, NULL, lodbias, rgba, faces); 87334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian} 87434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 87534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 876a34b8594b7b2d00404bb639621ec1ce918ba0786Brian/** 877a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Called via tgsi_sampler::get_samples() 878a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Use the sampler's state setting to get a filtered RGBA value 879753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * from the sampler's texture. 880a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * 881a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * XXX we can implement many versions of this function, each 882a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * tightly coded for a specific combination of sampler state 883a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * (nearest + repeat), (bilinear mipmap + clamp), etc. 884a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * 885a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * The update_samplers() function in st_atom_sampler.c could create 886a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * a new tgsi_sampler object for each state combo it finds.... 887a34b8594b7b2d00404bb639621ec1ce918ba0786Brian */ 88834a48abd5ff82ce9748fc29191e35a0985d47c5fBrianvoid 889b4480285ed5098f1c862690ee105dd46f5e6cd1eBriansp_get_samples(struct tgsi_sampler *sampler, 890b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float s[QUAD_SIZE], 891b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float t[QUAD_SIZE], 892b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float p[QUAD_SIZE], 893f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian float lodbias, 894b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float rgba[NUM_CHANNELS][QUAD_SIZE]) 89534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{ 8964f23468bd0d14b8ed687a641003d587b91ad39a7Brian if (!sampler->texture) 8974f23468bd0d14b8ed687a641003d587b91ad39a7Brian return; 8984f23468bd0d14b8ed687a641003d587b91ad39a7Brian 89934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian switch (sampler->texture->target) { 90070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell case PIPE_TEXTURE_1D: 901f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian sp_get_samples_1d(sampler, s, t, p, lodbias, rgba); 90234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian break; 90370af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell case PIPE_TEXTURE_2D: 904f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian sp_get_samples_2d(sampler, s, t, p, lodbias, rgba); 90534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian break; 90670af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell case PIPE_TEXTURE_3D: 907f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian sp_get_samples_3d(sampler, s, t, p, lodbias, rgba); 90834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian break; 90970af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell case PIPE_TEXTURE_CUBE: 910f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian sp_get_samples_cube(sampler, s, t, p, lodbias, rgba); 91134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian break; 91234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian default: 91334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian assert(0); 91434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 91534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian} 91634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 917