sp_tex_sample.c revision f911c3b9897b90132c8621a72bfeb824eb3b01e5
10dc4eea64f56cc93e5359372b08b99a2d600273cBrian/************************************************************************** 20dc4eea64f56cc93e5359372b08b99a2d600273cBrian * 30dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 40dc4eea64f56cc93e5359372b08b99a2d600273cBrian * All Rights Reserved. 53ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul * Copyright 2008 VMware, Inc. All rights reserved. 60dc4eea64f56cc93e5359372b08b99a2d600273cBrian * 70dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Permission is hereby granted, free of charge, to any person obtaining a 80dc4eea64f56cc93e5359372b08b99a2d600273cBrian * copy of this software and associated documentation files (the 90dc4eea64f56cc93e5359372b08b99a2d600273cBrian * "Software"), to deal in the Software without restriction, including 100dc4eea64f56cc93e5359372b08b99a2d600273cBrian * without limitation the rights to use, copy, modify, merge, publish, 110dc4eea64f56cc93e5359372b08b99a2d600273cBrian * distribute, sub license, and/or sell copies of the Software, and to 120dc4eea64f56cc93e5359372b08b99a2d600273cBrian * permit persons to whom the Software is furnished to do so, subject to 130dc4eea64f56cc93e5359372b08b99a2d600273cBrian * the following conditions: 140dc4eea64f56cc93e5359372b08b99a2d600273cBrian * 150dc4eea64f56cc93e5359372b08b99a2d600273cBrian * The above copyright notice and this permission notice (including the 160dc4eea64f56cc93e5359372b08b99a2d600273cBrian * next paragraph) shall be included in all copies or substantial portions 170dc4eea64f56cc93e5359372b08b99a2d600273cBrian * of the Software. 180dc4eea64f56cc93e5359372b08b99a2d600273cBrian * 190dc4eea64f56cc93e5359372b08b99a2d600273cBrian * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 200dc4eea64f56cc93e5359372b08b99a2d600273cBrian * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 210dc4eea64f56cc93e5359372b08b99a2d600273cBrian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 220dc4eea64f56cc93e5359372b08b99a2d600273cBrian * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 230dc4eea64f56cc93e5359372b08b99a2d600273cBrian * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 240dc4eea64f56cc93e5359372b08b99a2d600273cBrian * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 250dc4eea64f56cc93e5359372b08b99a2d600273cBrian * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 260dc4eea64f56cc93e5359372b08b99a2d600273cBrian * 270dc4eea64f56cc93e5359372b08b99a2d600273cBrian **************************************************************************/ 280dc4eea64f56cc93e5359372b08b99a2d600273cBrian 290dc4eea64f56cc93e5359372b08b99a2d600273cBrian/** 300dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Texture sampling 310dc4eea64f56cc93e5359372b08b99a2d600273cBrian * 320dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Authors: 330dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Brian Paul 340dc4eea64f56cc93e5359372b08b99a2d600273cBrian */ 350dc4eea64f56cc93e5359372b08b99a2d600273cBrian 3608f33a025100dea2d951e6d628891fe294b18082Brian#include "sp_context.h" 377925274da323d5a896b557181d4016e0391f026fBrian#include "sp_quad.h" 380dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "sp_surface.h" 390b9e96fae9493d5d58f046e01c983a3c4267090eBrian#include "sp_texture.h" 400dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "sp_tex_sample.h" 4170eb7996f265f3634dabda078f13d1be3533cc65Brian#include "sp_tile_cache.h" 420dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "pipe/p_context.h" 430dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "pipe/p_defines.h" 441a46dcc8a927dfb38ca1381e7b3dafb789f8257cBrian Paul#include "util/u_math.h" 454f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h" 460dc4eea64f56cc93e5359372b08b99a2d600273cBrian 470dc4eea64f56cc93e5359372b08b99a2d600273cBrian 483ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul 4908f33a025100dea2d951e6d628891fe294b18082Brian/* 5008f33a025100dea2d951e6d628891fe294b18082Brian * Note, the FRAC macro has to work perfectly. Otherwise you'll sometimes 5108f33a025100dea2d951e6d628891fe294b18082Brian * see 1-pixel bands of improperly weighted linear-filtered textures. 5208f33a025100dea2d951e6d628891fe294b18082Brian * The tests/texwrap.c demo is a good test. 5308f33a025100dea2d951e6d628891fe294b18082Brian * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0. 5408f33a025100dea2d951e6d628891fe294b18082Brian * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x). 5508f33a025100dea2d951e6d628891fe294b18082Brian */ 569935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul#define FRAC(f) ((f) - util_ifloor(f)) 5708f33a025100dea2d951e6d628891fe294b18082Brian 5808f33a025100dea2d951e6d628891fe294b18082Brian 5908f33a025100dea2d951e6d628891fe294b18082Brian/** 6008f33a025100dea2d951e6d628891fe294b18082Brian * Linear interpolation macro 6108f33a025100dea2d951e6d628891fe294b18082Brian */ 6238bee46e83b18ff4ad42d340b507b1a15b4326c7Brianstatic INLINE float 6338bee46e83b18ff4ad42d340b507b1a15b4326c7Brianlerp(float a, float v0, float v1) 6438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian{ 6538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian return v0 + a * (v1 - v0); 6638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian} 670dc4eea64f56cc93e5359372b08b99a2d600273cBrian 680dc4eea64f56cc93e5359372b08b99a2d600273cBrian 690dc4eea64f56cc93e5359372b08b99a2d600273cBrian/** 700dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Do 2D/biliner interpolation of float values. 710dc4eea64f56cc93e5359372b08b99a2d600273cBrian * v00, v10, v01 and v11 are typically four texture samples in a square/box. 720dc4eea64f56cc93e5359372b08b99a2d600273cBrian * a and b are the horizontal and vertical interpolants. 730dc4eea64f56cc93e5359372b08b99a2d600273cBrian * It's important that this function is inlined when compiled with 740dc4eea64f56cc93e5359372b08b99a2d600273cBrian * optimization! If we find that's not true on some systems, convert 750dc4eea64f56cc93e5359372b08b99a2d600273cBrian * to a macro. 760dc4eea64f56cc93e5359372b08b99a2d600273cBrian */ 77b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic INLINE float 78b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianlerp_2d(float a, float b, 79b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float v00, float v10, float v01, float v11) 800dc4eea64f56cc93e5359372b08b99a2d600273cBrian{ 8138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian const float temp0 = lerp(a, v00, v10); 8238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian const float temp1 = lerp(a, v01, v11); 8338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian return lerp(b, temp0, temp1); 8438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian} 8538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian 8638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian 8738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian/** 8838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * As above, but 3D interpolation of 8 values. 8938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian */ 9038bee46e83b18ff4ad42d340b507b1a15b4326c7Brianstatic INLINE float 9138bee46e83b18ff4ad42d340b507b1a15b4326c7Brianlerp_3d(float a, float b, float c, 9238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float v000, float v100, float v010, float v110, 9338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float v001, float v101, float v011, float v111) 9438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian{ 9538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian const float temp0 = lerp_2d(a, b, v000, v100, v010, v110); 9638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian const float temp1 = lerp_2d(a, b, v001, v101, v011, v111); 9738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian return lerp(c, temp0, temp1); 980dc4eea64f56cc93e5359372b08b99a2d600273cBrian} 990dc4eea64f56cc93e5359372b08b99a2d600273cBrian 1000dc4eea64f56cc93e5359372b08b99a2d600273cBrian 10138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian 1020dc4eea64f56cc93e5359372b08b99a2d600273cBrian/** 103906768316d9521a32d9a7eebc9edaf76c06a98a7Brian * If A is a signed integer, A % B doesn't give the right value for A < 0 104906768316d9521a32d9a7eebc9edaf76c06a98a7Brian * (in terms of texture repeat). Just casting to unsigned fixes that. 1050dc4eea64f56cc93e5359372b08b99a2d600273cBrian */ 106906768316d9521a32d9a7eebc9edaf76c06a98a7Brian#define REMAINDER(A, B) ((unsigned) (A) % (unsigned) (B)) 10708f33a025100dea2d951e6d628891fe294b18082Brian 10808f33a025100dea2d951e6d628891fe294b18082Brian 10908f33a025100dea2d951e6d628891fe294b18082Brian/** 11038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * Apply texture coord wrapping mode and return integer texture indexes 11138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * for a vector of four texcoords (S or T or P). 11208f33a025100dea2d951e6d628891fe294b18082Brian * \param wrapMode PIPE_TEX_WRAP_x 11338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param s the incoming texcoords 11408f33a025100dea2d951e6d628891fe294b18082Brian * \param size the texture image size 11538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param icoord returns the integer texcoords 11608f33a025100dea2d951e6d628891fe294b18082Brian * \return integer texture index 11708f33a025100dea2d951e6d628891fe294b18082Brian */ 11838bee46e83b18ff4ad42d340b507b1a15b4326c7Brianstatic INLINE void 11938bee46e83b18ff4ad42d340b507b1a15b4326c7Briannearest_texcoord_4(unsigned wrapMode, const float s[4], unsigned size, 12038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int icoord[4]) 1210dc4eea64f56cc93e5359372b08b99a2d600273cBrian{ 12238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian uint ch; 1230dc4eea64f56cc93e5359372b08b99a2d600273cBrian switch (wrapMode) { 1240dc4eea64f56cc93e5359372b08b99a2d600273cBrian case PIPE_TEX_WRAP_REPEAT: 12508f33a025100dea2d951e6d628891fe294b18082Brian /* s limited to [0,1) */ 12608f33a025100dea2d951e6d628891fe294b18082Brian /* i limited to [0,size-1] */ 12738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 12838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int i = util_ifloor(s[ch] * size); 12938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = REMAINDER(i, size); 13038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 13138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian return; 1320dc4eea64f56cc93e5359372b08b99a2d600273cBrian case PIPE_TEX_WRAP_CLAMP: 13308f33a025100dea2d951e6d628891fe294b18082Brian /* s limited to [0,1] */ 13408f33a025100dea2d951e6d628891fe294b18082Brian /* i limited to [0,size-1] */ 13538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 13638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (s[ch] <= 0.0F) 13738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = 0; 13838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else if (s[ch] >= 1.0F) 13938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = size - 1; 14038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else 14138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = util_ifloor(s[ch] * size); 14238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 14338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian return; 14408f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 14508f33a025100dea2d951e6d628891fe294b18082Brian { 14608f33a025100dea2d951e6d628891fe294b18082Brian /* s limited to [min,max] */ 14708f33a025100dea2d951e6d628891fe294b18082Brian /* i limited to [0, size-1] */ 148b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float min = 1.0F / (2.0F * size); 149b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float max = 1.0F - min; 15038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 15138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (s[ch] < min) 15238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = 0; 15338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else if (s[ch] > max) 15438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = size - 1; 15538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else 15638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = util_ifloor(s[ch] * size); 15738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 15808f33a025100dea2d951e6d628891fe294b18082Brian } 15938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian return; 16008f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 16108f33a025100dea2d951e6d628891fe294b18082Brian { 16208f33a025100dea2d951e6d628891fe294b18082Brian /* s limited to [min,max] */ 16308f33a025100dea2d951e6d628891fe294b18082Brian /* i limited to [-1, size] */ 164b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float min = -1.0F / (2.0F * size); 165b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float max = 1.0F - min; 16638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 16738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (s[ch] <= min) 16838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = -1; 16938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else if (s[ch] >= max) 17038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = size; 17138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else 17238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = util_ifloor(s[ch] * size); 17338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 17408f33a025100dea2d951e6d628891fe294b18082Brian } 17538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian return; 17608f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_REPEAT: 17708f33a025100dea2d951e6d628891fe294b18082Brian { 178b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float min = 1.0F / (2.0F * size); 179b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float max = 1.0F - min; 18038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 18138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian const int flr = util_ifloor(s[ch]); 18238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float u; 18338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (flr & 1) 18438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u = 1.0F - (s[ch] - (float) flr); 18538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else 18638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u = s[ch] - (float) flr; 18738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (u < min) 18838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = 0; 18938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else if (u > max) 19038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = size - 1; 19138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else 19238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = util_ifloor(u * size); 19338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 19408f33a025100dea2d951e6d628891fe294b18082Brian } 19538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian return; 19608f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_CLAMP: 19738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 19808f33a025100dea2d951e6d628891fe294b18082Brian /* s limited to [0,1] */ 19908f33a025100dea2d951e6d628891fe294b18082Brian /* i limited to [0,size-1] */ 20038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian const float u = fabsf(s[ch]); 20108f33a025100dea2d951e6d628891fe294b18082Brian if (u <= 0.0F) 20238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = 0; 20308f33a025100dea2d951e6d628891fe294b18082Brian else if (u >= 1.0F) 20438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = size - 1; 20508f33a025100dea2d951e6d628891fe294b18082Brian else 20638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = util_ifloor(u * size); 20708f33a025100dea2d951e6d628891fe294b18082Brian } 20838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian return; 20908f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: 21008f33a025100dea2d951e6d628891fe294b18082Brian { 21108f33a025100dea2d951e6d628891fe294b18082Brian /* s limited to [min,max] */ 21208f33a025100dea2d951e6d628891fe294b18082Brian /* i limited to [0, size-1] */ 213b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float min = 1.0F / (2.0F * size); 214b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float max = 1.0F - min; 21538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 21638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian const float u = fabsf(s[ch]); 21738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (u < min) 21838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = 0; 21938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else if (u > max) 22038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = size - 1; 22138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else 22238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = util_ifloor(u * size); 22338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 22408f33a025100dea2d951e6d628891fe294b18082Brian } 22538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian return; 22608f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: 22708f33a025100dea2d951e6d628891fe294b18082Brian { 22808f33a025100dea2d951e6d628891fe294b18082Brian /* s limited to [min,max] */ 22908f33a025100dea2d951e6d628891fe294b18082Brian /* i limited to [0, size-1] */ 230b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float min = -1.0F / (2.0F * size); 231b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float max = 1.0F - min; 23238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 23338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian const float u = fabsf(s[ch]); 23438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (u < min) 23538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = -1; 23638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else if (u > max) 23738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = size; 23838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else 23938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = util_ifloor(u * size); 24038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 24108f33a025100dea2d951e6d628891fe294b18082Brian } 24238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian return; 2430dc4eea64f56cc93e5359372b08b99a2d600273cBrian default: 2440dc4eea64f56cc93e5359372b08b99a2d600273cBrian assert(0); 2450dc4eea64f56cc93e5359372b08b99a2d600273cBrian } 2460dc4eea64f56cc93e5359372b08b99a2d600273cBrian} 2470dc4eea64f56cc93e5359372b08b99a2d600273cBrian 24808f33a025100dea2d951e6d628891fe294b18082Brian 24908f33a025100dea2d951e6d628891fe294b18082Brian/** 25038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * Used to compute texel locations for linear sampling for four texcoords. 25108f33a025100dea2d951e6d628891fe294b18082Brian * \param wrapMode PIPE_TEX_WRAP_x 25238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param s the texcoords 25308f33a025100dea2d951e6d628891fe294b18082Brian * \param size the texture image size 25438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param icoord0 returns first texture indexes 25538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param icoord1 returns second texture indexes (usually icoord0 + 1) 25638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param w returns blend factor/weight between texture indexes 25738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param icoord returns the computed integer texture coords 25808f33a025100dea2d951e6d628891fe294b18082Brian */ 2590dc4eea64f56cc93e5359372b08b99a2d600273cBrianstatic INLINE void 26038bee46e83b18ff4ad42d340b507b1a15b4326c7Brianlinear_texcoord_4(unsigned wrapMode, const float s[4], unsigned size, 26138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int icoord0[4], int icoord1[4], float w[4]) 2620dc4eea64f56cc93e5359372b08b99a2d600273cBrian{ 26338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian uint ch; 26438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian 2650dc4eea64f56cc93e5359372b08b99a2d600273cBrian switch (wrapMode) { 2660dc4eea64f56cc93e5359372b08b99a2d600273cBrian case PIPE_TEX_WRAP_REPEAT: 26738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 26838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float u = s[ch] * size - 0.5F; 26938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord0[ch] = REMAINDER(util_ifloor(u), size); 27038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord1[ch] = REMAINDER(icoord0[ch] + 1, size); 27138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian w[ch] = FRAC(u); 27238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 27338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian break;; 2740dc4eea64f56cc93e5359372b08b99a2d600273cBrian case PIPE_TEX_WRAP_CLAMP: 27538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 27638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float u = CLAMP(s[ch], 0.0F, 1.0F); 27738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u = u * size - 0.5f; 27838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord0[ch] = util_ifloor(u); 27938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord1[ch] = icoord0[ch] + 1; 28038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian w[ch] = FRAC(u); 28138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 28238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian break;; 28308f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 28438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 28538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float u = CLAMP(s[ch], 0.0F, 1.0F); 28638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u = u * size - 0.5f; 28738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord0[ch] = util_ifloor(u); 28838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord1[ch] = icoord0[ch] + 1; 28938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (icoord0[ch] < 0) 29038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord0[ch] = 0; 29138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (icoord1[ch] >= (int) size) 29238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord1[ch] = size - 1; 29338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian w[ch] = FRAC(u); 29438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 29538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian break;; 29608f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 29708f33a025100dea2d951e6d628891fe294b18082Brian { 298b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float min = -1.0F / (2.0F * size); 299b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float max = 1.0F - min; 30038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 30138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float u = CLAMP(s[ch], min, max); 30238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u = u * size - 0.5f; 30338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord0[ch] = util_ifloor(u); 30438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord1[ch] = icoord0[ch] + 1; 30538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian w[ch] = FRAC(u); 30638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 30708f33a025100dea2d951e6d628891fe294b18082Brian } 30838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian break;; 30908f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_REPEAT: 31038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 31138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian const int flr = util_ifloor(s[ch]); 31238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float u; 31308f33a025100dea2d951e6d628891fe294b18082Brian if (flr & 1) 31438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u = 1.0F - (s[ch] - (float) flr); 31508f33a025100dea2d951e6d628891fe294b18082Brian else 31638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u = s[ch] - (float) flr; 31738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u = u * size - 0.5F; 31838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord0[ch] = util_ifloor(u); 31938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord1[ch] = icoord0[ch] + 1; 32038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (icoord0[ch] < 0) 32138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord0[ch] = 0; 32238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (icoord1[ch] >= (int) size) 32338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord1[ch] = size - 1; 32438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian w[ch] = FRAC(u); 32508f33a025100dea2d951e6d628891fe294b18082Brian } 32638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian break;; 32708f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_CLAMP: 32838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 32938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float u = fabsf(s[ch]); 33038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (u >= 1.0F) 33138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u = (float) size; 33238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else 33338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u *= size; 33438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u -= 0.5F; 33538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord0[ch] = util_ifloor(u); 33638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord1[ch] = icoord0[ch] + 1; 33738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian w[ch] = FRAC(u); 33838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 33938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian break;; 34008f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: 34138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 34238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float u = fabsf(s[ch]); 34338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (u >= 1.0F) 34438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u = (float) size; 34538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else 34638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u *= size; 34738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u -= 0.5F; 34838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord0[ch] = util_ifloor(u); 34938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord1[ch] = icoord0[ch] + 1; 35038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (icoord0[ch] < 0) 35138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord0[ch] = 0; 35238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (icoord1[ch] >= (int) size) 35338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord1[ch] = size - 1; 35438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian w[ch] = FRAC(u); 35538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 35638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian break;; 35708f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: 35808f33a025100dea2d951e6d628891fe294b18082Brian { 359b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float min = -1.0F / (2.0F * size); 360b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float max = 1.0F - min; 36138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 36238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float u = fabsf(s[ch]); 36338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (u <= min) 36438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u = min * size; 36538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else if (u >= max) 36638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u = max * size; 36738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else 36838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u *= size; 36938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u -= 0.5F; 37038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord0[ch] = util_ifloor(u); 37138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord1[ch] = icoord0[ch] + 1; 37238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian w[ch] = FRAC(u); 37338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 37408f33a025100dea2d951e6d628891fe294b18082Brian } 37538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian break;; 3760dc4eea64f56cc93e5359372b08b99a2d600273cBrian default: 3770dc4eea64f56cc93e5359372b08b99a2d600273cBrian assert(0); 3780dc4eea64f56cc93e5359372b08b99a2d600273cBrian } 3790dc4eea64f56cc93e5359372b08b99a2d600273cBrian} 3800dc4eea64f56cc93e5359372b08b99a2d600273cBrian 3810dc4eea64f56cc93e5359372b08b99a2d600273cBrian 382b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian/** 383b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * For RECT textures / unnormalized texcoords 384b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * Only a subset of wrap modes supported. 385b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian */ 38638bee46e83b18ff4ad42d340b507b1a15b4326c7Brianstatic INLINE void 38738bee46e83b18ff4ad42d340b507b1a15b4326c7Briannearest_texcoord_unnorm_4(unsigned wrapMode, const float s[4], unsigned size, 38838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int icoord[4]) 389b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{ 39038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian uint ch; 391b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian switch (wrapMode) { 392b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_WRAP_CLAMP: 39338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 39438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int i = util_ifloor(s[ch]); 39538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch]= CLAMP(i, 0, (int) size-1); 39638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 39738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian return; 398b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 399b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian /* fall-through */ 400b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 40138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 40238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch]= util_ifloor( CLAMP(s[ch], 0.5F, (float) size - 0.5F) ); 40338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 40438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian return; 405b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian default: 406b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(0); 407b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 408b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian} 409b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 410b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 411b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian/** 412b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * For RECT textures / unnormalized texcoords. 413b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * Only a subset of wrap modes supported. 414b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian */ 415b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrianstatic INLINE void 41638bee46e83b18ff4ad42d340b507b1a15b4326c7Brianlinear_texcoord_unnorm_4(unsigned wrapMode, const float s[4], unsigned size, 41738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int icoord0[4], int icoord1[4], float w[4]) 418b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{ 41938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian uint ch; 420b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian switch (wrapMode) { 421b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_WRAP_CLAMP: 42238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 42338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian /* Not exactly what the spec says, but it matches NVIDIA output */ 42438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float u = CLAMP(s[ch] - 0.5F, 0.0f, (float) size - 1.0f); 42538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord0[ch] = util_ifloor(u); 42638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord1[ch] = icoord0[ch] + 1; 42738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian w[ch] = FRAC(u); 42838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 42938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian return; 430b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 431b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian /* fall-through */ 432b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 43338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 43438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float u = CLAMP(s[ch], 0.5F, (float) size - 0.5F); 43538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u -= 0.5F; 43638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord0[ch] = util_ifloor(u); 43738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord1[ch] = icoord0[ch] + 1; 43838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (icoord1[ch] > (int) size - 1) 43938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord1[ch] = size - 1; 44038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian w[ch] = FRAC(u); 44138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 442b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian break; 443b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian default: 444b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(0); 445b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 446b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian} 447b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 448b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 44970af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwellstatic unsigned 450a34b8594b7b2d00404bb639621ec1ce918ba0786Brianchoose_cube_face(float rx, float ry, float rz, float *newS, float *newT) 45134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{ 45234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian /* 45334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian major axis 45434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian direction target sc tc ma 45534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ---------- ------------------------------- --- --- --- 45634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian +rx TEXTURE_CUBE_MAP_POSITIVE_X_EXT -rz -ry rx 45734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian -rx TEXTURE_CUBE_MAP_NEGATIVE_X_EXT +rz -ry rx 45834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian +ry TEXTURE_CUBE_MAP_POSITIVE_Y_EXT +rx +rz ry 45934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian -ry TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT +rx -rz ry 46034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian +rz TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz 46134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian -rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz 46234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian */ 4639935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz); 46470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell unsigned face; 465b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float sc, tc, ma; 46634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 46734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian if (arx > ary && arx > arz) { 46834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian if (rx >= 0.0F) { 46934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_POS_X; 47034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = -rz; 47134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = -ry; 47234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = arx; 47334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 47434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian else { 47534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_NEG_X; 47634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = rz; 47734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = -ry; 47834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = arx; 47934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 48034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 48134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian else if (ary > arx && ary > arz) { 48234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian if (ry >= 0.0F) { 48334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_POS_Y; 48434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = rx; 48534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = rz; 48634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = ary; 48734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 48834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian else { 48934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_NEG_Y; 49034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = rx; 49134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = -rz; 49234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = ary; 49334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 49434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 49534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian else { 49634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian if (rz > 0.0F) { 49734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_POS_Z; 49834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = rx; 49934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = -ry; 50034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = arz; 50134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 50234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian else { 50334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_NEG_Z; 50434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = -rx; 50534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = -ry; 50634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = arz; 50734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 50834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 50934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 510a34b8594b7b2d00404bb639621ec1ce918ba0786Brian *newS = ( sc / ma + 1.0F ) * 0.5F; 511a34b8594b7b2d00404bb639621ec1ce918ba0786Brian *newT = ( tc / ma + 1.0F ) * 0.5F; 51234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 51334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian return face; 51434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian} 51534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 51634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 517b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/** 518b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * Examine the quad's texture coordinates to compute the partial 519b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * derivatives w.r.t X and Y, then compute lambda (level of detail). 520b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * 521b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * This is only done for fragment shaders, not vertex shaders. 522b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian */ 523b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic float 5240b9e96fae9493d5d58f046e01c983a3c4267090eBriancompute_lambda(const struct pipe_texture *tex, 5250b9e96fae9493d5d58f046e01c983a3c4267090eBrian const struct pipe_sampler_state *sampler, 526b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float s[QUAD_SIZE], 527b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float t[QUAD_SIZE], 528f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian const float p[QUAD_SIZE], 529f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian float lodbias) 530b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian{ 531b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float rho, lambda; 532b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 5330b9e96fae9493d5d58f046e01c983a3c4267090eBrian assert(sampler->normalized_coords); 534b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 535b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian assert(s); 536b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian { 537b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dsdx = s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]; 538b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dsdy = s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]; 5399935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul dsdx = fabsf(dsdx); 5409935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul dsdy = fabsf(dsdy); 5410b9e96fae9493d5d58f046e01c983a3c4267090eBrian rho = MAX2(dsdx, dsdy) * tex->width[0]; 542b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian } 543b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian if (t) { 544b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]; 545b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dtdy = t[QUAD_TOP_LEFT] - t[QUAD_BOTTOM_LEFT]; 546b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float max; 5479935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul dtdx = fabsf(dtdx); 5489935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul dtdy = fabsf(dtdy); 5490b9e96fae9493d5d58f046e01c983a3c4267090eBrian max = MAX2(dtdx, dtdy) * tex->height[0]; 550b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian rho = MAX2(rho, max); 551b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian } 552b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian if (p) { 553b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dpdx = p[QUAD_BOTTOM_RIGHT] - p[QUAD_BOTTOM_LEFT]; 554b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dpdy = p[QUAD_TOP_LEFT] - p[QUAD_BOTTOM_LEFT]; 555b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float max; 5569935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul dpdx = fabsf(dpdx); 5579935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul dpdy = fabsf(dpdy); 5580b9e96fae9493d5d58f046e01c983a3c4267090eBrian max = MAX2(dpdx, dpdy) * tex->depth[0]; 559b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian rho = MAX2(rho, max); 560b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian } 561b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 5621a46dcc8a927dfb38ca1381e7b3dafb789f8257cBrian Paul lambda = util_fast_log2(rho); 5630b9e96fae9493d5d58f046e01c983a3c4267090eBrian lambda += lodbias + sampler->lod_bias; 5640b9e96fae9493d5d58f046e01c983a3c4267090eBrian lambda = CLAMP(lambda, sampler->min_lod, sampler->max_lod); 565b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 566b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian return lambda; 567b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian} 568b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 569b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 570f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian/** 571c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * Do several things here: 572c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 1. Compute lambda from the texcoords, if needed 573c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 2. Determine if we're minifying or magnifying 574c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 3. If minifying, choose mipmap levels 575c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 4. Return image filter to use within mipmap images 576dd55083ac1c13723dba6be71f161e2ca7cac7c66Brian * \param level0 Returns first mipmap level to sample from 577dd55083ac1c13723dba6be71f161e2ca7cac7c66Brian * \param level1 Returns second mipmap level to sample from 578dd55083ac1c13723dba6be71f161e2ca7cac7c66Brian * \param levelBlend Returns blend factor between levels, in [0,1] 579dd55083ac1c13723dba6be71f161e2ca7cac7c66Brian * \param imgFilter Returns either the min or mag filter, depending on lambda 580f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian */ 581f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrianstatic void 5820b9e96fae9493d5d58f046e01c983a3c4267090eBrianchoose_mipmap_levels(const struct pipe_texture *texture, 5830b9e96fae9493d5d58f046e01c983a3c4267090eBrian const struct pipe_sampler_state *sampler, 584c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian const float s[QUAD_SIZE], 585c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian const float t[QUAD_SIZE], 586c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian const float p[QUAD_SIZE], 5873ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul boolean computeLambda, 588c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian float lodbias, 589c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian unsigned *level0, unsigned *level1, float *levelBlend, 590c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian unsigned *imgFilter) 59109a1b912605ff48c8782dcc5aae55ac77e27037bBrian{ 5920b9e96fae9493d5d58f046e01c983a3c4267090eBrian if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) { 593c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* no mipmap selection needed */ 5940b9e96fae9493d5d58f046e01c983a3c4267090eBrian *level0 = *level1 = CLAMP((int) sampler->min_lod, 5950b9e96fae9493d5d58f046e01c983a3c4267090eBrian 0, (int) texture->last_level); 59608c9534107fcaf06f9b801551524ed5dc724db13Brian 5970b9e96fae9493d5d58f046e01c983a3c4267090eBrian if (sampler->min_img_filter != sampler->mag_img_filter) { 59808c9534107fcaf06f9b801551524ed5dc724db13Brian /* non-mipmapped texture, but still need to determine if doing 59908c9534107fcaf06f9b801551524ed5dc724db13Brian * minification or magnification. 60008c9534107fcaf06f9b801551524ed5dc724db13Brian */ 6010b9e96fae9493d5d58f046e01c983a3c4267090eBrian float lambda = compute_lambda(texture, sampler, s, t, p, lodbias); 6023b2a291888d8e62787de03f8529806fb562bd186Brian if (lambda <= 0.0) { 6030b9e96fae9493d5d58f046e01c983a3c4267090eBrian *imgFilter = sampler->mag_img_filter; 60408c9534107fcaf06f9b801551524ed5dc724db13Brian } 60508c9534107fcaf06f9b801551524ed5dc724db13Brian else { 6060b9e96fae9493d5d58f046e01c983a3c4267090eBrian *imgFilter = sampler->min_img_filter; 60708c9534107fcaf06f9b801551524ed5dc724db13Brian } 60808c9534107fcaf06f9b801551524ed5dc724db13Brian } 6093b2a291888d8e62787de03f8529806fb562bd186Brian else { 6100b9e96fae9493d5d58f046e01c983a3c4267090eBrian *imgFilter = sampler->mag_img_filter; 6113b2a291888d8e62787de03f8529806fb562bd186Brian } 612c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian } 613c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian else { 614c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian float lambda; 615c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian 6163ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul if (computeLambda) 617c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* fragment shader */ 6180b9e96fae9493d5d58f046e01c983a3c4267090eBrian lambda = compute_lambda(texture, sampler, s, t, p, lodbias); 619c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian else 620c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* vertex shader */ 621c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian lambda = lodbias; /* not really a bias, but absolute LOD */ 622c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian 6233b2a291888d8e62787de03f8529806fb562bd186Brian if (lambda <= 0.0) { /* XXX threshold depends on the filter */ 624c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* magnifying */ 6250b9e96fae9493d5d58f046e01c983a3c4267090eBrian *imgFilter = sampler->mag_img_filter; 6264da1cdf78fa3b954840650fa46cf72da5daf149fBrian *level0 = *level1 = 0; 627f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 628c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian else { 629c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* minifying */ 6300b9e96fae9493d5d58f046e01c983a3c4267090eBrian *imgFilter = sampler->min_img_filter; 631c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian 632c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* choose mipmap level(s) and compute the blend factor between them */ 6330b9e96fae9493d5d58f046e01c983a3c4267090eBrian if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NEAREST) { 634c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* Nearest mipmap level */ 635c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian const int lvl = (int) (lambda + 0.5); 636c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian *level0 = 6370b9e96fae9493d5d58f046e01c983a3c4267090eBrian *level1 = CLAMP(lvl, 0, (int) texture->last_level); 638c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian } 639c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian else { 640c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* Linear interpolation between mipmap levels */ 641c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian const int lvl = (int) lambda; 6420b9e96fae9493d5d58f046e01c983a3c4267090eBrian *level0 = CLAMP(lvl, 0, (int) texture->last_level); 6430b9e96fae9493d5d58f046e01c983a3c4267090eBrian *level1 = CLAMP(lvl + 1, 0, (int) texture->last_level); 644c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian *levelBlend = FRAC(lambda); /* blending weight between levels */ 645c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian } 646f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 64709a1b912605ff48c8782dcc5aae55ac77e27037bBrian } 64809a1b912605ff48c8782dcc5aae55ac77e27037bBrian} 64909a1b912605ff48c8782dcc5aae55ac77e27037bBrian 65008f33a025100dea2d951e6d628891fe294b18082Brian 651b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/** 652a13de2464dd034ff117f9314df5757d068cae8e5Brian * Get a texel from a texture, using the texture tile cache. 653a13de2464dd034ff117f9314df5757d068cae8e5Brian * 654b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param face the cube face in 0..5 655b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param level the mipmap level 656b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param x the x coord of texel within 2D image 657b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param y the y coord of texel within 2D image 65870eb7996f265f3634dabda078f13d1be3533cc65Brian * \param z which slice of a 3D texture 659b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param rgba the quad to put the texel/color into 660b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param j which element of the rgba quad to write to 66170eb7996f265f3634dabda078f13d1be3533cc65Brian * 66270eb7996f265f3634dabda078f13d1be3533cc65Brian * XXX maybe move this into sp_tile_cache.c and merge with the 66370eb7996f265f3634dabda078f13d1be3533cc65Brian * sp_get_cached_tile_tex() function. Also, get 4 texels instead of 1... 664b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian */ 665b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic void 666dd55083ac1c13723dba6be71f161e2ca7cac7c66Brianget_texel(const struct tgsi_sampler *tgsi_sampler, 66770eb7996f265f3634dabda078f13d1be3533cc65Brian unsigned face, unsigned level, int x, int y, int z, 668a13de2464dd034ff117f9314df5757d068cae8e5Brian float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j) 669b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian{ 6700b9e96fae9493d5d58f046e01c983a3c4267090eBrian const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); 671aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell const struct pipe_texture *texture = samp->texture; 672aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell const struct pipe_sampler_state *sampler = samp->sampler; 6730b9e96fae9493d5d58f046e01c983a3c4267090eBrian 6740b9e96fae9493d5d58f046e01c983a3c4267090eBrian if (x < 0 || x >= (int) texture->width[level] || 6750b9e96fae9493d5d58f046e01c983a3c4267090eBrian y < 0 || y >= (int) texture->height[level] || 6760b9e96fae9493d5d58f046e01c983a3c4267090eBrian z < 0 || z >= (int) texture->depth[level]) { 6770b9e96fae9493d5d58f046e01c983a3c4267090eBrian rgba[0][j] = sampler->border_color[0]; 6780b9e96fae9493d5d58f046e01c983a3c4267090eBrian rgba[1][j] = sampler->border_color[1]; 6790b9e96fae9493d5d58f046e01c983a3c4267090eBrian rgba[2][j] = sampler->border_color[2]; 6800b9e96fae9493d5d58f046e01c983a3c4267090eBrian rgba[3][j] = sampler->border_color[3]; 681ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul } 682ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul else { 683f911c3b9897b90132c8621a72bfeb824eb3b01e5Keith Whitwell const unsigned tx = x % TILE_SIZE; 684f911c3b9897b90132c8621a72bfeb824eb3b01e5Keith Whitwell const unsigned ty = y % TILE_SIZE; 685f911c3b9897b90132c8621a72bfeb824eb3b01e5Keith Whitwell const struct softpipe_cached_tile *tile; 686f911c3b9897b90132c8621a72bfeb824eb3b01e5Keith Whitwell 687f911c3b9897b90132c8621a72bfeb824eb3b01e5Keith Whitwell tile = sp_get_cached_tile_tex(samp->cache, 688f911c3b9897b90132c8621a72bfeb824eb3b01e5Keith Whitwell tile_address(x, y, z, face, level)); 689f911c3b9897b90132c8621a72bfeb824eb3b01e5Keith Whitwell 690ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul rgba[0][j] = tile->data.color[ty][tx][0]; 691ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul rgba[1][j] = tile->data.color[ty][tx][1]; 692ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul rgba[2][j] = tile->data.color[ty][tx][2]; 693ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul rgba[3][j] = tile->data.color[ty][tx][3]; 694b1ff7dac537947d412bf423a73e7eacd76f90d84Brian Paul if (0) 695b1ff7dac537947d412bf423a73e7eacd76f90d84Brian Paul { 696ae2195caf56d2eb782475254c68858a25ee7c857Brian Paul debug_printf("Get texel %f %f %f %f from %s\n", 6978fb55dab783f2de5111e7440093e1458fce5fb3dBrian Paul rgba[0][j], rgba[1][j], rgba[2][j], rgba[3][j], 6980b9e96fae9493d5d58f046e01c983a3c4267090eBrian pf_name(texture->format)); 699b1ff7dac537947d412bf423a73e7eacd76f90d84Brian Paul } 700ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul } 701b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian} 702b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 703b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 7043d8c05f7320151898dd224c1daaf3118e1f7ea34Brian/** 7053d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * Compare texcoord 'p' (aka R) against texture value 'rgba[0]' 7063d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * When we sampled the depth texture, the depth value was put into all 7073d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * RGBA channels. We look at the red channel here. 708efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul * \param rgba quad of (depth) texel values 709efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul * \param p texture 'P' components for four pixels in quad 710efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul * \param j which pixel in the quad to test [0..3] 7113d8c05f7320151898dd224c1daaf3118e1f7ea34Brian */ 7123d8c05f7320151898dd224c1daaf3118e1f7ea34Brianstatic INLINE void 713005ee9f4e05b487d455e87c6843d1d1a3c1536ffBrian Paulshadow_compare(const struct pipe_sampler_state *sampler, 7143d8c05f7320151898dd224c1daaf3118e1f7ea34Brian float rgba[NUM_CHANNELS][QUAD_SIZE], 7153d8c05f7320151898dd224c1daaf3118e1f7ea34Brian const float p[QUAD_SIZE], 7163d8c05f7320151898dd224c1daaf3118e1f7ea34Brian uint j) 7173d8c05f7320151898dd224c1daaf3118e1f7ea34Brian{ 7183d8c05f7320151898dd224c1daaf3118e1f7ea34Brian int k; 719005ee9f4e05b487d455e87c6843d1d1a3c1536ffBrian Paul switch (sampler->compare_func) { 7203d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_LESS: 7213d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] < rgba[0][j]; 7223d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 7233d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_LEQUAL: 7243d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] <= rgba[0][j]; 7253d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 7263d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_GREATER: 7273d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] > rgba[0][j]; 7283d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 7293d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_GEQUAL: 7303d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] >= rgba[0][j]; 7313d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 7323d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_EQUAL: 7333d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] == rgba[0][j]; 7343d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 7353d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_NOTEQUAL: 7363d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] != rgba[0][j]; 7373d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 7383d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_ALWAYS: 7393d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = 1; 7403d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 7413d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_NEVER: 7423d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = 0; 7433d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 7443d8c05f7320151898dd224c1daaf3118e1f7ea34Brian default: 745f9b1d47d652778012fd35552ffc51717ac0b6f79Keith Whitwell k = 0; 7463d8c05f7320151898dd224c1daaf3118e1f7ea34Brian assert(0); 747f9b1d47d652778012fd35552ffc51717ac0b6f79Keith Whitwell break; 7483d8c05f7320151898dd224c1daaf3118e1f7ea34Brian } 7493d8c05f7320151898dd224c1daaf3118e1f7ea34Brian 750048765624598e6c60b9fe4dc82a72b7110f16715Brian Paul /* XXX returning result for default GL_DEPTH_TEXTURE_MODE = GL_LUMINANCE */ 7513d8c05f7320151898dd224c1daaf3118e1f7ea34Brian rgba[0][j] = rgba[1][j] = rgba[2][j] = (float) k; 752048765624598e6c60b9fe4dc82a72b7110f16715Brian Paul rgba[3][j] = 1.0F; 7533d8c05f7320151898dd224c1daaf3118e1f7ea34Brian} 7543d8c05f7320151898dd224c1daaf3118e1f7ea34Brian 755b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 756b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/** 757efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul * As above, but do four z/texture comparisons. 758efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul */ 759efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paulstatic INLINE void 760efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paulshadow_compare4(const struct pipe_sampler_state *sampler, 761efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul float rgba[NUM_CHANNELS][QUAD_SIZE], 762efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul const float p[QUAD_SIZE]) 763efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul{ 764efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul int j, k0, k1, k2, k3; 765efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul float val; 766efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul 767efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul /* compare four texcoords vs. four texture samples */ 768efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul switch (sampler->compare_func) { 769efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul case PIPE_FUNC_LESS: 770efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul k0 = p[0] < rgba[0][0]; 771efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul k1 = p[1] < rgba[0][1]; 772efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul k2 = p[2] < rgba[0][2]; 773efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul k3 = p[3] < rgba[0][3]; 774efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul break; 775efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul case PIPE_FUNC_LEQUAL: 776efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul k0 = p[0] <= rgba[0][0]; 777efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul k1 = p[1] <= rgba[0][1]; 778efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul k2 = p[2] <= rgba[0][2]; 779efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul k3 = p[3] <= rgba[0][3]; 780efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul break; 781efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul case PIPE_FUNC_GREATER: 782efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul k0 = p[0] > rgba[0][0]; 783efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul k1 = p[1] > rgba[0][1]; 784efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul k2 = p[2] > rgba[0][2]; 785efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul k3 = p[3] > rgba[0][3]; 786efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul break; 787efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul case PIPE_FUNC_GEQUAL: 788efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul k0 = p[0] >= rgba[0][0]; 789efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul k1 = p[1] >= rgba[0][1]; 790efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul k2 = p[2] >= rgba[0][2]; 791efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul k3 = p[3] >= rgba[0][3]; 792efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul break; 793efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul case PIPE_FUNC_EQUAL: 794efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul k0 = p[0] == rgba[0][0]; 795efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul k1 = p[1] == rgba[0][1]; 796efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul k2 = p[2] == rgba[0][2]; 797efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul k3 = p[3] == rgba[0][3]; 798efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul break; 799efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul case PIPE_FUNC_NOTEQUAL: 800efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul k0 = p[0] != rgba[0][0]; 801efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul k1 = p[1] != rgba[0][1]; 802efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul k2 = p[2] != rgba[0][2]; 803efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul k3 = p[3] != rgba[0][3]; 804efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul break; 805efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul case PIPE_FUNC_ALWAYS: 806efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul k0 = k1 = k2 = k3 = 1; 807efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul break; 808efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul case PIPE_FUNC_NEVER: 809efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul k0 = k1 = k2 = k3 = 0; 810efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul break; 811efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul default: 812efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul k0 = k1 = k2 = k3 = 0; 813efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul assert(0); 814efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul break; 815efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul } 816efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul 817efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul /* convert four pass/fail values to an intensity in [0,1] */ 818efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul val = 0.25F * (k0 + k1 + k2 + k3); 819efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul 820efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul /* XXX returning result for default GL_DEPTH_TEXTURE_MODE = GL_LUMINANCE */ 821efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul for (j = 0; j < 4; j++) { 822efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul rgba[0][j] = rgba[1][j] = rgba[2][j] = val; 823efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul rgba[3][j] = 1.0F; 824efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul } 825efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul} 826efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul 827efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul 828efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul/** 829a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Common code for sampling 1D/2D/cube textures. 830a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Could probably extend for 3D... 8310dc4eea64f56cc93e5359372b08b99a2d600273cBrian */ 832e12810d92ffb3547680b227bf88937c03018112bBrianstatic void 833dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler, 834a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float s[QUAD_SIZE], 835a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float t[QUAD_SIZE], 836a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float p[QUAD_SIZE], 8373ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul boolean computeLambda, 838a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float lodbias, 839a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float rgba[NUM_CHANNELS][QUAD_SIZE], 840a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const unsigned faces[4]) 8410dc4eea64f56cc93e5359372b08b99a2d600273cBrian{ 8420b9e96fae9493d5d58f046e01c983a3c4267090eBrian const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); 843aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell const struct pipe_texture *texture = samp->texture; 844aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell const struct pipe_sampler_state *sampler = samp->sampler; 845f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian unsigned level0, level1, j, imgFilter; 846f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian int width, height; 847c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian float levelBlend; 848a34b8594b7b2d00404bb639621ec1ce918ba0786Brian 8493ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias, 850c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian &level0, &level1, &levelBlend, &imgFilter); 85109a1b912605ff48c8782dcc5aae55ac77e27037bBrian 8520b9e96fae9493d5d58f046e01c983a3c4267090eBrian assert(sampler->normalized_coords); 853b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 8540b9e96fae9493d5d58f046e01c983a3c4267090eBrian width = texture->width[level0]; 8550b9e96fae9493d5d58f046e01c983a3c4267090eBrian height = texture->height[level0]; 85609a1b912605ff48c8782dcc5aae55ac77e27037bBrian 857b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian assert(width > 0); 858612cfb749c3526eeb446bbc631bf24716522f373Brian 859b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian switch (imgFilter) { 8600dc4eea64f56cc93e5359372b08b99a2d600273cBrian case PIPE_TEX_FILTER_NEAREST: 86138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian { 86238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int x[4], y[4]; 86338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian nearest_texcoord_4(sampler->wrap_s, s, width, x); 86438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian nearest_texcoord_4(sampler->wrap_t, t, height, y); 86538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian 86638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (j = 0; j < QUAD_SIZE; j++) { 86738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, faces[j], level0, x[j], y[j], 0, rgba, j); 86838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { 869005ee9f4e05b487d455e87c6843d1d1a3c1536ffBrian Paul shadow_compare(sampler, rgba, p, j); 8703d8c05f7320151898dd224c1daaf3118e1f7ea34Brian } 8713d8c05f7320151898dd224c1daaf3118e1f7ea34Brian 87238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (level0 != level1) { 87338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian /* get texels from second mipmap level and blend */ 87438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float rgba2[4][4]; 87538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian unsigned c; 87638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian x[j] /= 2; 87738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian y[j] /= 2; 87838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, faces[j], level1, x[j], y[j], 0, 87938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian rgba2, j); 88038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){ 881005ee9f4e05b487d455e87c6843d1d1a3c1536ffBrian Paul shadow_compare(sampler, rgba2, p, j); 88238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 88338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian 88438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (c = 0; c < NUM_CHANNELS; c++) { 88538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]); 88638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 887f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 888f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 8890dc4eea64f56cc93e5359372b08b99a2d600273cBrian } 8900dc4eea64f56cc93e5359372b08b99a2d600273cBrian break; 8910dc4eea64f56cc93e5359372b08b99a2d600273cBrian case PIPE_TEX_FILTER_LINEAR: 89298ae83d5cc73b61826823c915b5c59746c2e85c7Keith Whitwell case PIPE_TEX_FILTER_ANISO: 89338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian { 89438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int x0[4], y0[4], x1[4], y1[4]; 89538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float xw[4], yw[4]; /* weights */ 89638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian 89738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian linear_texcoord_4(sampler->wrap_s, s, width, x0, x1, xw); 89838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian linear_texcoord_4(sampler->wrap_t, t, height, y0, y1, yw); 89938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian 90038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (j = 0; j < QUAD_SIZE; j++) { 90138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float tx[4][4]; /* texels */ 90238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int c; 90338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, faces[j], level0, x0[j], y0[j], 0, tx, 0); 90438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, faces[j], level0, x1[j], y0[j], 0, tx, 1); 90538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, faces[j], level0, x0[j], y1[j], 0, tx, 2); 90638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, faces[j], level0, x1[j], y1[j], 0, tx, 3); 90738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { 908efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul shadow_compare4(sampler, tx, p); 9093d8c05f7320151898dd224c1daaf3118e1f7ea34Brian } 9103d8c05f7320151898dd224c1daaf3118e1f7ea34Brian 91138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian /* interpolate R, G, B, A */ 912f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian for (c = 0; c < 4; c++) { 91338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian rgba[c][j] = lerp_2d(xw[j], yw[j], 91438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian tx[c][0], tx[c][1], 91538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian tx[c][2], tx[c][3]); 916f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 917f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian 91838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (level0 != level1) { 91938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian /* get texels from second mipmap level and blend */ 92038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float rgba2[4][4]; 92138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian x0[j] /= 2; 92238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian y0[j] /= 2; 92338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian x1[j] /= 2; 92438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian y1[j] /= 2; 92538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, faces[j], level1, x0[j], y0[j], 0, tx, 0); 92638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, faces[j], level1, x1[j], y0[j], 0, tx, 1); 92738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, faces[j], level1, x0[j], y1[j], 0, tx, 2); 92838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, faces[j], level1, x1[j], y1[j], 0, tx, 3); 92938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){ 930efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul shadow_compare4(sampler, tx, p); 93138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 93238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian 93338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian /* interpolate R, G, B, A */ 93438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (c = 0; c < 4; c++) { 93538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian rgba2[c][j] = lerp_2d(xw[j], yw[j], 93638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian tx[c][0], tx[c][1], tx[c][2], tx[c][3]); 93738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 93838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian 93938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (c = 0; c < NUM_CHANNELS; c++) { 94038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]); 94138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 942f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 943f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 94409a1b912605ff48c8782dcc5aae55ac77e27037bBrian } 94509a1b912605ff48c8782dcc5aae55ac77e27037bBrian break; 9460dc4eea64f56cc93e5359372b08b99a2d600273cBrian default: 9470dc4eea64f56cc93e5359372b08b99a2d600273cBrian assert(0); 9480dc4eea64f56cc93e5359372b08b99a2d600273cBrian } 9490dc4eea64f56cc93e5359372b08b99a2d600273cBrian} 95034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 95134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 952dd55083ac1c13723dba6be71f161e2ca7cac7c66Brianstatic INLINE void 953dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_1d(const struct tgsi_sampler *sampler, 954a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float s[QUAD_SIZE], 955a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float t[QUAD_SIZE], 956a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float p[QUAD_SIZE], 9573ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul boolean computeLambda, 958a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float lodbias, 959a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float rgba[NUM_CHANNELS][QUAD_SIZE]) 960a34b8594b7b2d00404bb639621ec1ce918ba0786Brian{ 961a34b8594b7b2d00404bb639621ec1ce918ba0786Brian static const unsigned faces[4] = {0, 0, 0, 0}; 962d16b4bc32a731cb6ae320e8c187af3bc751d4138Brian static const float tzero[4] = {0, 0, 0, 0}; 9633ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul sp_get_samples_2d_common(sampler, s, tzero, NULL, 9643ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul computeLambda, lodbias, rgba, faces); 965a34b8594b7b2d00404bb639621ec1ce918ba0786Brian} 966a34b8594b7b2d00404bb639621ec1ce918ba0786Brian 967a34b8594b7b2d00404bb639621ec1ce918ba0786Brian 968dd55083ac1c13723dba6be71f161e2ca7cac7c66Brianstatic INLINE void 969dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_2d(const struct tgsi_sampler *sampler, 970a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float s[QUAD_SIZE], 971a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float t[QUAD_SIZE], 972a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float p[QUAD_SIZE], 9733ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul boolean computeLambda, 974a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float lodbias, 975a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float rgba[NUM_CHANNELS][QUAD_SIZE]) 976a34b8594b7b2d00404bb639621ec1ce918ba0786Brian{ 977a34b8594b7b2d00404bb639621ec1ce918ba0786Brian static const unsigned faces[4] = {0, 0, 0, 0}; 9783ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul sp_get_samples_2d_common(sampler, s, t, p, 9793ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul computeLambda, lodbias, rgba, faces); 980a34b8594b7b2d00404bb639621ec1ce918ba0786Brian} 981a34b8594b7b2d00404bb639621ec1ce918ba0786Brian 982a34b8594b7b2d00404bb639621ec1ce918ba0786Brian 983dd55083ac1c13723dba6be71f161e2ca7cac7c66Brianstatic INLINE void 984dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_3d(const struct tgsi_sampler *tgsi_sampler, 985b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float s[QUAD_SIZE], 986b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float t[QUAD_SIZE], 987b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float p[QUAD_SIZE], 9883ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul boolean computeLambda, 989f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian float lodbias, 990b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float rgba[NUM_CHANNELS][QUAD_SIZE]) 99134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{ 9920b9e96fae9493d5d58f046e01c983a3c4267090eBrian const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); 993aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell const struct pipe_texture *texture = samp->texture; 994aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell const struct pipe_sampler_state *sampler = samp->sampler; 99534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian /* get/map pipe_surfaces corresponding to 3D tex slices */ 9963d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian unsigned level0, level1, j, imgFilter; 9973d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian int width, height, depth; 9983d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian float levelBlend; 9993d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian const uint face = 0; 10003d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 10013ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias, 10023d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian &level0, &level1, &levelBlend, &imgFilter); 10033d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 10040b9e96fae9493d5d58f046e01c983a3c4267090eBrian assert(sampler->normalized_coords); 1005b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 10060b9e96fae9493d5d58f046e01c983a3c4267090eBrian width = texture->width[level0]; 10070b9e96fae9493d5d58f046e01c983a3c4267090eBrian height = texture->height[level0]; 10080b9e96fae9493d5d58f046e01c983a3c4267090eBrian depth = texture->depth[level0]; 10093d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 10103d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian assert(width > 0); 10113d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian assert(height > 0); 10123d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian assert(depth > 0); 10133d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 10143d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian switch (imgFilter) { 10153d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian case PIPE_TEX_FILTER_NEAREST: 101638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian { 101738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int x[4], y[4], z[4]; 101838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian nearest_texcoord_4(sampler->wrap_s, s, width, x); 101938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian nearest_texcoord_4(sampler->wrap_t, t, height, y); 102038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian nearest_texcoord_4(sampler->wrap_r, p, depth, z); 102138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (j = 0; j < QUAD_SIZE; j++) { 102238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level0, x[j], y[j], z[j], rgba, j); 102338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (level0 != level1) { 102438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian /* get texels from second mipmap level and blend */ 102538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float rgba2[4][4]; 102638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian unsigned c; 102738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian x[j] /= 2; 102838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian y[j] /= 2; 102938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian z[j] /= 2; 103038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level1, x[j], y[j], z[j], rgba2, j); 103138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (c = 0; c < NUM_CHANNELS; c++) { 103238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian rgba[c][j] = lerp(levelBlend, rgba2[c][j], rgba[c][j]); 103338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 10343d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 10353d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 10363d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 10373d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian break; 10383d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian case PIPE_TEX_FILTER_LINEAR: 103998ae83d5cc73b61826823c915b5c59746c2e85c7Keith Whitwell case PIPE_TEX_FILTER_ANISO: 104038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian { 104138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int x0[4], x1[4], y0[4], y1[4], z0[4], z1[4]; 104238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float xw[4], yw[4], zw[4]; /* interpolation weights */ 104338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian linear_texcoord_4(sampler->wrap_s, s, width, x0, x1, xw); 104438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian linear_texcoord_4(sampler->wrap_t, t, height, y0, y1, yw); 104538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian linear_texcoord_4(sampler->wrap_r, p, depth, z0, z1, zw); 104638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian 104738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (j = 0; j < QUAD_SIZE; j++) { 104838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int c; 104938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float tx0[4][4], tx1[4][4]; 105038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level0, x0[j], y0[j], z0[j], tx0, 0); 105138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level0, x1[j], y0[j], z0[j], tx0, 1); 105238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level0, x0[j], y1[j], z0[j], tx0, 2); 105338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level0, x1[j], y1[j], z0[j], tx0, 3); 105438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level0, x0[j], y0[j], z1[j], tx1, 0); 105538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level0, x1[j], y0[j], z1[j], tx1, 1); 105638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level0, x0[j], y1[j], z1[j], tx1, 2); 105738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level0, x1[j], y1[j], z1[j], tx1, 3); 105838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian 105938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian /* interpolate R, G, B, A */ 10603d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian for (c = 0; c < 4; c++) { 106138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian rgba[c][j] = lerp_3d(xw[j], yw[j], zw[j], 106238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian tx0[c][0], tx0[c][1], 106338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian tx0[c][2], tx0[c][3], 106438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian tx1[c][0], tx1[c][1], 106538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian tx1[c][2], tx1[c][3]); 10663d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 10673d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 106838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (level0 != level1) { 106938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian /* get texels from second mipmap level and blend */ 107038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float rgba2[4][4]; 107138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian x0[j] /= 2; 107238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian y0[j] /= 2; 107338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian z0[j] /= 2; 107438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian x1[j] /= 2; 107538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian y1[j] /= 2; 107638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian z1[j] /= 2; 107738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level1, x0[j], y0[j], z0[j], tx0, 0); 107838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level1, x1[j], y0[j], z0[j], tx0, 1); 107938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level1, x0[j], y1[j], z0[j], tx0, 2); 108038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level1, x1[j], y1[j], z0[j], tx0, 3); 108138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level1, x0[j], y0[j], z1[j], tx1, 0); 108238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level1, x1[j], y0[j], z1[j], tx1, 1); 108338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level1, x0[j], y1[j], z1[j], tx1, 2); 108438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level1, x1[j], y1[j], z1[j], tx1, 3); 108538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian 108638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian /* interpolate R, G, B, A */ 108738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (c = 0; c < 4; c++) { 108838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian rgba2[c][j] = lerp_3d(xw[j], yw[j], zw[j], 108938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian tx0[c][0], tx0[c][1], 109038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian tx0[c][2], tx0[c][3], 109138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian tx1[c][0], tx1[c][1], 109238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian tx1[c][2], tx1[c][3]); 109338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 109438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian 109538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian /* blend mipmap levels */ 109638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (c = 0; c < NUM_CHANNELS; c++) { 109738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]); 109838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 10993d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 11003d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 11013d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 11023d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian break; 11033d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian default: 11043d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian assert(0); 11053d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 110634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian} 110734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 110834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 110934a48abd5ff82ce9748fc29191e35a0985d47c5fBrianstatic void 1110dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_cube(const struct tgsi_sampler *sampler, 1111b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float s[QUAD_SIZE], 1112b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float t[QUAD_SIZE], 1113b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float p[QUAD_SIZE], 11143ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul boolean computeLambda, 1115f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian float lodbias, 1116b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float rgba[NUM_CHANNELS][QUAD_SIZE]) 111734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{ 1118a34b8594b7b2d00404bb639621ec1ce918ba0786Brian unsigned faces[QUAD_SIZE], j; 1119a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float ssss[4], tttt[4]; 1120b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian for (j = 0; j < QUAD_SIZE; j++) { 1121a34b8594b7b2d00404bb639621ec1ce918ba0786Brian faces[j] = choose_cube_face(s[j], t[j], p[j], ssss + j, tttt + j); 1122b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian } 11233ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul sp_get_samples_2d_common(sampler, ssss, tttt, NULL, 11243ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul computeLambda, lodbias, rgba, faces); 112534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian} 112634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 112734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 1128b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrianstatic void 1129dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler, 1130b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian const float s[QUAD_SIZE], 1131b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian const float t[QUAD_SIZE], 1132b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian const float p[QUAD_SIZE], 11333ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul boolean computeLambda, 1134b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian float lodbias, 1135b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian float rgba[NUM_CHANNELS][QUAD_SIZE]) 1136b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{ 11370b9e96fae9493d5d58f046e01c983a3c4267090eBrian const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); 1138aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell const struct pipe_texture *texture = samp->texture; 1139aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell const struct pipe_sampler_state *sampler = samp->sampler; 114036b941cdbf83bc23c95598baf7638def1632db01Brian const uint face = 0; 1141b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian unsigned level0, level1, j, imgFilter; 1142b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian int width, height; 1143b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian float levelBlend; 1144b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 11453ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias, 1146b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian &level0, &level1, &levelBlend, &imgFilter); 1147b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 1148b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian /* texture RECTS cannot be mipmapped */ 1149b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(level0 == level1); 1150b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 11510b9e96fae9493d5d58f046e01c983a3c4267090eBrian width = texture->width[level0]; 11520b9e96fae9493d5d58f046e01c983a3c4267090eBrian height = texture->height[level0]; 1153b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 1154b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(width > 0); 1155b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 1156b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian switch (imgFilter) { 1157b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_FILTER_NEAREST: 115838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian { 115938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int x[4], y[4]; 116038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian nearest_texcoord_unnorm_4(sampler->wrap_s, s, width, x); 116138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian nearest_texcoord_unnorm_4(sampler->wrap_t, t, height, y); 116238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (j = 0; j < QUAD_SIZE; j++) { 116338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level0, x[j], y[j], 0, rgba, j); 116438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { 1165005ee9f4e05b487d455e87c6843d1d1a3c1536ffBrian Paul shadow_compare(sampler, rgba, p, j); 116638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 1167b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 1168b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 1169b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian break; 1170b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_FILTER_LINEAR: 117198ae83d5cc73b61826823c915b5c59746c2e85c7Keith Whitwell case PIPE_TEX_FILTER_ANISO: 117238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian { 117338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int x0[4], y0[4], x1[4], y1[4]; 117438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float xw[4], yw[4]; /* weights */ 117538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian linear_texcoord_unnorm_4(sampler->wrap_s, s, width, x0, x1, xw); 117638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian linear_texcoord_unnorm_4(sampler->wrap_t, t, height, y0, y1, yw); 117738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (j = 0; j < QUAD_SIZE; j++) { 117838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float tx[4][4]; /* texels */ 117938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int c; 118038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level0, x0[j], y0[j], 0, tx, 0); 118138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level0, x1[j], y0[j], 0, tx, 1); 118238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level0, x0[j], y1[j], 0, tx, 2); 118338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level0, x1[j], y1[j], 0, tx, 3); 118438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { 1185efe9faf0612778db2423a4f8835b318b95d9efd7Brian Paul shadow_compare4(sampler, tx, p); 118638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 118738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (c = 0; c < 4; c++) { 118838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian rgba[c][j] = lerp_2d(xw[j], yw[j], 118938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian tx[c][0], tx[c][1], tx[c][2], tx[c][3]); 119038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 1191b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 1192b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 1193b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian break; 1194b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian default: 1195b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(0); 1196b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 1197b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian} 1198b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 1199b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 1200a34b8594b7b2d00404bb639621ec1ce918ba0786Brian/** 12013ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul * Common code for vertex/fragment program texture sampling. 1202a34b8594b7b2d00404bb639621ec1ce918ba0786Brian */ 12033ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paulstatic INLINE void 12040b9e96fae9493d5d58f046e01c983a3c4267090eBriansp_get_samples(struct tgsi_sampler *tgsi_sampler, 1205b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float s[QUAD_SIZE], 1206b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float t[QUAD_SIZE], 1207b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float p[QUAD_SIZE], 12083ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul boolean computeLambda, 1209f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian float lodbias, 1210b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float rgba[NUM_CHANNELS][QUAD_SIZE]) 121134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{ 12120b9e96fae9493d5d58f046e01c983a3c4267090eBrian const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); 1213aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell const struct pipe_texture *texture = samp->texture; 1214aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell const struct pipe_sampler_state *sampler = samp->sampler; 12150b9e96fae9493d5d58f046e01c983a3c4267090eBrian 12160b9e96fae9493d5d58f046e01c983a3c4267090eBrian if (!texture) 12174f23468bd0d14b8ed687a641003d587b91ad39a7Brian return; 12184f23468bd0d14b8ed687a641003d587b91ad39a7Brian 12190b9e96fae9493d5d58f046e01c983a3c4267090eBrian switch (texture->target) { 122070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell case PIPE_TEXTURE_1D: 12210b9e96fae9493d5d58f046e01c983a3c4267090eBrian assert(sampler->normalized_coords); 12223ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul sp_get_samples_1d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba); 122334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian break; 122470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell case PIPE_TEXTURE_2D: 12250b9e96fae9493d5d58f046e01c983a3c4267090eBrian if (sampler->normalized_coords) 12263ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul sp_get_samples_2d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba); 1227b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian else 12283ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul sp_get_samples_rect(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba); 122934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian break; 123070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell case PIPE_TEXTURE_3D: 12310b9e96fae9493d5d58f046e01c983a3c4267090eBrian assert(sampler->normalized_coords); 12323ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul sp_get_samples_3d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba); 123334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian break; 123470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell case PIPE_TEXTURE_CUBE: 12350b9e96fae9493d5d58f046e01c983a3c4267090eBrian assert(sampler->normalized_coords); 12363ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul sp_get_samples_cube(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba); 123734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian break; 123834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian default: 123934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian assert(0); 124034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 12413d53d38d5e35386de4793162b9dd32e171927059Brian Paul 12423d53d38d5e35386de4793162b9dd32e171927059Brian Paul#if 0 /* DEBUG */ 12433d53d38d5e35386de4793162b9dd32e171927059Brian Paul { 12443d53d38d5e35386de4793162b9dd32e171927059Brian Paul int i; 12453d53d38d5e35386de4793162b9dd32e171927059Brian Paul printf("Sampled at %f, %f, %f:\n", s[0], t[0], p[0]); 12463d53d38d5e35386de4793162b9dd32e171927059Brian Paul for (i = 0; i < 4; i++) { 12473d53d38d5e35386de4793162b9dd32e171927059Brian Paul printf("Frag %d: %f %f %f %f\n", i, 12483d53d38d5e35386de4793162b9dd32e171927059Brian Paul rgba[0][i], 12493d53d38d5e35386de4793162b9dd32e171927059Brian Paul rgba[1][i], 12503d53d38d5e35386de4793162b9dd32e171927059Brian Paul rgba[2][i], 12513d53d38d5e35386de4793162b9dd32e171927059Brian Paul rgba[3][i]); 12523d53d38d5e35386de4793162b9dd32e171927059Brian Paul } 12533d53d38d5e35386de4793162b9dd32e171927059Brian Paul } 12543d53d38d5e35386de4793162b9dd32e171927059Brian Paul#endif 125534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian} 125634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 12573ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul 12583ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul/** 12593ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul * Called via tgsi_sampler::get_samples() when running a fragment shader. 12603ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul * Get four filtered RGBA values from the sampler's texture. 12613ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul */ 12623ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paulvoid 12633ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paulsp_get_samples_fragment(struct tgsi_sampler *tgsi_sampler, 12643ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul const float s[QUAD_SIZE], 12653ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul const float t[QUAD_SIZE], 12663ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul const float p[QUAD_SIZE], 12673ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul float lodbias, 12683ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul float rgba[NUM_CHANNELS][QUAD_SIZE]) 12693ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul{ 12703ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul sp_get_samples(tgsi_sampler, s, t, p, TRUE, lodbias, rgba); 12713ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul} 12723ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul 12733ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul 12743ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul/** 12753ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul * Called via tgsi_sampler::get_samples() when running a vertex shader. 12763ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul * Get four filtered RGBA values from the sampler's texture. 12773ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul */ 12783ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paulvoid 12793ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paulsp_get_samples_vertex(struct tgsi_sampler *tgsi_sampler, 12803ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul const float s[QUAD_SIZE], 12813ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul const float t[QUAD_SIZE], 12823ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul const float p[QUAD_SIZE], 12833ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul float lodbias, 12843ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul float rgba[NUM_CHANNELS][QUAD_SIZE]) 12853ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul{ 12863ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul sp_get_samples(tgsi_sampler, s, t, p, FALSE, lodbias, rgba); 12873ffd529ff19bf8dd7b022a267bf2afe44c7f0f65Brian Paul} 1288