sp_tex_sample.c revision b1c8fa5b6002296d9abe21c06d5cb81a3f70828a
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 335b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian/** 336b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * For RECT textures / unnormalized texcoords 337b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * Only a subset of wrap modes supported. 338b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian */ 339b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrianstatic INLINE int 340b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBriannearest_texcoord_unnorm(unsigned wrapMode, float s, unsigned size) 341b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{ 342b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian int i; 343b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian switch (wrapMode) { 344b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_WRAP_CLAMP: 345b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian i = ifloor(s); 346b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian return CLAMP(i, 0, size-1); 347b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 348b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian /* fall-through */ 349b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 350b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian return ifloor( CLAMP(s, 0.5F, size - 0.5F) ); 351b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian default: 352b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(0); 353b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian return 0; 354b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 355b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian} 356b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 357b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 358b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian/** 359b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * For RECT textures / unnormalized texcoords. 360b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * Only a subset of wrap modes supported. 361b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian */ 362b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrianstatic INLINE void 363b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrianlinear_texcoord_unnorm(unsigned wrapMode, float s, unsigned size, 364b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian int *i0, int *i1, float *a) 365b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{ 366b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian switch (wrapMode) { 367b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_WRAP_CLAMP: 368b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian /* Not exactly what the spec says, but it matches NVIDIA output */ 369b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian s = CLAMP(s - 0.5F, 0.0, size - 1.0); 370b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian *i0 = ifloor(s); 371b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian *i1 = *i0 + 1; 372b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian break; 373b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 374b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian /* fall-through */ 375b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 376b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian s = CLAMP(s, 0.5F, size - 0.5F); 377b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian s -= 0.5F; 378b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian *i0 = ifloor(s); 379b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian *i1 = *i0 + 1; 380b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian if (*i1 > size - 1) 381b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian *i1 = size - 1; 382b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian break; 383b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian default: 384b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(0); 385b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 386b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian *a = FRAC(s); 387b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian} 388b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 389b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 39070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwellstatic unsigned 391a34b8594b7b2d00404bb639621ec1ce918ba0786Brianchoose_cube_face(float rx, float ry, float rz, float *newS, float *newT) 39234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{ 39334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian /* 39434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian major axis 39534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian direction target sc tc ma 39634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ---------- ------------------------------- --- --- --- 39734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian +rx TEXTURE_CUBE_MAP_POSITIVE_X_EXT -rz -ry rx 39834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian -rx TEXTURE_CUBE_MAP_NEGATIVE_X_EXT +rz -ry rx 39934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian +ry TEXTURE_CUBE_MAP_POSITIVE_Y_EXT +rx +rz ry 40034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian -ry TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT +rx -rz ry 40134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian +rz TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz 40234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian -rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz 40334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian */ 404b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float arx = FABSF(rx), ary = FABSF(ry), arz = FABSF(rz); 40570af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell unsigned face; 406b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float sc, tc, ma; 40734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 40834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian if (arx > ary && arx > arz) { 40934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian if (rx >= 0.0F) { 41034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_POS_X; 41134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = -rz; 41234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = -ry; 41334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = arx; 41434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 41534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian else { 41634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_NEG_X; 41734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = rz; 41834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = -ry; 41934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = arx; 42034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 42134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 42234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian else if (ary > arx && ary > arz) { 42334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian if (ry >= 0.0F) { 42434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_POS_Y; 42534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = rx; 42634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = rz; 42734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = ary; 42834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 42934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian else { 43034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_NEG_Y; 43134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = rx; 43234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = -rz; 43334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = ary; 43434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 43534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 43634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian else { 43734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian if (rz > 0.0F) { 43834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_POS_Z; 43934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = rx; 44034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = -ry; 44134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = arz; 44234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 44334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian else { 44434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_NEG_Z; 44534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = -rx; 44634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = -ry; 44734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = arz; 44834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 44934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 45034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 451a34b8594b7b2d00404bb639621ec1ce918ba0786Brian *newS = ( sc / ma + 1.0F ) * 0.5F; 452a34b8594b7b2d00404bb639621ec1ce918ba0786Brian *newT = ( tc / ma + 1.0F ) * 0.5F; 45334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 45434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian return face; 45534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian} 45634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 45734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 458b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/** 459b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * Examine the quad's texture coordinates to compute the partial 460b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * derivatives w.r.t X and Y, then compute lambda (level of detail). 461b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * 462b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * This is only done for fragment shaders, not vertex shaders. 463b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian */ 464b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic float 465b4480285ed5098f1c862690ee105dd46f5e6cd1eBriancompute_lambda(struct tgsi_sampler *sampler, 466b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float s[QUAD_SIZE], 467b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float t[QUAD_SIZE], 468f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian const float p[QUAD_SIZE], 469f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian float lodbias) 470b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian{ 471b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float rho, lambda; 472b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 473b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(sampler->state->normalized_coords); 474b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 475b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian assert(s); 476b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian { 477b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dsdx = s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]; 478b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dsdy = s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]; 479b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian dsdx = FABSF(dsdx); 480b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian dsdy = FABSF(dsdy); 481b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian rho = MAX2(dsdx, dsdy) * sampler->texture->width[0]; 482b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian } 483b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian if (t) { 484b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]; 485b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dtdy = t[QUAD_TOP_LEFT] - t[QUAD_BOTTOM_LEFT]; 486b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float max; 487b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian dtdx = FABSF(dtdx); 488b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian dtdy = FABSF(dtdy); 489b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian max = MAX2(dtdx, dtdy) * sampler->texture->height[0]; 490b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian rho = MAX2(rho, max); 491b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian } 492b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian if (p) { 493b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dpdx = p[QUAD_BOTTOM_RIGHT] - p[QUAD_BOTTOM_LEFT]; 494b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dpdy = p[QUAD_TOP_LEFT] - p[QUAD_BOTTOM_LEFT]; 495b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float max; 496b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian dpdx = FABSF(dpdx); 497b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian dpdy = FABSF(dpdy); 498b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian max = MAX2(dpdx, dpdy) * sampler->texture->depth[0]; 499b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian rho = MAX2(rho, max); 500b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian } 501b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 502b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian lambda = LOG2(rho); 503f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian lambda += lodbias + sampler->state->lod_bias; 504b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian lambda = CLAMP(lambda, sampler->state->min_lod, sampler->state->max_lod); 505b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 506b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian return lambda; 507b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian} 508b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 509b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 510f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian/** 511c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * Do several things here: 512c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 1. Compute lambda from the texcoords, if needed 513c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 2. Determine if we're minifying or magnifying 514c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 3. If minifying, choose mipmap levels 515c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 4. Return image filter to use within mipmap images 516f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian */ 517f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrianstatic void 518c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brianchoose_mipmap_levels(struct tgsi_sampler *sampler, 519c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian const float s[QUAD_SIZE], 520c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian const float t[QUAD_SIZE], 521c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian const float p[QUAD_SIZE], 522c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian float lodbias, 523c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian unsigned *level0, unsigned *level1, float *levelBlend, 524c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian unsigned *imgFilter) 52509a1b912605ff48c8782dcc5aae55ac77e27037bBrian{ 526c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) { 527c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* no mipmap selection needed */ 5280c6bbd41bd6dc1041eaca7c907d3768d107c1afaBrian *level0 = *level1 = CLAMP((int) sampler->state->min_lod, 5290c6bbd41bd6dc1041eaca7c907d3768d107c1afaBrian 0, (int) sampler->texture->last_level); 53008c9534107fcaf06f9b801551524ed5dc724db13Brian 53108c9534107fcaf06f9b801551524ed5dc724db13Brian if (sampler->state->min_img_filter != sampler->state->mag_img_filter) { 53208c9534107fcaf06f9b801551524ed5dc724db13Brian /* non-mipmapped texture, but still need to determine if doing 53308c9534107fcaf06f9b801551524ed5dc724db13Brian * minification or magnification. 53408c9534107fcaf06f9b801551524ed5dc724db13Brian */ 53508c9534107fcaf06f9b801551524ed5dc724db13Brian float lambda = compute_lambda(sampler, s, t, p, lodbias); 5363b2a291888d8e62787de03f8529806fb562bd186Brian if (lambda <= 0.0) { 53708c9534107fcaf06f9b801551524ed5dc724db13Brian *imgFilter = sampler->state->mag_img_filter; 53808c9534107fcaf06f9b801551524ed5dc724db13Brian } 53908c9534107fcaf06f9b801551524ed5dc724db13Brian else { 54008c9534107fcaf06f9b801551524ed5dc724db13Brian *imgFilter = sampler->state->min_img_filter; 54108c9534107fcaf06f9b801551524ed5dc724db13Brian } 54208c9534107fcaf06f9b801551524ed5dc724db13Brian } 5433b2a291888d8e62787de03f8529806fb562bd186Brian else { 5443b2a291888d8e62787de03f8529806fb562bd186Brian *imgFilter = sampler->state->mag_img_filter; 5453b2a291888d8e62787de03f8529806fb562bd186Brian } 546c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian } 547c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian else { 548c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian float lambda; 549c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian 550c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian if (1) 551c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* fragment shader */ 552c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian lambda = compute_lambda(sampler, s, t, p, lodbias); 553c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian else 554c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* vertex shader */ 555c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian lambda = lodbias; /* not really a bias, but absolute LOD */ 556c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian 5573b2a291888d8e62787de03f8529806fb562bd186Brian if (lambda <= 0.0) { /* XXX threshold depends on the filter */ 558c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* magnifying */ 559c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian *imgFilter = sampler->state->mag_img_filter; 5604da1cdf78fa3b954840650fa46cf72da5daf149fBrian *level0 = *level1 = 0; 561f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 562c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian else { 563c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* minifying */ 564c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian *imgFilter = sampler->state->min_img_filter; 565c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian 566c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* choose mipmap level(s) and compute the blend factor between them */ 567c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NEAREST) { 568c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* Nearest mipmap level */ 569c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian const int lvl = (int) (lambda + 0.5); 570c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian *level0 = 5714da1cdf78fa3b954840650fa46cf72da5daf149fBrian *level1 = CLAMP(lvl, 0, (int) sampler->texture->last_level); 572c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian } 573c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian else { 574c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* Linear interpolation between mipmap levels */ 575c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian const int lvl = (int) lambda; 5764da1cdf78fa3b954840650fa46cf72da5daf149fBrian *level0 = CLAMP(lvl, 0, (int) sampler->texture->last_level); 5774da1cdf78fa3b954840650fa46cf72da5daf149fBrian *level1 = CLAMP(lvl + 1, 0, (int) sampler->texture->last_level); 578c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian *levelBlend = FRAC(lambda); /* blending weight between levels */ 579c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian } 580f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 58109a1b912605ff48c8782dcc5aae55ac77e27037bBrian } 58209a1b912605ff48c8782dcc5aae55ac77e27037bBrian} 58309a1b912605ff48c8782dcc5aae55ac77e27037bBrian 58408f33a025100dea2d951e6d628891fe294b18082Brian 585b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/** 586a13de2464dd034ff117f9314df5757d068cae8e5Brian * Get a texel from a texture, using the texture tile cache. 587a13de2464dd034ff117f9314df5757d068cae8e5Brian * 588b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param face the cube face in 0..5 589b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param level the mipmap level 590b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param x the x coord of texel within 2D image 591b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param y the y coord of texel within 2D image 59270eb7996f265f3634dabda078f13d1be3533cc65Brian * \param z which slice of a 3D texture 593b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param rgba the quad to put the texel/color into 594b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param j which element of the rgba quad to write to 59570eb7996f265f3634dabda078f13d1be3533cc65Brian * 59670eb7996f265f3634dabda078f13d1be3533cc65Brian * XXX maybe move this into sp_tile_cache.c and merge with the 59770eb7996f265f3634dabda078f13d1be3533cc65Brian * sp_get_cached_tile_tex() function. Also, get 4 texels instead of 1... 598b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian */ 599b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic void 600b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianget_texel(struct tgsi_sampler *sampler, 60170eb7996f265f3634dabda078f13d1be3533cc65Brian unsigned face, unsigned level, int x, int y, int z, 602a13de2464dd034ff117f9314df5757d068cae8e5Brian float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j) 603b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian{ 60470eb7996f265f3634dabda078f13d1be3533cc65Brian const int tx = x % TILE_SIZE; 60570eb7996f265f3634dabda078f13d1be3533cc65Brian const int ty = y % TILE_SIZE; 60670eb7996f265f3634dabda078f13d1be3533cc65Brian const struct softpipe_cached_tile *tile 60770eb7996f265f3634dabda078f13d1be3533cc65Brian = sp_get_cached_tile_tex(sampler->pipe, sampler->cache, 60870eb7996f265f3634dabda078f13d1be3533cc65Brian x, y, z, face, level); 60970eb7996f265f3634dabda078f13d1be3533cc65Brian rgba[0][j] = tile->data.color[ty][tx][0]; 61070eb7996f265f3634dabda078f13d1be3533cc65Brian rgba[1][j] = tile->data.color[ty][tx][1]; 61170eb7996f265f3634dabda078f13d1be3533cc65Brian rgba[2][j] = tile->data.color[ty][tx][2]; 61270eb7996f265f3634dabda078f13d1be3533cc65Brian rgba[3][j] = tile->data.color[ty][tx][3]; 613b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian} 614b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 615b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 6163d8c05f7320151898dd224c1daaf3118e1f7ea34Brian/** 6173d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * Compare texcoord 'p' (aka R) against texture value 'rgba[0]' 6183d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * When we sampled the depth texture, the depth value was put into all 6193d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * RGBA channels. We look at the red channel here. 6203d8c05f7320151898dd224c1daaf3118e1f7ea34Brian */ 6213d8c05f7320151898dd224c1daaf3118e1f7ea34Brianstatic INLINE void 6223d8c05f7320151898dd224c1daaf3118e1f7ea34Brianshadow_compare(uint compare_func, 6233d8c05f7320151898dd224c1daaf3118e1f7ea34Brian float rgba[NUM_CHANNELS][QUAD_SIZE], 6243d8c05f7320151898dd224c1daaf3118e1f7ea34Brian const float p[QUAD_SIZE], 6253d8c05f7320151898dd224c1daaf3118e1f7ea34Brian uint j) 6263d8c05f7320151898dd224c1daaf3118e1f7ea34Brian{ 6273d8c05f7320151898dd224c1daaf3118e1f7ea34Brian int k; 6283d8c05f7320151898dd224c1daaf3118e1f7ea34Brian switch (compare_func) { 6293d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_LESS: 6303d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] < rgba[0][j]; 6313d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 6323d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_LEQUAL: 6333d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] <= rgba[0][j]; 6343d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 6353d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_GREATER: 6363d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] > rgba[0][j]; 6373d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 6383d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_GEQUAL: 6393d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] >= rgba[0][j]; 6403d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 6413d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_EQUAL: 6423d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] == rgba[0][j]; 6433d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 6443d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_NOTEQUAL: 6453d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] != rgba[0][j]; 6463d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 6473d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_ALWAYS: 6483d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = 1; 6493d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 6503d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_NEVER: 6513d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = 0; 6523d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 6533d8c05f7320151898dd224c1daaf3118e1f7ea34Brian default: 6543d8c05f7320151898dd224c1daaf3118e1f7ea34Brian assert(0); 6553d8c05f7320151898dd224c1daaf3118e1f7ea34Brian } 6563d8c05f7320151898dd224c1daaf3118e1f7ea34Brian 6573d8c05f7320151898dd224c1daaf3118e1f7ea34Brian rgba[0][j] = rgba[1][j] = rgba[2][j] = (float) k; 6583d8c05f7320151898dd224c1daaf3118e1f7ea34Brian} 6593d8c05f7320151898dd224c1daaf3118e1f7ea34Brian 660b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 661b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/** 662a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Common code for sampling 1D/2D/cube textures. 663a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Could probably extend for 3D... 6640dc4eea64f56cc93e5359372b08b99a2d600273cBrian */ 665e12810d92ffb3547680b227bf88937c03018112bBrianstatic void 666a34b8594b7b2d00404bb639621ec1ce918ba0786Briansp_get_samples_2d_common(struct tgsi_sampler *sampler, 667a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float s[QUAD_SIZE], 668a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float t[QUAD_SIZE], 669a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float p[QUAD_SIZE], 670a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float lodbias, 671a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float rgba[NUM_CHANNELS][QUAD_SIZE], 672a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const unsigned faces[4]) 6730dc4eea64f56cc93e5359372b08b99a2d600273cBrian{ 6743d8c05f7320151898dd224c1daaf3118e1f7ea34Brian const uint compare_func = sampler->state->compare_func; 675f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian unsigned level0, level1, j, imgFilter; 676f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian int width, height; 677c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian float levelBlend; 678a34b8594b7b2d00404bb639621ec1ce918ba0786Brian 679c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian choose_mipmap_levels(sampler, s, t, p, lodbias, 680c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian &level0, &level1, &levelBlend, &imgFilter); 68109a1b912605ff48c8782dcc5aae55ac77e27037bBrian 682b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(sampler->state->normalized_coords); 683b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 684b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian width = sampler->texture->width[level0]; 685b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian height = sampler->texture->height[level0]; 68609a1b912605ff48c8782dcc5aae55ac77e27037bBrian 687b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian assert(width > 0); 688612cfb749c3526eeb446bbc631bf24716522f373Brian 689b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian switch (imgFilter) { 6900dc4eea64f56cc93e5359372b08b99a2d600273cBrian case PIPE_TEX_FILTER_NEAREST: 691b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian for (j = 0; j < QUAD_SIZE; j++) { 692b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian int x = nearest_texcoord(sampler->state->wrap_s, s[j], width); 693b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian int y = nearest_texcoord(sampler->state->wrap_t, t[j], height); 694df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level0, x, y, 0, rgba, j); 6953d8c05f7320151898dd224c1daaf3118e1f7ea34Brian if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { 6963d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, rgba, p, j); 6973d8c05f7320151898dd224c1daaf3118e1f7ea34Brian } 698f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian 699f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian if (level0 != level1) { 700f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian /* get texels from second mipmap level and blend */ 701f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian float rgba2[4][4]; 702f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian unsigned c; 703f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian x = x / 2; 704f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian y = y / 2; 705df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level1, x, y, 0, rgba2, j); 7063d8c05f7320151898dd224c1daaf3118e1f7ea34Brian if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){ 7073d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, rgba2, p, j); 7083d8c05f7320151898dd224c1daaf3118e1f7ea34Brian } 7093d8c05f7320151898dd224c1daaf3118e1f7ea34Brian 710f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian for (c = 0; c < NUM_CHANNELS; c++) { 71117c2f56dc3f2f58ba89d8e305e7d9b423e3cae16Brian rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]); 712f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 713f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 7140dc4eea64f56cc93e5359372b08b99a2d600273cBrian } 7150dc4eea64f56cc93e5359372b08b99a2d600273cBrian break; 7160dc4eea64f56cc93e5359372b08b99a2d600273cBrian case PIPE_TEX_FILTER_LINEAR: 717b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian for (j = 0; j < QUAD_SIZE; j++) { 718b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float tx[4][4], a, b; 719b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian int x0, y0, x1, y1, c; 720b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian linear_texcoord(sampler->state->wrap_s, s[j], width, &x0, &x1, &a); 721b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian linear_texcoord(sampler->state->wrap_t, t[j], height, &y0, &y1, &b); 722df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level0, x0, y0, 0, tx, 0); 723df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level0, x1, y0, 0, tx, 1); 724df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level0, x0, y1, 0, tx, 2); 725df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level0, x1, y1, 0, tx, 3); 7263d8c05f7320151898dd224c1daaf3118e1f7ea34Brian if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { 7273d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, tx, p, 0); 7283d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, tx, p, 1); 7293d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, tx, p, 2); 7303d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, tx, p, 3); 7313d8c05f7320151898dd224c1daaf3118e1f7ea34Brian } 7323d8c05f7320151898dd224c1daaf3118e1f7ea34Brian 733b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian for (c = 0; c < 4; c++) { 734b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian rgba[c][j] = lerp_2d(a, b, tx[c][0], tx[c][1], tx[c][2], tx[c][3]); 735b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian } 736f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian 737f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian if (level0 != level1) { 738f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian /* get texels from second mipmap level and blend */ 739f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian float rgba2[4][4]; 740f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian x0 = x0 / 2; 741f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian y0 = y0 / 2; 742f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian x1 = x1 / 2; 743f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian y1 = y1 / 2; 744df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level1, x0, y0, 0, tx, 0); 745df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level1, x1, y0, 0, tx, 1); 746df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level1, x0, y1, 0, tx, 2); 747df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, faces[j], level1, x1, y1, 0, tx, 3); 7483d8c05f7320151898dd224c1daaf3118e1f7ea34Brian if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){ 7493d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, tx, p, 0); 7503d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, tx, p, 1); 7513d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, tx, p, 2); 7523d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, tx, p, 3); 7533d8c05f7320151898dd224c1daaf3118e1f7ea34Brian } 7543d8c05f7320151898dd224c1daaf3118e1f7ea34Brian 755f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian for (c = 0; c < 4; c++) { 756f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian rgba2[c][j] = lerp_2d(a, b, 757f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian tx[c][0], tx[c][1], tx[c][2], tx[c][3]); 758f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 759f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian 760f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian for (c = 0; c < NUM_CHANNELS; c++) { 761c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]); 762f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 763f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 76409a1b912605ff48c8782dcc5aae55ac77e27037bBrian } 76509a1b912605ff48c8782dcc5aae55ac77e27037bBrian break; 7660dc4eea64f56cc93e5359372b08b99a2d600273cBrian default: 7670dc4eea64f56cc93e5359372b08b99a2d600273cBrian assert(0); 7680dc4eea64f56cc93e5359372b08b99a2d600273cBrian } 7690dc4eea64f56cc93e5359372b08b99a2d600273cBrian} 77034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 77134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 77234a48abd5ff82ce9748fc29191e35a0985d47c5fBrianstatic void 773a34b8594b7b2d00404bb639621ec1ce918ba0786Briansp_get_samples_1d(struct tgsi_sampler *sampler, 774a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float s[QUAD_SIZE], 775a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float t[QUAD_SIZE], 776a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float p[QUAD_SIZE], 777a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float lodbias, 778a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float rgba[NUM_CHANNELS][QUAD_SIZE]) 779a34b8594b7b2d00404bb639621ec1ce918ba0786Brian{ 780a34b8594b7b2d00404bb639621ec1ce918ba0786Brian static const unsigned faces[4] = {0, 0, 0, 0}; 781d16b4bc32a731cb6ae320e8c187af3bc751d4138Brian static const float tzero[4] = {0, 0, 0, 0}; 782d16b4bc32a731cb6ae320e8c187af3bc751d4138Brian sp_get_samples_2d_common(sampler, s, tzero, NULL, lodbias, rgba, faces); 783a34b8594b7b2d00404bb639621ec1ce918ba0786Brian} 784a34b8594b7b2d00404bb639621ec1ce918ba0786Brian 785a34b8594b7b2d00404bb639621ec1ce918ba0786Brian 786a34b8594b7b2d00404bb639621ec1ce918ba0786Brianstatic void 787a34b8594b7b2d00404bb639621ec1ce918ba0786Briansp_get_samples_2d(struct tgsi_sampler *sampler, 788a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float s[QUAD_SIZE], 789a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float t[QUAD_SIZE], 790a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float p[QUAD_SIZE], 791a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float lodbias, 792a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float rgba[NUM_CHANNELS][QUAD_SIZE]) 793a34b8594b7b2d00404bb639621ec1ce918ba0786Brian{ 794a34b8594b7b2d00404bb639621ec1ce918ba0786Brian static const unsigned faces[4] = {0, 0, 0, 0}; 7953d8c05f7320151898dd224c1daaf3118e1f7ea34Brian sp_get_samples_2d_common(sampler, s, t, p, lodbias, rgba, faces); 796a34b8594b7b2d00404bb639621ec1ce918ba0786Brian} 797a34b8594b7b2d00404bb639621ec1ce918ba0786Brian 798a34b8594b7b2d00404bb639621ec1ce918ba0786Brian 799a34b8594b7b2d00404bb639621ec1ce918ba0786Brianstatic void 800b4480285ed5098f1c862690ee105dd46f5e6cd1eBriansp_get_samples_3d(struct tgsi_sampler *sampler, 801b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float s[QUAD_SIZE], 802b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float t[QUAD_SIZE], 803b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float p[QUAD_SIZE], 804f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian float lodbias, 805b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float rgba[NUM_CHANNELS][QUAD_SIZE]) 80634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{ 80734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian /* get/map pipe_surfaces corresponding to 3D tex slices */ 8083d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian unsigned level0, level1, j, imgFilter; 8093d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian int width, height, depth; 8103d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian float levelBlend; 8113d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian const uint face = 0; 8123d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 8133d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian choose_mipmap_levels(sampler, s, t, p, lodbias, 8143d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian &level0, &level1, &levelBlend, &imgFilter); 8153d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 816b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(sampler->state->normalized_coords); 817b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 818b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian width = sampler->texture->width[level0]; 819b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian height = sampler->texture->height[level0]; 820b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian depth = sampler->texture->depth[level0]; 8213d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 8223d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian assert(width > 0); 8233d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian assert(height > 0); 8243d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian assert(depth > 0); 8253d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 8263d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian switch (imgFilter) { 8273d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian case PIPE_TEX_FILTER_NEAREST: 8283d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian for (j = 0; j < QUAD_SIZE; j++) { 8293d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian int x = nearest_texcoord(sampler->state->wrap_s, s[j], width); 8303d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian int y = nearest_texcoord(sampler->state->wrap_t, t[j], height); 8313d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian int z = nearest_texcoord(sampler->state->wrap_r, p[j], depth); 832df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level0, x, y, z, rgba, j); 8333d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 8343d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian if (level0 != level1) { 8353d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian /* get texels from second mipmap level and blend */ 8363d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian float rgba2[4][4]; 8373d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian unsigned c; 8383d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian x /= 2; 8393d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian y /= 2; 8403d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian z /= 2; 841df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level1, x, y, z, rgba2, j); 8423d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian for (c = 0; c < NUM_CHANNELS; c++) { 8433d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian rgba[c][j] = LERP(levelBlend, rgba2[c][j], rgba[c][j]); 8443d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 8453d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 8463d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 8473d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian break; 8483d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian case PIPE_TEX_FILTER_LINEAR: 8493d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian for (j = 0; j < QUAD_SIZE; j++) { 850df4410a59784482fcbd48f82788dd0a9f5a62c15Brian float texel0[4][4], texel1[4][4]; 851df4410a59784482fcbd48f82788dd0a9f5a62c15Brian float xw, yw, zw; /* interpolation weights */ 8523d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian int x0, x1, y0, y1, z0, z1, c; 8533d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian linear_texcoord(sampler->state->wrap_s, s[j], width, &x0, &x1, &xw); 8543d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian linear_texcoord(sampler->state->wrap_t, t[j], height, &y0, &y1, &yw); 8553d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian linear_texcoord(sampler->state->wrap_r, p[j], depth, &z0, &z1, &zw); 856df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level0, x0, y0, z0, texel0, 0); 857df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level0, x1, y0, z0, texel0, 1); 858df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level0, x0, y1, z0, texel0, 2); 859df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level0, x1, y1, z0, texel0, 3); 860df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level0, x0, y0, z1, texel1, 0); 861df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level0, x1, y0, z1, texel1, 1); 862df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level0, x0, y1, z1, texel1, 2); 863df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level0, x1, y1, z1, texel1, 3); 8643d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 8653d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian /* 3D lerp */ 8663d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian for (c = 0; c < 4; c++) { 8673d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian float ctemp0[4][4], ctemp1[4][4]; 8683d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian ctemp0[c][j] = lerp_2d(xw, yw, 8693d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian texel0[c][0], texel0[c][1], 8703d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian texel0[c][2], texel0[c][3]); 8713d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian ctemp1[c][j] = lerp_2d(xw, yw, 8723d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian texel1[c][0], texel1[c][1], 8733d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian texel1[c][2], texel1[c][3]); 8743d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian rgba[c][j] = LERP(zw, ctemp0[c][j], ctemp1[c][j]); 8753d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 8763d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 8773d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian if (level0 != level1) { 8783d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian /* get texels from second mipmap level and blend */ 8793d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian float rgba2[4][4]; 8803d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian x0 /= 2; 8813d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian y0 /= 2; 8823d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian z0 /= 2; 8833d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian x1 /= 2; 8843d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian y1 /= 2; 8853d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian z1 /= 2; 886df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level1, x0, y0, z0, texel0, 0); 887df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level1, x1, y0, z0, texel0, 1); 888df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level1, x0, y1, z0, texel0, 2); 889df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level1, x1, y1, z0, texel0, 3); 890df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level1, x0, y0, z1, texel1, 0); 891df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level1, x1, y0, z1, texel1, 1); 892df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level1, x0, y1, z1, texel1, 2); 893df4410a59784482fcbd48f82788dd0a9f5a62c15Brian get_texel(sampler, face, level1, x1, y1, z1, texel1, 3); 8943d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 8953d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian /* 3D lerp */ 8963d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian for (c = 0; c < 4; c++) { 8973d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian float ctemp0[4][4], ctemp1[4][4]; 8983d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian ctemp0[c][j] = lerp_2d(xw, yw, 8993d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian texel0[c][0], texel0[c][1], 9003d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian texel0[c][2], texel0[c][3]); 9013d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian ctemp1[c][j] = lerp_2d(xw, yw, 9023d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian texel1[c][0], texel1[c][1], 9033d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian texel1[c][2], texel1[c][3]); 9043d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian rgba2[c][j] = LERP(zw, ctemp0[c][j], ctemp1[c][j]); 9053d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 9063d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 9073d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian /* blend mipmap levels */ 9083d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian for (c = 0; c < NUM_CHANNELS; c++) { 9093d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]); 9103d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 9113d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 9123d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 9133d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian break; 9143d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian default: 9153d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian assert(0); 9163d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 91734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian} 91834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 91934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 92034a48abd5ff82ce9748fc29191e35a0985d47c5fBrianstatic void 921b4480285ed5098f1c862690ee105dd46f5e6cd1eBriansp_get_samples_cube(struct tgsi_sampler *sampler, 922b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float s[QUAD_SIZE], 923b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float t[QUAD_SIZE], 924b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float p[QUAD_SIZE], 925f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian float lodbias, 926b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float rgba[NUM_CHANNELS][QUAD_SIZE]) 92734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{ 928a34b8594b7b2d00404bb639621ec1ce918ba0786Brian unsigned faces[QUAD_SIZE], j; 929a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float ssss[4], tttt[4]; 930b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian for (j = 0; j < QUAD_SIZE; j++) { 931a34b8594b7b2d00404bb639621ec1ce918ba0786Brian faces[j] = choose_cube_face(s[j], t[j], p[j], ssss + j, tttt + j); 932b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian } 933a34b8594b7b2d00404bb639621ec1ce918ba0786Brian sp_get_samples_2d_common(sampler, ssss, tttt, NULL, lodbias, rgba, faces); 93434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian} 93534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 93634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 937b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrianstatic void 938b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBriansp_get_samples_rect(struct tgsi_sampler *sampler, 939b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian const float s[QUAD_SIZE], 940b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian const float t[QUAD_SIZE], 941b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian const float p[QUAD_SIZE], 942b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian float lodbias, 943b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian float rgba[NUM_CHANNELS][QUAD_SIZE]) 944b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{ 945b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian //sp_get_samples_2d_common(sampler, s, t, p, lodbias, rgba, faces); 946b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian static const uint face = 0; 947b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian const uint compare_func = sampler->state->compare_func; 948b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian unsigned level0, level1, j, imgFilter; 949b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian int width, height; 950b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian float levelBlend; 951b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 952b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian choose_mipmap_levels(sampler, s, t, p, lodbias, 953b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian &level0, &level1, &levelBlend, &imgFilter); 954b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 955b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian /* texture RECTS cannot be mipmapped */ 956b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(level0 == level1); 957b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 958b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian width = sampler->texture->width[level0]; 959b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian height = sampler->texture->height[level0]; 960b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 961b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(width > 0); 962b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 963b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian switch (imgFilter) { 964b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_FILTER_NEAREST: 965b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian for (j = 0; j < QUAD_SIZE; j++) { 966b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian int x = nearest_texcoord_unnorm(sampler->state->wrap_s, s[j], width); 967b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian int y = nearest_texcoord_unnorm(sampler->state->wrap_t, t[j], height); 968b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian get_texel(sampler, face, level0, x, y, 0, rgba, j); 969b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { 970b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian shadow_compare(compare_func, rgba, p, j); 971b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 972b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 973b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian break; 974b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_FILTER_LINEAR: 975b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian for (j = 0; j < QUAD_SIZE; j++) { 976b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian float tx[4][4], a, b; 977b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian int x0, y0, x1, y1, c; 978b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian linear_texcoord_unnorm(sampler->state->wrap_s, s[j], width, &x0, &x1, &a); 979b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian linear_texcoord_unnorm(sampler->state->wrap_t, t[j], height, &y0, &y1, &b); 980b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian get_texel(sampler, face, level0, x0, y0, 0, tx, 0); 981b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian get_texel(sampler, face, level0, x1, y0, 0, tx, 1); 982b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian get_texel(sampler, face, level0, x0, y1, 0, tx, 2); 983b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian get_texel(sampler, face, level0, x1, y1, 0, tx, 3); 984b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { 985b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian shadow_compare(compare_func, tx, p, 0); 986b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian shadow_compare(compare_func, tx, p, 1); 987b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian shadow_compare(compare_func, tx, p, 2); 988b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian shadow_compare(compare_func, tx, p, 3); 989b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 990b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 991b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian for (c = 0; c < 4; c++) { 992b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian rgba[c][j] = lerp_2d(a, b, tx[c][0], tx[c][1], tx[c][2], tx[c][3]); 993b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 994b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 995b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian break; 996b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian default: 997b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(0); 998b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 999b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian} 1000b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 1001b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 1002b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 1003b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 1004a34b8594b7b2d00404bb639621ec1ce918ba0786Brian/** 1005a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Called via tgsi_sampler::get_samples() 1006a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Use the sampler's state setting to get a filtered RGBA value 1007753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * from the sampler's texture. 1008a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * 1009a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * XXX we can implement many versions of this function, each 1010a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * tightly coded for a specific combination of sampler state 1011a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * (nearest + repeat), (bilinear mipmap + clamp), etc. 1012a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * 1013a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * The update_samplers() function in st_atom_sampler.c could create 1014a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * a new tgsi_sampler object for each state combo it finds.... 1015a34b8594b7b2d00404bb639621ec1ce918ba0786Brian */ 101634a48abd5ff82ce9748fc29191e35a0985d47c5fBrianvoid 1017b4480285ed5098f1c862690ee105dd46f5e6cd1eBriansp_get_samples(struct tgsi_sampler *sampler, 1018b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float s[QUAD_SIZE], 1019b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float t[QUAD_SIZE], 1020b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float p[QUAD_SIZE], 1021f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian float lodbias, 1022b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float rgba[NUM_CHANNELS][QUAD_SIZE]) 102334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{ 10244f23468bd0d14b8ed687a641003d587b91ad39a7Brian if (!sampler->texture) 10254f23468bd0d14b8ed687a641003d587b91ad39a7Brian return; 10264f23468bd0d14b8ed687a641003d587b91ad39a7Brian 102734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian switch (sampler->texture->target) { 102870af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell case PIPE_TEXTURE_1D: 1029b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(sampler->state->normalized_coords); 1030f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian sp_get_samples_1d(sampler, s, t, p, lodbias, rgba); 103134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian break; 103270af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell case PIPE_TEXTURE_2D: 1033b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian if (sampler->state->normalized_coords) 1034b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian sp_get_samples_2d(sampler, s, t, p, lodbias, rgba); 1035b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian else 1036b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian sp_get_samples_rect(sampler, s, t, p, lodbias, rgba); 103734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian break; 103870af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell case PIPE_TEXTURE_3D: 1039b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(sampler->state->normalized_coords); 1040f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian sp_get_samples_3d(sampler, s, t, p, lodbias, rgba); 104134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian break; 104270af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell case PIPE_TEXTURE_CUBE: 1043b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(sampler->state->normalized_coords); 1044f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian sp_get_samples_cube(sampler, s, t, p, lodbias, rgba); 104534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian break; 104634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian default: 104734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian assert(0); 104834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 104934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian} 105034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 1051