sp_tex_sample.c revision 38bee46e83b18ff4ad42d340b507b1a15b4326c7
10dc4eea64f56cc93e5359372b08b99a2d600273cBrian/************************************************************************** 20dc4eea64f56cc93e5359372b08b99a2d600273cBrian * 30dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 40dc4eea64f56cc93e5359372b08b99a2d600273cBrian * All Rights Reserved. 50dc4eea64f56cc93e5359372b08b99a2d600273cBrian * 60dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Permission is hereby granted, free of charge, to any person obtaining a 70dc4eea64f56cc93e5359372b08b99a2d600273cBrian * copy of this software and associated documentation files (the 80dc4eea64f56cc93e5359372b08b99a2d600273cBrian * "Software"), to deal in the Software without restriction, including 90dc4eea64f56cc93e5359372b08b99a2d600273cBrian * without limitation the rights to use, copy, modify, merge, publish, 100dc4eea64f56cc93e5359372b08b99a2d600273cBrian * distribute, sub license, and/or sell copies of the Software, and to 110dc4eea64f56cc93e5359372b08b99a2d600273cBrian * permit persons to whom the Software is furnished to do so, subject to 120dc4eea64f56cc93e5359372b08b99a2d600273cBrian * the following conditions: 130dc4eea64f56cc93e5359372b08b99a2d600273cBrian * 140dc4eea64f56cc93e5359372b08b99a2d600273cBrian * The above copyright notice and this permission notice (including the 150dc4eea64f56cc93e5359372b08b99a2d600273cBrian * next paragraph) shall be included in all copies or substantial portions 160dc4eea64f56cc93e5359372b08b99a2d600273cBrian * of the Software. 170dc4eea64f56cc93e5359372b08b99a2d600273cBrian * 180dc4eea64f56cc93e5359372b08b99a2d600273cBrian * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 190dc4eea64f56cc93e5359372b08b99a2d600273cBrian * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 200dc4eea64f56cc93e5359372b08b99a2d600273cBrian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 210dc4eea64f56cc93e5359372b08b99a2d600273cBrian * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 220dc4eea64f56cc93e5359372b08b99a2d600273cBrian * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 230dc4eea64f56cc93e5359372b08b99a2d600273cBrian * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 240dc4eea64f56cc93e5359372b08b99a2d600273cBrian * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 250dc4eea64f56cc93e5359372b08b99a2d600273cBrian * 260dc4eea64f56cc93e5359372b08b99a2d600273cBrian **************************************************************************/ 270dc4eea64f56cc93e5359372b08b99a2d600273cBrian 280dc4eea64f56cc93e5359372b08b99a2d600273cBrian/** 290dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Texture sampling 300dc4eea64f56cc93e5359372b08b99a2d600273cBrian * 310dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Authors: 320dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Brian Paul 330dc4eea64f56cc93e5359372b08b99a2d600273cBrian */ 340dc4eea64f56cc93e5359372b08b99a2d600273cBrian 3508f33a025100dea2d951e6d628891fe294b18082Brian#include "sp_context.h" 36b91de8a6e7d74d38698b6dad9f34040e484e69afBrian#include "sp_headers.h" 370dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "sp_surface.h" 380b9e96fae9493d5d58f046e01c983a3c4267090eBrian#include "sp_texture.h" 390dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "sp_tex_sample.h" 4070eb7996f265f3634dabda078f13d1be3533cc65Brian#include "sp_tile_cache.h" 410dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "pipe/p_context.h" 420dc4eea64f56cc93e5359372b08b99a2d600273cBrian#include "pipe/p_defines.h" 43c208a2c791fa24c7c5887fc496738cbddbfafc72José Fonseca#include "tgsi/tgsi_exec.h" 441a46dcc8a927dfb38ca1381e7b3dafb789f8257cBrian Paul#include "util/u_math.h" 454f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h" 460dc4eea64f56cc93e5359372b08b99a2d600273cBrian 470dc4eea64f56cc93e5359372b08b99a2d600273cBrian 4808f33a025100dea2d951e6d628891fe294b18082Brian/* 4908f33a025100dea2d951e6d628891fe294b18082Brian * Note, the FRAC macro has to work perfectly. Otherwise you'll sometimes 5008f33a025100dea2d951e6d628891fe294b18082Brian * see 1-pixel bands of improperly weighted linear-filtered textures. 5108f33a025100dea2d951e6d628891fe294b18082Brian * The tests/texwrap.c demo is a good test. 5208f33a025100dea2d951e6d628891fe294b18082Brian * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0. 5308f33a025100dea2d951e6d628891fe294b18082Brian * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x). 5408f33a025100dea2d951e6d628891fe294b18082Brian */ 559935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul#define FRAC(f) ((f) - util_ifloor(f)) 5608f33a025100dea2d951e6d628891fe294b18082Brian 5708f33a025100dea2d951e6d628891fe294b18082Brian 5808f33a025100dea2d951e6d628891fe294b18082Brian/** 5908f33a025100dea2d951e6d628891fe294b18082Brian * Linear interpolation macro 6008f33a025100dea2d951e6d628891fe294b18082Brian */ 6138bee46e83b18ff4ad42d340b507b1a15b4326c7Brianstatic INLINE float 6238bee46e83b18ff4ad42d340b507b1a15b4326c7Brianlerp(float a, float v0, float v1) 6338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian{ 6438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian return v0 + a * (v1 - v0); 6538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian} 660dc4eea64f56cc93e5359372b08b99a2d600273cBrian 670dc4eea64f56cc93e5359372b08b99a2d600273cBrian 680dc4eea64f56cc93e5359372b08b99a2d600273cBrian/** 690dc4eea64f56cc93e5359372b08b99a2d600273cBrian * Do 2D/biliner interpolation of float values. 700dc4eea64f56cc93e5359372b08b99a2d600273cBrian * v00, v10, v01 and v11 are typically four texture samples in a square/box. 710dc4eea64f56cc93e5359372b08b99a2d600273cBrian * a and b are the horizontal and vertical interpolants. 720dc4eea64f56cc93e5359372b08b99a2d600273cBrian * It's important that this function is inlined when compiled with 730dc4eea64f56cc93e5359372b08b99a2d600273cBrian * optimization! If we find that's not true on some systems, convert 740dc4eea64f56cc93e5359372b08b99a2d600273cBrian * to a macro. 750dc4eea64f56cc93e5359372b08b99a2d600273cBrian */ 76b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic INLINE float 77b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianlerp_2d(float a, float b, 78b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float v00, float v10, float v01, float v11) 790dc4eea64f56cc93e5359372b08b99a2d600273cBrian{ 8038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian const float temp0 = lerp(a, v00, v10); 8138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian const float temp1 = lerp(a, v01, v11); 8238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian return lerp(b, temp0, temp1); 8338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian} 8438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian 8538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian 8638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian/** 8738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * As above, but 3D interpolation of 8 values. 8838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian */ 8938bee46e83b18ff4ad42d340b507b1a15b4326c7Brianstatic INLINE float 9038bee46e83b18ff4ad42d340b507b1a15b4326c7Brianlerp_3d(float a, float b, float c, 9138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float v000, float v100, float v010, float v110, 9238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float v001, float v101, float v011, float v111) 9338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian{ 9438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian const float temp0 = lerp_2d(a, b, v000, v100, v010, v110); 9538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian const float temp1 = lerp_2d(a, b, v001, v101, v011, v111); 9638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian return lerp(c, temp0, temp1); 970dc4eea64f56cc93e5359372b08b99a2d600273cBrian} 980dc4eea64f56cc93e5359372b08b99a2d600273cBrian 990dc4eea64f56cc93e5359372b08b99a2d600273cBrian 10038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian 1010dc4eea64f56cc93e5359372b08b99a2d600273cBrian/** 102906768316d9521a32d9a7eebc9edaf76c06a98a7Brian * If A is a signed integer, A % B doesn't give the right value for A < 0 103906768316d9521a32d9a7eebc9edaf76c06a98a7Brian * (in terms of texture repeat). Just casting to unsigned fixes that. 1040dc4eea64f56cc93e5359372b08b99a2d600273cBrian */ 105906768316d9521a32d9a7eebc9edaf76c06a98a7Brian#define REMAINDER(A, B) ((unsigned) (A) % (unsigned) (B)) 10608f33a025100dea2d951e6d628891fe294b18082Brian 10708f33a025100dea2d951e6d628891fe294b18082Brian 10808f33a025100dea2d951e6d628891fe294b18082Brian/** 10938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * Apply texture coord wrapping mode and return integer texture indexes 11038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * for a vector of four texcoords (S or T or P). 11108f33a025100dea2d951e6d628891fe294b18082Brian * \param wrapMode PIPE_TEX_WRAP_x 11238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param s the incoming texcoords 11308f33a025100dea2d951e6d628891fe294b18082Brian * \param size the texture image size 11438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param icoord returns the integer texcoords 11508f33a025100dea2d951e6d628891fe294b18082Brian * \return integer texture index 11608f33a025100dea2d951e6d628891fe294b18082Brian */ 11738bee46e83b18ff4ad42d340b507b1a15b4326c7Brianstatic INLINE void 11838bee46e83b18ff4ad42d340b507b1a15b4326c7Briannearest_texcoord_4(unsigned wrapMode, const float s[4], unsigned size, 11938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int icoord[4]) 1200dc4eea64f56cc93e5359372b08b99a2d600273cBrian{ 12138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian uint ch; 1220dc4eea64f56cc93e5359372b08b99a2d600273cBrian switch (wrapMode) { 1230dc4eea64f56cc93e5359372b08b99a2d600273cBrian case PIPE_TEX_WRAP_REPEAT: 12408f33a025100dea2d951e6d628891fe294b18082Brian /* s limited to [0,1) */ 12508f33a025100dea2d951e6d628891fe294b18082Brian /* i limited to [0,size-1] */ 12638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 12738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int i = util_ifloor(s[ch] * size); 12838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = REMAINDER(i, size); 12938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 13038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian return; 1310dc4eea64f56cc93e5359372b08b99a2d600273cBrian case PIPE_TEX_WRAP_CLAMP: 13208f33a025100dea2d951e6d628891fe294b18082Brian /* s limited to [0,1] */ 13308f33a025100dea2d951e6d628891fe294b18082Brian /* i limited to [0,size-1] */ 13438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 13538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (s[ch] <= 0.0F) 13638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = 0; 13738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else if (s[ch] >= 1.0F) 13838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = size - 1; 13938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else 14038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = util_ifloor(s[ch] * size); 14138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 14238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian return; 14308f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 14408f33a025100dea2d951e6d628891fe294b18082Brian { 14508f33a025100dea2d951e6d628891fe294b18082Brian /* s limited to [min,max] */ 14608f33a025100dea2d951e6d628891fe294b18082Brian /* i limited to [0, size-1] */ 147b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float min = 1.0F / (2.0F * size); 148b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float max = 1.0F - min; 14938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 15038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (s[ch] < min) 15138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = 0; 15238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else if (s[ch] > max) 15338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = size - 1; 15438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else 15538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = util_ifloor(s[ch] * size); 15638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 15708f33a025100dea2d951e6d628891fe294b18082Brian } 15838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian return; 15908f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 16008f33a025100dea2d951e6d628891fe294b18082Brian { 16108f33a025100dea2d951e6d628891fe294b18082Brian /* s limited to [min,max] */ 16208f33a025100dea2d951e6d628891fe294b18082Brian /* i limited to [-1, size] */ 163b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float min = -1.0F / (2.0F * size); 164b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float max = 1.0F - min; 16538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 16638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (s[ch] <= min) 16738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = -1; 16838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else if (s[ch] >= max) 16938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = size; 17038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else 17138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = util_ifloor(s[ch] * size); 17238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 17308f33a025100dea2d951e6d628891fe294b18082Brian } 17438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian return; 17508f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_REPEAT: 17608f33a025100dea2d951e6d628891fe294b18082Brian { 177b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float min = 1.0F / (2.0F * size); 178b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float max = 1.0F - min; 17938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 18038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian const int flr = util_ifloor(s[ch]); 18138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float u; 18238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (flr & 1) 18338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u = 1.0F - (s[ch] - (float) flr); 18438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else 18538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u = s[ch] - (float) flr; 18638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (u < min) 18738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = 0; 18838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else if (u > max) 18938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = size - 1; 19038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else 19138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = util_ifloor(u * size); 19238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 19308f33a025100dea2d951e6d628891fe294b18082Brian } 19438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian return; 19508f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_CLAMP: 19638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 19708f33a025100dea2d951e6d628891fe294b18082Brian /* s limited to [0,1] */ 19808f33a025100dea2d951e6d628891fe294b18082Brian /* i limited to [0,size-1] */ 19938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian const float u = fabsf(s[ch]); 20008f33a025100dea2d951e6d628891fe294b18082Brian if (u <= 0.0F) 20138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = 0; 20208f33a025100dea2d951e6d628891fe294b18082Brian else if (u >= 1.0F) 20338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = size - 1; 20408f33a025100dea2d951e6d628891fe294b18082Brian else 20538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = util_ifloor(u * size); 20608f33a025100dea2d951e6d628891fe294b18082Brian } 20738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian return; 20808f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: 20908f33a025100dea2d951e6d628891fe294b18082Brian { 21008f33a025100dea2d951e6d628891fe294b18082Brian /* s limited to [min,max] */ 21108f33a025100dea2d951e6d628891fe294b18082Brian /* i limited to [0, size-1] */ 212b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float min = 1.0F / (2.0F * size); 213b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float max = 1.0F - min; 21438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 21538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian const float u = fabsf(s[ch]); 21638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (u < min) 21738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = 0; 21838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else if (u > max) 21938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = size - 1; 22038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else 22138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = util_ifloor(u * size); 22238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 22308f33a025100dea2d951e6d628891fe294b18082Brian } 22438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian return; 22508f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: 22608f33a025100dea2d951e6d628891fe294b18082Brian { 22708f33a025100dea2d951e6d628891fe294b18082Brian /* s limited to [min,max] */ 22808f33a025100dea2d951e6d628891fe294b18082Brian /* i limited to [0, size-1] */ 229b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float min = -1.0F / (2.0F * size); 230b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float max = 1.0F - min; 23138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 23238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian const float u = fabsf(s[ch]); 23338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (u < min) 23438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = -1; 23538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else if (u > max) 23638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = size; 23738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else 23838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch] = util_ifloor(u * size); 23938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 24008f33a025100dea2d951e6d628891fe294b18082Brian } 24138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian return; 2420dc4eea64f56cc93e5359372b08b99a2d600273cBrian default: 2430dc4eea64f56cc93e5359372b08b99a2d600273cBrian assert(0); 2440dc4eea64f56cc93e5359372b08b99a2d600273cBrian } 2450dc4eea64f56cc93e5359372b08b99a2d600273cBrian} 2460dc4eea64f56cc93e5359372b08b99a2d600273cBrian 24708f33a025100dea2d951e6d628891fe294b18082Brian 24808f33a025100dea2d951e6d628891fe294b18082Brian/** 24938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * Used to compute texel locations for linear sampling for four texcoords. 25008f33a025100dea2d951e6d628891fe294b18082Brian * \param wrapMode PIPE_TEX_WRAP_x 25138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param s the texcoords 25208f33a025100dea2d951e6d628891fe294b18082Brian * \param size the texture image size 25338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param icoord0 returns first texture indexes 25438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param icoord1 returns second texture indexes (usually icoord0 + 1) 25538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param w returns blend factor/weight between texture indexes 25638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian * \param icoord returns the computed integer texture coords 25708f33a025100dea2d951e6d628891fe294b18082Brian */ 2580dc4eea64f56cc93e5359372b08b99a2d600273cBrianstatic INLINE void 25938bee46e83b18ff4ad42d340b507b1a15b4326c7Brianlinear_texcoord_4(unsigned wrapMode, const float s[4], unsigned size, 26038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int icoord0[4], int icoord1[4], float w[4]) 2610dc4eea64f56cc93e5359372b08b99a2d600273cBrian{ 26238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian uint ch; 26338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian 2640dc4eea64f56cc93e5359372b08b99a2d600273cBrian switch (wrapMode) { 2650dc4eea64f56cc93e5359372b08b99a2d600273cBrian case PIPE_TEX_WRAP_REPEAT: 26638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 26738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float u = s[ch] * size - 0.5F; 26838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord0[ch] = REMAINDER(util_ifloor(u), size); 26938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord1[ch] = REMAINDER(icoord0[ch] + 1, size); 27038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian w[ch] = FRAC(u); 27138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 27238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian break;; 2730dc4eea64f56cc93e5359372b08b99a2d600273cBrian case PIPE_TEX_WRAP_CLAMP: 27438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 27538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float u = CLAMP(s[ch], 0.0F, 1.0F); 27638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u = u * size - 0.5f; 27738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord0[ch] = util_ifloor(u); 27838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord1[ch] = icoord0[ch] + 1; 27938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian w[ch] = FRAC(u); 28038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 28138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian break;; 28208f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 28338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 28438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float u = CLAMP(s[ch], 0.0F, 1.0F); 28538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u = u * size - 0.5f; 28638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord0[ch] = util_ifloor(u); 28738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord1[ch] = icoord0[ch] + 1; 28838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (icoord0[ch] < 0) 28938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord0[ch] = 0; 29038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (icoord1[ch] >= (int) size) 29138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord1[ch] = size - 1; 29238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian w[ch] = FRAC(u); 29338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 29438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian break;; 29508f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 29608f33a025100dea2d951e6d628891fe294b18082Brian { 297b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float min = -1.0F / (2.0F * size); 298b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float max = 1.0F - min; 29938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 30038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float u = CLAMP(s[ch], min, max); 30138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u = u * size - 0.5f; 30238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord0[ch] = util_ifloor(u); 30338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord1[ch] = icoord0[ch] + 1; 30438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian w[ch] = FRAC(u); 30538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 30608f33a025100dea2d951e6d628891fe294b18082Brian } 30738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian break;; 30808f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_REPEAT: 30938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 31038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian const int flr = util_ifloor(s[ch]); 31138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float u; 31208f33a025100dea2d951e6d628891fe294b18082Brian if (flr & 1) 31338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u = 1.0F - (s[ch] - (float) flr); 31408f33a025100dea2d951e6d628891fe294b18082Brian else 31538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u = s[ch] - (float) flr; 31638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u = u * size - 0.5F; 31738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord0[ch] = util_ifloor(u); 31838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord1[ch] = icoord0[ch] + 1; 31938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (icoord0[ch] < 0) 32038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord0[ch] = 0; 32138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (icoord1[ch] >= (int) size) 32238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord1[ch] = size - 1; 32338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian w[ch] = FRAC(u); 32408f33a025100dea2d951e6d628891fe294b18082Brian } 32538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian break;; 32608f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_CLAMP: 32738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 32838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float u = fabsf(s[ch]); 32938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (u >= 1.0F) 33038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u = (float) size; 33138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else 33238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u *= size; 33338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u -= 0.5F; 33438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord0[ch] = util_ifloor(u); 33538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord1[ch] = icoord0[ch] + 1; 33638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian w[ch] = FRAC(u); 33738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 33838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian break;; 33908f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: 34038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 34138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float u = fabsf(s[ch]); 34238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (u >= 1.0F) 34338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u = (float) size; 34438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else 34538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u *= size; 34638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u -= 0.5F; 34738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord0[ch] = util_ifloor(u); 34838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord1[ch] = icoord0[ch] + 1; 34938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (icoord0[ch] < 0) 35038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord0[ch] = 0; 35138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (icoord1[ch] >= (int) size) 35238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord1[ch] = size - 1; 35338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian w[ch] = FRAC(u); 35438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 35538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian break;; 35608f33a025100dea2d951e6d628891fe294b18082Brian case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: 35708f33a025100dea2d951e6d628891fe294b18082Brian { 358b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float min = -1.0F / (2.0F * size); 359b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float max = 1.0F - min; 36038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 36138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float u = fabsf(s[ch]); 36238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (u <= min) 36338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u = min * size; 36438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else if (u >= max) 36538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u = max * size; 36638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian else 36738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u *= size; 36838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u -= 0.5F; 36938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord0[ch] = util_ifloor(u); 37038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord1[ch] = icoord0[ch] + 1; 37138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian w[ch] = FRAC(u); 37238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 37308f33a025100dea2d951e6d628891fe294b18082Brian } 37438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian break;; 3750dc4eea64f56cc93e5359372b08b99a2d600273cBrian default: 3760dc4eea64f56cc93e5359372b08b99a2d600273cBrian assert(0); 3770dc4eea64f56cc93e5359372b08b99a2d600273cBrian } 3780dc4eea64f56cc93e5359372b08b99a2d600273cBrian} 3790dc4eea64f56cc93e5359372b08b99a2d600273cBrian 3800dc4eea64f56cc93e5359372b08b99a2d600273cBrian 381b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian/** 382b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * For RECT textures / unnormalized texcoords 383b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * Only a subset of wrap modes supported. 384b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian */ 38538bee46e83b18ff4ad42d340b507b1a15b4326c7Brianstatic INLINE void 38638bee46e83b18ff4ad42d340b507b1a15b4326c7Briannearest_texcoord_unnorm_4(unsigned wrapMode, const float s[4], unsigned size, 38738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int icoord[4]) 388b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{ 38938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian uint ch; 390b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian switch (wrapMode) { 391b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_WRAP_CLAMP: 39238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 39338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int i = util_ifloor(s[ch]); 39438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch]= CLAMP(i, 0, (int) size-1); 39538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 39638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian return; 397b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 398b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian /* fall-through */ 399b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 40038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 40138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord[ch]= util_ifloor( CLAMP(s[ch], 0.5F, (float) size - 0.5F) ); 40238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 40338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian return; 404b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian default: 405b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(0); 406b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 407b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian} 408b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 409b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 410b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian/** 411b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * For RECT textures / unnormalized texcoords. 412b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian * Only a subset of wrap modes supported. 413b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian */ 414b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrianstatic INLINE void 41538bee46e83b18ff4ad42d340b507b1a15b4326c7Brianlinear_texcoord_unnorm_4(unsigned wrapMode, const float s[4], unsigned size, 41638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int icoord0[4], int icoord1[4], float w[4]) 417b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{ 41838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian uint ch; 419b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian switch (wrapMode) { 420b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_WRAP_CLAMP: 42138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 42238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian /* Not exactly what the spec says, but it matches NVIDIA output */ 42338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float u = CLAMP(s[ch] - 0.5F, 0.0f, (float) size - 1.0f); 42438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord0[ch] = util_ifloor(u); 42538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord1[ch] = icoord0[ch] + 1; 42638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian w[ch] = FRAC(u); 42738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 42838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian return; 429b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 430b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian /* fall-through */ 431b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 43238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (ch = 0; ch < 4; ch++) { 43338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float u = CLAMP(s[ch], 0.5F, (float) size - 0.5F); 43438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian u -= 0.5F; 43538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord0[ch] = util_ifloor(u); 43638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord1[ch] = icoord0[ch] + 1; 43738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (icoord1[ch] > (int) size - 1) 43838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian icoord1[ch] = size - 1; 43938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian w[ch] = FRAC(u); 44038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 441b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian break; 442b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian default: 443b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(0); 444b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 445b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian} 446b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 447b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 44870af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwellstatic unsigned 449a34b8594b7b2d00404bb639621ec1ce918ba0786Brianchoose_cube_face(float rx, float ry, float rz, float *newS, float *newT) 45034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{ 45134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian /* 45234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian major axis 45334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian direction target sc tc ma 45434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ---------- ------------------------------- --- --- --- 45534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian +rx TEXTURE_CUBE_MAP_POSITIVE_X_EXT -rz -ry rx 45634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian -rx TEXTURE_CUBE_MAP_NEGATIVE_X_EXT +rz -ry rx 45734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian +ry TEXTURE_CUBE_MAP_POSITIVE_Y_EXT +rx +rz ry 45834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian -ry TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT +rx -rz ry 45934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian +rz TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz 46034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian -rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz 46134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian */ 4629935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz); 46370af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell unsigned face; 464b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float sc, tc, ma; 46534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 46634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian if (arx > ary && arx > arz) { 46734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian if (rx >= 0.0F) { 46834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_POS_X; 46934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = -rz; 47034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = -ry; 47134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = arx; 47234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 47334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian else { 47434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_NEG_X; 47534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = rz; 47634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = -ry; 47734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = arx; 47834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 47934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 48034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian else if (ary > arx && ary > arz) { 48134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian if (ry >= 0.0F) { 48234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_POS_Y; 48334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = rx; 48434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = rz; 48534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = ary; 48634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 48734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian else { 48834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_NEG_Y; 48934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = rx; 49034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = -rz; 49134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = ary; 49234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 49334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 49434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian else { 49534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian if (rz > 0.0F) { 49634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_POS_Z; 49734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = rx; 49834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = -ry; 49934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = arz; 50034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 50134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian else { 50234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian face = PIPE_TEX_FACE_NEG_Z; 50334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian sc = -rx; 50434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian tc = -ry; 50534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian ma = arz; 50634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 50734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 50834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 509a34b8594b7b2d00404bb639621ec1ce918ba0786Brian *newS = ( sc / ma + 1.0F ) * 0.5F; 510a34b8594b7b2d00404bb639621ec1ce918ba0786Brian *newT = ( tc / ma + 1.0F ) * 0.5F; 51134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 51234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian return face; 51334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian} 51434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 51534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 516b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/** 517b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * Examine the quad's texture coordinates to compute the partial 518b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * derivatives w.r.t X and Y, then compute lambda (level of detail). 519b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * 520b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * This is only done for fragment shaders, not vertex shaders. 521b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian */ 522b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic float 5230b9e96fae9493d5d58f046e01c983a3c4267090eBriancompute_lambda(const struct pipe_texture *tex, 5240b9e96fae9493d5d58f046e01c983a3c4267090eBrian const struct pipe_sampler_state *sampler, 525b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float s[QUAD_SIZE], 526b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float t[QUAD_SIZE], 527f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian const float p[QUAD_SIZE], 528f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian float lodbias) 529b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian{ 530b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float rho, lambda; 531b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 5320b9e96fae9493d5d58f046e01c983a3c4267090eBrian assert(sampler->normalized_coords); 533b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 534b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian assert(s); 535b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian { 536b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dsdx = s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]; 537b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dsdy = s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]; 5389935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul dsdx = fabsf(dsdx); 5399935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul dsdy = fabsf(dsdy); 5400b9e96fae9493d5d58f046e01c983a3c4267090eBrian rho = MAX2(dsdx, dsdy) * tex->width[0]; 541b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian } 542b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian if (t) { 543b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]; 544b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dtdy = t[QUAD_TOP_LEFT] - t[QUAD_BOTTOM_LEFT]; 545b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float max; 5469935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul dtdx = fabsf(dtdx); 5479935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul dtdy = fabsf(dtdy); 5480b9e96fae9493d5d58f046e01c983a3c4267090eBrian max = MAX2(dtdx, dtdy) * tex->height[0]; 549b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian rho = MAX2(rho, max); 550b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian } 551b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian if (p) { 552b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dpdx = p[QUAD_BOTTOM_RIGHT] - p[QUAD_BOTTOM_LEFT]; 553b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float dpdy = p[QUAD_TOP_LEFT] - p[QUAD_BOTTOM_LEFT]; 554b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float max; 5559935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul dpdx = fabsf(dpdx); 5569935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul dpdy = fabsf(dpdy); 5570b9e96fae9493d5d58f046e01c983a3c4267090eBrian max = MAX2(dpdx, dpdy) * tex->depth[0]; 558b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian rho = MAX2(rho, max); 559b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian } 560b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 5611a46dcc8a927dfb38ca1381e7b3dafb789f8257cBrian Paul lambda = util_fast_log2(rho); 5620b9e96fae9493d5d58f046e01c983a3c4267090eBrian lambda += lodbias + sampler->lod_bias; 5630b9e96fae9493d5d58f046e01c983a3c4267090eBrian lambda = CLAMP(lambda, sampler->min_lod, sampler->max_lod); 564b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 565b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian return lambda; 566b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian} 567b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 568b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 569f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian/** 570c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * Do several things here: 571c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 1. Compute lambda from the texcoords, if needed 572c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 2. Determine if we're minifying or magnifying 573c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 3. If minifying, choose mipmap levels 574c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian * 4. Return image filter to use within mipmap images 575dd55083ac1c13723dba6be71f161e2ca7cac7c66Brian * \param level0 Returns first mipmap level to sample from 576dd55083ac1c13723dba6be71f161e2ca7cac7c66Brian * \param level1 Returns second mipmap level to sample from 577dd55083ac1c13723dba6be71f161e2ca7cac7c66Brian * \param levelBlend Returns blend factor between levels, in [0,1] 578dd55083ac1c13723dba6be71f161e2ca7cac7c66Brian * \param imgFilter Returns either the min or mag filter, depending on lambda 579f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian */ 580f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrianstatic void 5810b9e96fae9493d5d58f046e01c983a3c4267090eBrianchoose_mipmap_levels(const struct pipe_texture *texture, 5820b9e96fae9493d5d58f046e01c983a3c4267090eBrian const struct pipe_sampler_state *sampler, 583c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian const float s[QUAD_SIZE], 584c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian const float t[QUAD_SIZE], 585c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian const float p[QUAD_SIZE], 586c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian float lodbias, 587c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian unsigned *level0, unsigned *level1, float *levelBlend, 588c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian unsigned *imgFilter) 58909a1b912605ff48c8782dcc5aae55ac77e27037bBrian{ 5900b9e96fae9493d5d58f046e01c983a3c4267090eBrian if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) { 591c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* no mipmap selection needed */ 5920b9e96fae9493d5d58f046e01c983a3c4267090eBrian *level0 = *level1 = CLAMP((int) sampler->min_lod, 5930b9e96fae9493d5d58f046e01c983a3c4267090eBrian 0, (int) texture->last_level); 59408c9534107fcaf06f9b801551524ed5dc724db13Brian 5950b9e96fae9493d5d58f046e01c983a3c4267090eBrian if (sampler->min_img_filter != sampler->mag_img_filter) { 59608c9534107fcaf06f9b801551524ed5dc724db13Brian /* non-mipmapped texture, but still need to determine if doing 59708c9534107fcaf06f9b801551524ed5dc724db13Brian * minification or magnification. 59808c9534107fcaf06f9b801551524ed5dc724db13Brian */ 5990b9e96fae9493d5d58f046e01c983a3c4267090eBrian float lambda = compute_lambda(texture, sampler, s, t, p, lodbias); 6003b2a291888d8e62787de03f8529806fb562bd186Brian if (lambda <= 0.0) { 6010b9e96fae9493d5d58f046e01c983a3c4267090eBrian *imgFilter = sampler->mag_img_filter; 60208c9534107fcaf06f9b801551524ed5dc724db13Brian } 60308c9534107fcaf06f9b801551524ed5dc724db13Brian else { 6040b9e96fae9493d5d58f046e01c983a3c4267090eBrian *imgFilter = sampler->min_img_filter; 60508c9534107fcaf06f9b801551524ed5dc724db13Brian } 60608c9534107fcaf06f9b801551524ed5dc724db13Brian } 6073b2a291888d8e62787de03f8529806fb562bd186Brian else { 6080b9e96fae9493d5d58f046e01c983a3c4267090eBrian *imgFilter = sampler->mag_img_filter; 6093b2a291888d8e62787de03f8529806fb562bd186Brian } 610c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian } 611c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian else { 612c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian float lambda; 613c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian 614c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian if (1) 615c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* fragment shader */ 6160b9e96fae9493d5d58f046e01c983a3c4267090eBrian lambda = compute_lambda(texture, sampler, s, t, p, lodbias); 617c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian else 618c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* vertex shader */ 619c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian lambda = lodbias; /* not really a bias, but absolute LOD */ 620c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian 6213b2a291888d8e62787de03f8529806fb562bd186Brian if (lambda <= 0.0) { /* XXX threshold depends on the filter */ 622c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* magnifying */ 6230b9e96fae9493d5d58f046e01c983a3c4267090eBrian *imgFilter = sampler->mag_img_filter; 6244da1cdf78fa3b954840650fa46cf72da5daf149fBrian *level0 = *level1 = 0; 625f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 626c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian else { 627c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* minifying */ 6280b9e96fae9493d5d58f046e01c983a3c4267090eBrian *imgFilter = sampler->min_img_filter; 629c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian 630c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* choose mipmap level(s) and compute the blend factor between them */ 6310b9e96fae9493d5d58f046e01c983a3c4267090eBrian if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NEAREST) { 632c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* Nearest mipmap level */ 633c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian const int lvl = (int) (lambda + 0.5); 634c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian *level0 = 6350b9e96fae9493d5d58f046e01c983a3c4267090eBrian *level1 = CLAMP(lvl, 0, (int) texture->last_level); 636c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian } 637c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian else { 638c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian /* Linear interpolation between mipmap levels */ 639c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian const int lvl = (int) lambda; 6400b9e96fae9493d5d58f046e01c983a3c4267090eBrian *level0 = CLAMP(lvl, 0, (int) texture->last_level); 6410b9e96fae9493d5d58f046e01c983a3c4267090eBrian *level1 = CLAMP(lvl + 1, 0, (int) texture->last_level); 642c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian *levelBlend = FRAC(lambda); /* blending weight between levels */ 643c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian } 644f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 64509a1b912605ff48c8782dcc5aae55ac77e27037bBrian } 64609a1b912605ff48c8782dcc5aae55ac77e27037bBrian} 64709a1b912605ff48c8782dcc5aae55ac77e27037bBrian 64808f33a025100dea2d951e6d628891fe294b18082Brian 649b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/** 650a13de2464dd034ff117f9314df5757d068cae8e5Brian * Get a texel from a texture, using the texture tile cache. 651a13de2464dd034ff117f9314df5757d068cae8e5Brian * 652b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param face the cube face in 0..5 653b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param level the mipmap level 654b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param x the x coord of texel within 2D image 655b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param y the y coord of texel within 2D image 65670eb7996f265f3634dabda078f13d1be3533cc65Brian * \param z which slice of a 3D texture 657b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param rgba the quad to put the texel/color into 658b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian * \param j which element of the rgba quad to write to 65970eb7996f265f3634dabda078f13d1be3533cc65Brian * 66070eb7996f265f3634dabda078f13d1be3533cc65Brian * XXX maybe move this into sp_tile_cache.c and merge with the 66170eb7996f265f3634dabda078f13d1be3533cc65Brian * sp_get_cached_tile_tex() function. Also, get 4 texels instead of 1... 662b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian */ 663b4480285ed5098f1c862690ee105dd46f5e6cd1eBrianstatic void 664dd55083ac1c13723dba6be71f161e2ca7cac7c66Brianget_texel(const struct tgsi_sampler *tgsi_sampler, 66570eb7996f265f3634dabda078f13d1be3533cc65Brian unsigned face, unsigned level, int x, int y, int z, 666a13de2464dd034ff117f9314df5757d068cae8e5Brian float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j) 667b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian{ 6680b9e96fae9493d5d58f046e01c983a3c4267090eBrian const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); 6690b9e96fae9493d5d58f046e01c983a3c4267090eBrian const struct softpipe_context *sp = samp->sp; 6700b9e96fae9493d5d58f046e01c983a3c4267090eBrian const uint unit = samp->unit; 6710b9e96fae9493d5d58f046e01c983a3c4267090eBrian const struct pipe_texture *texture = sp->texture[unit]; 6720b9e96fae9493d5d58f046e01c983a3c4267090eBrian const struct pipe_sampler_state *sampler = sp->sampler[unit]; 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 { 683ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul const int tx = x % TILE_SIZE; 684ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul const int ty = y % TILE_SIZE; 685ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul const struct softpipe_cached_tile *tile 6860b9e96fae9493d5d58f046e01c983a3c4267090eBrian = sp_get_cached_tile_tex(samp->sp, samp->cache, 687ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul x, y, z, face, level); 688ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul rgba[0][j] = tile->data.color[ty][tx][0]; 689ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul rgba[1][j] = tile->data.color[ty][tx][1]; 690ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul rgba[2][j] = tile->data.color[ty][tx][2]; 691ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul rgba[3][j] = tile->data.color[ty][tx][3]; 692b1ff7dac537947d412bf423a73e7eacd76f90d84Brian Paul if (0) 693b1ff7dac537947d412bf423a73e7eacd76f90d84Brian Paul { 694ae2195caf56d2eb782475254c68858a25ee7c857Brian Paul debug_printf("Get texel %f %f %f %f from %s\n", 6958fb55dab783f2de5111e7440093e1458fce5fb3dBrian Paul rgba[0][j], rgba[1][j], rgba[2][j], rgba[3][j], 6960b9e96fae9493d5d58f046e01c983a3c4267090eBrian pf_name(texture->format)); 697b1ff7dac537947d412bf423a73e7eacd76f90d84Brian Paul } 698ea0007cc4ca077c7e3951c4fda122bd242728d70Brian Paul } 699b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian} 700b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 701b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 7023d8c05f7320151898dd224c1daaf3118e1f7ea34Brian/** 7033d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * Compare texcoord 'p' (aka R) against texture value 'rgba[0]' 7043d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * When we sampled the depth texture, the depth value was put into all 7053d8c05f7320151898dd224c1daaf3118e1f7ea34Brian * RGBA channels. We look at the red channel here. 7063d8c05f7320151898dd224c1daaf3118e1f7ea34Brian */ 7073d8c05f7320151898dd224c1daaf3118e1f7ea34Brianstatic INLINE void 7083d8c05f7320151898dd224c1daaf3118e1f7ea34Brianshadow_compare(uint compare_func, 7093d8c05f7320151898dd224c1daaf3118e1f7ea34Brian float rgba[NUM_CHANNELS][QUAD_SIZE], 7103d8c05f7320151898dd224c1daaf3118e1f7ea34Brian const float p[QUAD_SIZE], 7113d8c05f7320151898dd224c1daaf3118e1f7ea34Brian uint j) 7123d8c05f7320151898dd224c1daaf3118e1f7ea34Brian{ 7133d8c05f7320151898dd224c1daaf3118e1f7ea34Brian int k; 7143d8c05f7320151898dd224c1daaf3118e1f7ea34Brian switch (compare_func) { 7153d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_LESS: 7163d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] < rgba[0][j]; 7173d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 7183d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_LEQUAL: 7193d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] <= rgba[0][j]; 7203d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 7213d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_GREATER: 7223d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] > rgba[0][j]; 7233d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 7243d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_GEQUAL: 7253d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] >= rgba[0][j]; 7263d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 7273d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_EQUAL: 7283d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] == rgba[0][j]; 7293d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 7303d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_NOTEQUAL: 7313d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = p[j] != rgba[0][j]; 7323d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 7333d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_ALWAYS: 7343d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = 1; 7353d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 7363d8c05f7320151898dd224c1daaf3118e1f7ea34Brian case PIPE_FUNC_NEVER: 7373d8c05f7320151898dd224c1daaf3118e1f7ea34Brian k = 0; 7383d8c05f7320151898dd224c1daaf3118e1f7ea34Brian break; 7393d8c05f7320151898dd224c1daaf3118e1f7ea34Brian default: 740f9b1d47d652778012fd35552ffc51717ac0b6f79Keith Whitwell k = 0; 7413d8c05f7320151898dd224c1daaf3118e1f7ea34Brian assert(0); 742f9b1d47d652778012fd35552ffc51717ac0b6f79Keith Whitwell break; 7433d8c05f7320151898dd224c1daaf3118e1f7ea34Brian } 7443d8c05f7320151898dd224c1daaf3118e1f7ea34Brian 7453d8c05f7320151898dd224c1daaf3118e1f7ea34Brian rgba[0][j] = rgba[1][j] = rgba[2][j] = (float) k; 7463d8c05f7320151898dd224c1daaf3118e1f7ea34Brian} 7473d8c05f7320151898dd224c1daaf3118e1f7ea34Brian 748b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian 749b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian/** 750a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Common code for sampling 1D/2D/cube textures. 751a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Could probably extend for 3D... 7520dc4eea64f56cc93e5359372b08b99a2d600273cBrian */ 753e12810d92ffb3547680b227bf88937c03018112bBrianstatic void 754dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler, 755a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float s[QUAD_SIZE], 756a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float t[QUAD_SIZE], 757a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float p[QUAD_SIZE], 758a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float lodbias, 759a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float rgba[NUM_CHANNELS][QUAD_SIZE], 760a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const unsigned faces[4]) 7610dc4eea64f56cc93e5359372b08b99a2d600273cBrian{ 7620b9e96fae9493d5d58f046e01c983a3c4267090eBrian const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); 7630b9e96fae9493d5d58f046e01c983a3c4267090eBrian const struct softpipe_context *sp = samp->sp; 7640b9e96fae9493d5d58f046e01c983a3c4267090eBrian const uint unit = samp->unit; 7650b9e96fae9493d5d58f046e01c983a3c4267090eBrian const struct pipe_texture *texture = sp->texture[unit]; 7660b9e96fae9493d5d58f046e01c983a3c4267090eBrian const struct pipe_sampler_state *sampler = sp->sampler[unit]; 7670b9e96fae9493d5d58f046e01c983a3c4267090eBrian const uint compare_func = sampler->compare_func; 768f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian unsigned level0, level1, j, imgFilter; 769f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian int width, height; 770c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian float levelBlend; 771a34b8594b7b2d00404bb639621ec1ce918ba0786Brian 7720b9e96fae9493d5d58f046e01c983a3c4267090eBrian choose_mipmap_levels(texture, sampler, s, t, p, lodbias, 773c7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6Brian &level0, &level1, &levelBlend, &imgFilter); 77409a1b912605ff48c8782dcc5aae55ac77e27037bBrian 7750b9e96fae9493d5d58f046e01c983a3c4267090eBrian assert(sampler->normalized_coords); 776b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 7770b9e96fae9493d5d58f046e01c983a3c4267090eBrian width = texture->width[level0]; 7780b9e96fae9493d5d58f046e01c983a3c4267090eBrian height = texture->height[level0]; 77909a1b912605ff48c8782dcc5aae55ac77e27037bBrian 780b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian assert(width > 0); 781612cfb749c3526eeb446bbc631bf24716522f373Brian 782b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian switch (imgFilter) { 7830dc4eea64f56cc93e5359372b08b99a2d600273cBrian case PIPE_TEX_FILTER_NEAREST: 78438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian { 78538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int x[4], y[4]; 78638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian nearest_texcoord_4(sampler->wrap_s, s, width, x); 78738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian nearest_texcoord_4(sampler->wrap_t, t, height, y); 78838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian 78938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (j = 0; j < QUAD_SIZE; j++) { 79038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, faces[j], level0, x[j], y[j], 0, rgba, j); 79138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { 79238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian shadow_compare(compare_func, rgba, p, j); 7933d8c05f7320151898dd224c1daaf3118e1f7ea34Brian } 7943d8c05f7320151898dd224c1daaf3118e1f7ea34Brian 79538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (level0 != level1) { 79638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian /* get texels from second mipmap level and blend */ 79738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float rgba2[4][4]; 79838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian unsigned c; 79938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian x[j] /= 2; 80038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian y[j] /= 2; 80138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, faces[j], level1, x[j], y[j], 0, 80238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian rgba2, j); 80338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){ 80438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian shadow_compare(compare_func, rgba2, p, j); 80538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 80638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian 80738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (c = 0; c < NUM_CHANNELS; c++) { 80838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]); 80938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 810f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 811f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 8120dc4eea64f56cc93e5359372b08b99a2d600273cBrian } 8130dc4eea64f56cc93e5359372b08b99a2d600273cBrian break; 8140dc4eea64f56cc93e5359372b08b99a2d600273cBrian case PIPE_TEX_FILTER_LINEAR: 81598ae83d5cc73b61826823c915b5c59746c2e85c7Keith Whitwell case PIPE_TEX_FILTER_ANISO: 81638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian { 81738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int x0[4], y0[4], x1[4], y1[4]; 81838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float xw[4], yw[4]; /* weights */ 81938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian 82038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian linear_texcoord_4(sampler->wrap_s, s, width, x0, x1, xw); 82138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian linear_texcoord_4(sampler->wrap_t, t, height, y0, y1, yw); 82238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian 82338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (j = 0; j < QUAD_SIZE; j++) { 82438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float tx[4][4]; /* texels */ 82538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int c; 82638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, faces[j], level0, x0[j], y0[j], 0, tx, 0); 82738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, faces[j], level0, x1[j], y0[j], 0, tx, 1); 82838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, faces[j], level0, x0[j], y1[j], 0, tx, 2); 82938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, faces[j], level0, x1[j], y1[j], 0, tx, 3); 83038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { 8313d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, tx, p, 0); 8323d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, tx, p, 1); 8333d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, tx, p, 2); 8343d8c05f7320151898dd224c1daaf3118e1f7ea34Brian shadow_compare(compare_func, tx, p, 3); 8353d8c05f7320151898dd224c1daaf3118e1f7ea34Brian } 8363d8c05f7320151898dd224c1daaf3118e1f7ea34Brian 83738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian /* interpolate R, G, B, A */ 838f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian for (c = 0; c < 4; c++) { 83938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian rgba[c][j] = lerp_2d(xw[j], yw[j], 84038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian tx[c][0], tx[c][1], 84138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian tx[c][2], tx[c][3]); 842f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 843f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian 84438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (level0 != level1) { 84538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian /* get texels from second mipmap level and blend */ 84638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float rgba2[4][4]; 84738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian x0[j] /= 2; 84838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian y0[j] /= 2; 84938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian x1[j] /= 2; 85038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian y1[j] /= 2; 85138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, faces[j], level1, x0[j], y0[j], 0, tx, 0); 85238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, faces[j], level1, x1[j], y0[j], 0, tx, 1); 85338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, faces[j], level1, x0[j], y1[j], 0, tx, 2); 85438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, faces[j], level1, x1[j], y1[j], 0, tx, 3); 85538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){ 85638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian shadow_compare(compare_func, tx, p, 0); 85738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian shadow_compare(compare_func, tx, p, 1); 85838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian shadow_compare(compare_func, tx, p, 2); 85938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian shadow_compare(compare_func, tx, p, 3); 86038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 86138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian 86238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian /* interpolate R, G, B, A */ 86338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (c = 0; c < 4; c++) { 86438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian rgba2[c][j] = lerp_2d(xw[j], yw[j], 86538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian tx[c][0], tx[c][1], tx[c][2], tx[c][3]); 86638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 86738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian 86838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (c = 0; c < NUM_CHANNELS; c++) { 86938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]); 87038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 871f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 872f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian } 87309a1b912605ff48c8782dcc5aae55ac77e27037bBrian } 87409a1b912605ff48c8782dcc5aae55ac77e27037bBrian break; 8750dc4eea64f56cc93e5359372b08b99a2d600273cBrian default: 8760dc4eea64f56cc93e5359372b08b99a2d600273cBrian assert(0); 8770dc4eea64f56cc93e5359372b08b99a2d600273cBrian } 8780dc4eea64f56cc93e5359372b08b99a2d600273cBrian} 87934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 88034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 881dd55083ac1c13723dba6be71f161e2ca7cac7c66Brianstatic INLINE void 882dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_1d(const struct tgsi_sampler *sampler, 883a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float s[QUAD_SIZE], 884a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float t[QUAD_SIZE], 885a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float p[QUAD_SIZE], 886a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float lodbias, 887a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float rgba[NUM_CHANNELS][QUAD_SIZE]) 888a34b8594b7b2d00404bb639621ec1ce918ba0786Brian{ 889a34b8594b7b2d00404bb639621ec1ce918ba0786Brian static const unsigned faces[4] = {0, 0, 0, 0}; 890d16b4bc32a731cb6ae320e8c187af3bc751d4138Brian static const float tzero[4] = {0, 0, 0, 0}; 891d16b4bc32a731cb6ae320e8c187af3bc751d4138Brian sp_get_samples_2d_common(sampler, s, tzero, NULL, lodbias, rgba, faces); 892a34b8594b7b2d00404bb639621ec1ce918ba0786Brian} 893a34b8594b7b2d00404bb639621ec1ce918ba0786Brian 894a34b8594b7b2d00404bb639621ec1ce918ba0786Brian 895dd55083ac1c13723dba6be71f161e2ca7cac7c66Brianstatic INLINE void 896dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_2d(const struct tgsi_sampler *sampler, 897a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float s[QUAD_SIZE], 898a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float t[QUAD_SIZE], 899a34b8594b7b2d00404bb639621ec1ce918ba0786Brian const float p[QUAD_SIZE], 900a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float lodbias, 901a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float rgba[NUM_CHANNELS][QUAD_SIZE]) 902a34b8594b7b2d00404bb639621ec1ce918ba0786Brian{ 903a34b8594b7b2d00404bb639621ec1ce918ba0786Brian static const unsigned faces[4] = {0, 0, 0, 0}; 9043d8c05f7320151898dd224c1daaf3118e1f7ea34Brian sp_get_samples_2d_common(sampler, s, t, p, lodbias, rgba, faces); 905a34b8594b7b2d00404bb639621ec1ce918ba0786Brian} 906a34b8594b7b2d00404bb639621ec1ce918ba0786Brian 907a34b8594b7b2d00404bb639621ec1ce918ba0786Brian 908dd55083ac1c13723dba6be71f161e2ca7cac7c66Brianstatic INLINE void 909dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_3d(const struct tgsi_sampler *tgsi_sampler, 910b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float s[QUAD_SIZE], 911b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float t[QUAD_SIZE], 912b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float p[QUAD_SIZE], 913f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian float lodbias, 914b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float rgba[NUM_CHANNELS][QUAD_SIZE]) 91534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{ 9160b9e96fae9493d5d58f046e01c983a3c4267090eBrian const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); 9170b9e96fae9493d5d58f046e01c983a3c4267090eBrian const struct softpipe_context *sp = samp->sp; 9180b9e96fae9493d5d58f046e01c983a3c4267090eBrian const uint unit = samp->unit; 9190b9e96fae9493d5d58f046e01c983a3c4267090eBrian const struct pipe_texture *texture = sp->texture[unit]; 9200b9e96fae9493d5d58f046e01c983a3c4267090eBrian const struct pipe_sampler_state *sampler = sp->sampler[unit]; 92134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian /* get/map pipe_surfaces corresponding to 3D tex slices */ 9223d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian unsigned level0, level1, j, imgFilter; 9233d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian int width, height, depth; 9243d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian float levelBlend; 9253d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian const uint face = 0; 9263d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 9270b9e96fae9493d5d58f046e01c983a3c4267090eBrian choose_mipmap_levels(texture, sampler, s, t, p, lodbias, 9283d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian &level0, &level1, &levelBlend, &imgFilter); 9293d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 9300b9e96fae9493d5d58f046e01c983a3c4267090eBrian assert(sampler->normalized_coords); 931b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 9320b9e96fae9493d5d58f046e01c983a3c4267090eBrian width = texture->width[level0]; 9330b9e96fae9493d5d58f046e01c983a3c4267090eBrian height = texture->height[level0]; 9340b9e96fae9493d5d58f046e01c983a3c4267090eBrian depth = texture->depth[level0]; 9353d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 9363d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian assert(width > 0); 9373d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian assert(height > 0); 9383d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian assert(depth > 0); 9393d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 9403d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian switch (imgFilter) { 9413d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian case PIPE_TEX_FILTER_NEAREST: 94238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian { 94338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int x[4], y[4], z[4]; 94438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian nearest_texcoord_4(sampler->wrap_s, s, width, x); 94538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian nearest_texcoord_4(sampler->wrap_t, t, height, y); 94638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian nearest_texcoord_4(sampler->wrap_r, p, depth, z); 94738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (j = 0; j < QUAD_SIZE; j++) { 94838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level0, x[j], y[j], z[j], rgba, j); 94938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (level0 != level1) { 95038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian /* get texels from second mipmap level and blend */ 95138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float rgba2[4][4]; 95238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian unsigned c; 95338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian x[j] /= 2; 95438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian y[j] /= 2; 95538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian z[j] /= 2; 95638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level1, x[j], y[j], z[j], rgba2, j); 95738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (c = 0; c < NUM_CHANNELS; c++) { 95838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian rgba[c][j] = lerp(levelBlend, rgba2[c][j], rgba[c][j]); 95938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 9603d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 9613d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 9623d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 9633d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian break; 9643d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian case PIPE_TEX_FILTER_LINEAR: 96598ae83d5cc73b61826823c915b5c59746c2e85c7Keith Whitwell case PIPE_TEX_FILTER_ANISO: 96638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian { 96738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int x0[4], x1[4], y0[4], y1[4], z0[4], z1[4]; 96838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float xw[4], yw[4], zw[4]; /* interpolation weights */ 96938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian linear_texcoord_4(sampler->wrap_s, s, width, x0, x1, xw); 97038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian linear_texcoord_4(sampler->wrap_t, t, height, y0, y1, yw); 97138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian linear_texcoord_4(sampler->wrap_r, p, depth, z0, z1, zw); 97238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian 97338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (j = 0; j < QUAD_SIZE; j++) { 97438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int c; 97538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float tx0[4][4], tx1[4][4]; 97638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level0, x0[j], y0[j], z0[j], tx0, 0); 97738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level0, x1[j], y0[j], z0[j], tx0, 1); 97838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level0, x0[j], y1[j], z0[j], tx0, 2); 97938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level0, x1[j], y1[j], z0[j], tx0, 3); 98038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level0, x0[j], y0[j], z1[j], tx1, 0); 98138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level0, x1[j], y0[j], z1[j], tx1, 1); 98238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level0, x0[j], y1[j], z1[j], tx1, 2); 98338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level0, x1[j], y1[j], z1[j], tx1, 3); 98438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian 98538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian /* interpolate R, G, B, A */ 9863d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian for (c = 0; c < 4; c++) { 98738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian rgba[c][j] = lerp_3d(xw[j], yw[j], zw[j], 98838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian tx0[c][0], tx0[c][1], 98938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian tx0[c][2], tx0[c][3], 99038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian tx1[c][0], tx1[c][1], 99138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian tx1[c][2], tx1[c][3]); 9923d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 9933d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian 99438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (level0 != level1) { 99538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian /* get texels from second mipmap level and blend */ 99638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float rgba2[4][4]; 99738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian x0[j] /= 2; 99838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian y0[j] /= 2; 99938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian z0[j] /= 2; 100038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian x1[j] /= 2; 100138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian y1[j] /= 2; 100238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian z1[j] /= 2; 100338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level1, x0[j], y0[j], z0[j], tx0, 0); 100438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level1, x1[j], y0[j], z0[j], tx0, 1); 100538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level1, x0[j], y1[j], z0[j], tx0, 2); 100638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level1, x1[j], y1[j], z0[j], tx0, 3); 100738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level1, x0[j], y0[j], z1[j], tx1, 0); 100838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level1, x1[j], y0[j], z1[j], tx1, 1); 100938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level1, x0[j], y1[j], z1[j], tx1, 2); 101038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level1, x1[j], y1[j], z1[j], tx1, 3); 101138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian 101238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian /* interpolate R, G, B, A */ 101338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (c = 0; c < 4; c++) { 101438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian rgba2[c][j] = lerp_3d(xw[j], yw[j], zw[j], 101538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian tx0[c][0], tx0[c][1], 101638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian tx0[c][2], tx0[c][3], 101738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian tx1[c][0], tx1[c][1], 101838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian tx1[c][2], tx1[c][3]); 101938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 102038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian 102138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian /* blend mipmap levels */ 102238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (c = 0; c < NUM_CHANNELS; c++) { 102338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]); 102438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 10253d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 10263d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 10273d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 10283d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian break; 10293d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian default: 10303d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian assert(0); 10313d6f9d904f07b7676cc971eb3faf9dd8e7c58e50Brian } 103234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian} 103334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 103434a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 103534a48abd5ff82ce9748fc29191e35a0985d47c5fBrianstatic void 1036dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_cube(const struct tgsi_sampler *sampler, 1037b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float s[QUAD_SIZE], 1038b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float t[QUAD_SIZE], 1039b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float p[QUAD_SIZE], 1040f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian float lodbias, 1041b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float rgba[NUM_CHANNELS][QUAD_SIZE]) 104234a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{ 1043a34b8594b7b2d00404bb639621ec1ce918ba0786Brian unsigned faces[QUAD_SIZE], j; 1044a34b8594b7b2d00404bb639621ec1ce918ba0786Brian float ssss[4], tttt[4]; 1045b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian for (j = 0; j < QUAD_SIZE; j++) { 1046a34b8594b7b2d00404bb639621ec1ce918ba0786Brian faces[j] = choose_cube_face(s[j], t[j], p[j], ssss + j, tttt + j); 1047b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian } 1048a34b8594b7b2d00404bb639621ec1ce918ba0786Brian sp_get_samples_2d_common(sampler, ssss, tttt, NULL, lodbias, rgba, faces); 104934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian} 105034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 105134a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 1052b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrianstatic void 1053dd55083ac1c13723dba6be71f161e2ca7cac7c66Briansp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler, 1054b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian const float s[QUAD_SIZE], 1055b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian const float t[QUAD_SIZE], 1056b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian const float p[QUAD_SIZE], 1057b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian float lodbias, 1058b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian float rgba[NUM_CHANNELS][QUAD_SIZE]) 1059b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian{ 10600b9e96fae9493d5d58f046e01c983a3c4267090eBrian const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); 10610b9e96fae9493d5d58f046e01c983a3c4267090eBrian const struct softpipe_context *sp = samp->sp; 10620b9e96fae9493d5d58f046e01c983a3c4267090eBrian const uint unit = samp->unit; 10630b9e96fae9493d5d58f046e01c983a3c4267090eBrian const struct pipe_texture *texture = sp->texture[unit]; 10640b9e96fae9493d5d58f046e01c983a3c4267090eBrian const struct pipe_sampler_state *sampler = sp->sampler[unit]; 1065b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian //sp_get_samples_2d_common(sampler, s, t, p, lodbias, rgba, faces); 1066b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian static const uint face = 0; 10670b9e96fae9493d5d58f046e01c983a3c4267090eBrian const uint compare_func = sampler->compare_func; 1068b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian unsigned level0, level1, j, imgFilter; 1069b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian int width, height; 1070b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian float levelBlend; 1071b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 10720b9e96fae9493d5d58f046e01c983a3c4267090eBrian choose_mipmap_levels(texture, sampler, s, t, p, lodbias, 1073b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian &level0, &level1, &levelBlend, &imgFilter); 1074b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 1075b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian /* texture RECTS cannot be mipmapped */ 1076b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(level0 == level1); 1077b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 10780b9e96fae9493d5d58f046e01c983a3c4267090eBrian width = texture->width[level0]; 10790b9e96fae9493d5d58f046e01c983a3c4267090eBrian height = texture->height[level0]; 1080b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 1081b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(width > 0); 1082b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 1083b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian switch (imgFilter) { 1084b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_FILTER_NEAREST: 108538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian { 108638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int x[4], y[4]; 108738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian nearest_texcoord_unnorm_4(sampler->wrap_s, s, width, x); 108838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian nearest_texcoord_unnorm_4(sampler->wrap_t, t, height, y); 108938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (j = 0; j < QUAD_SIZE; j++) { 109038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level0, x[j], y[j], 0, rgba, j); 109138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { 109238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian shadow_compare(compare_func, rgba, p, j); 109338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 1094b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 1095b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 1096b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian break; 1097b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian case PIPE_TEX_FILTER_LINEAR: 109898ae83d5cc73b61826823c915b5c59746c2e85c7Keith Whitwell case PIPE_TEX_FILTER_ANISO: 109938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian { 110038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int x0[4], y0[4], x1[4], y1[4]; 110138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float xw[4], yw[4]; /* weights */ 110238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian linear_texcoord_unnorm_4(sampler->wrap_s, s, width, x0, x1, xw); 110338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian linear_texcoord_unnorm_4(sampler->wrap_t, t, height, y0, y1, yw); 110438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (j = 0; j < QUAD_SIZE; j++) { 110538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian float tx[4][4]; /* texels */ 110638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian int c; 110738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level0, x0[j], y0[j], 0, tx, 0); 110838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level0, x1[j], y0[j], 0, tx, 1); 110938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level0, x0[j], y1[j], 0, tx, 2); 111038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian get_texel(tgsi_sampler, face, level0, x1[j], y1[j], 0, tx, 3); 111138bee46e83b18ff4ad42d340b507b1a15b4326c7Brian if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { 111238bee46e83b18ff4ad42d340b507b1a15b4326c7Brian shadow_compare(compare_func, tx, p, 0); 111338bee46e83b18ff4ad42d340b507b1a15b4326c7Brian shadow_compare(compare_func, tx, p, 1); 111438bee46e83b18ff4ad42d340b507b1a15b4326c7Brian shadow_compare(compare_func, tx, p, 2); 111538bee46e83b18ff4ad42d340b507b1a15b4326c7Brian shadow_compare(compare_func, tx, p, 3); 111638bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 111738bee46e83b18ff4ad42d340b507b1a15b4326c7Brian for (c = 0; c < 4; c++) { 111838bee46e83b18ff4ad42d340b507b1a15b4326c7Brian rgba[c][j] = lerp_2d(xw[j], yw[j], 111938bee46e83b18ff4ad42d340b507b1a15b4326c7Brian tx[c][0], tx[c][1], tx[c][2], tx[c][3]); 112038bee46e83b18ff4ad42d340b507b1a15b4326c7Brian } 1121b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 1122b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 1123b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian break; 1124b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian default: 1125b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian assert(0); 1126b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian } 1127b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian} 1128b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 1129b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian 1130a34b8594b7b2d00404bb639621ec1ce918ba0786Brian/** 1131a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Called via tgsi_sampler::get_samples() 1132a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * Use the sampler's state setting to get a filtered RGBA value 1133753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer * from the sampler's texture. 1134a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * 1135a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * XXX we can implement many versions of this function, each 1136a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * tightly coded for a specific combination of sampler state 1137a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * (nearest + repeat), (bilinear mipmap + clamp), etc. 1138a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * 1139a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * The update_samplers() function in st_atom_sampler.c could create 1140a34b8594b7b2d00404bb639621ec1ce918ba0786Brian * a new tgsi_sampler object for each state combo it finds.... 1141a34b8594b7b2d00404bb639621ec1ce918ba0786Brian */ 114234a48abd5ff82ce9748fc29191e35a0985d47c5fBrianvoid 11430b9e96fae9493d5d58f046e01c983a3c4267090eBriansp_get_samples(struct tgsi_sampler *tgsi_sampler, 1144b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float s[QUAD_SIZE], 1145b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float t[QUAD_SIZE], 1146b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian const float p[QUAD_SIZE], 1147f9e331a574cc4eba60e0de5a29a4aed4bb40520cBrian float lodbias, 1148b4480285ed5098f1c862690ee105dd46f5e6cd1eBrian float rgba[NUM_CHANNELS][QUAD_SIZE]) 114934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian{ 11500b9e96fae9493d5d58f046e01c983a3c4267090eBrian const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); 11510b9e96fae9493d5d58f046e01c983a3c4267090eBrian const struct softpipe_context *sp = samp->sp; 11520b9e96fae9493d5d58f046e01c983a3c4267090eBrian const uint unit = samp->unit; 11530b9e96fae9493d5d58f046e01c983a3c4267090eBrian const struct pipe_texture *texture = sp->texture[unit]; 11540b9e96fae9493d5d58f046e01c983a3c4267090eBrian const struct pipe_sampler_state *sampler = sp->sampler[unit]; 11550b9e96fae9493d5d58f046e01c983a3c4267090eBrian 11560b9e96fae9493d5d58f046e01c983a3c4267090eBrian if (!texture) 11574f23468bd0d14b8ed687a641003d587b91ad39a7Brian return; 11584f23468bd0d14b8ed687a641003d587b91ad39a7Brian 11590b9e96fae9493d5d58f046e01c983a3c4267090eBrian switch (texture->target) { 116070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell case PIPE_TEXTURE_1D: 11610b9e96fae9493d5d58f046e01c983a3c4267090eBrian assert(sampler->normalized_coords); 11620b9e96fae9493d5d58f046e01c983a3c4267090eBrian sp_get_samples_1d(tgsi_sampler, s, t, p, lodbias, rgba); 116334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian break; 116470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell case PIPE_TEXTURE_2D: 11650b9e96fae9493d5d58f046e01c983a3c4267090eBrian if (sampler->normalized_coords) 11660b9e96fae9493d5d58f046e01c983a3c4267090eBrian sp_get_samples_2d(tgsi_sampler, s, t, p, lodbias, rgba); 1167b1c8fa5b6002296d9abe21c06d5cb81a3f70828aBrian else 11680b9e96fae9493d5d58f046e01c983a3c4267090eBrian sp_get_samples_rect(tgsi_sampler, s, t, p, lodbias, rgba); 116934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian break; 117070af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell case PIPE_TEXTURE_3D: 11710b9e96fae9493d5d58f046e01c983a3c4267090eBrian assert(sampler->normalized_coords); 11720b9e96fae9493d5d58f046e01c983a3c4267090eBrian sp_get_samples_3d(tgsi_sampler, s, t, p, lodbias, rgba); 117334a48abd5ff82ce9748fc29191e35a0985d47c5fBrian break; 117470af238b494ed1b6da4841c2065c33ee0f0f37c9Keith Whitwell case PIPE_TEXTURE_CUBE: 11750b9e96fae9493d5d58f046e01c983a3c4267090eBrian assert(sampler->normalized_coords); 11760b9e96fae9493d5d58f046e01c983a3c4267090eBrian sp_get_samples_cube(tgsi_sampler, s, t, p, lodbias, rgba); 117734a48abd5ff82ce9748fc29191e35a0985d47c5fBrian break; 117834a48abd5ff82ce9748fc29191e35a0985d47c5fBrian default: 117934a48abd5ff82ce9748fc29191e35a0985d47c5fBrian assert(0); 118034a48abd5ff82ce9748fc29191e35a0985d47c5fBrian } 11813d53d38d5e35386de4793162b9dd32e171927059Brian Paul 11823d53d38d5e35386de4793162b9dd32e171927059Brian Paul#if 0 /* DEBUG */ 11833d53d38d5e35386de4793162b9dd32e171927059Brian Paul { 11843d53d38d5e35386de4793162b9dd32e171927059Brian Paul int i; 11853d53d38d5e35386de4793162b9dd32e171927059Brian Paul printf("Sampled at %f, %f, %f:\n", s[0], t[0], p[0]); 11863d53d38d5e35386de4793162b9dd32e171927059Brian Paul for (i = 0; i < 4; i++) { 11873d53d38d5e35386de4793162b9dd32e171927059Brian Paul printf("Frag %d: %f %f %f %f\n", i, 11883d53d38d5e35386de4793162b9dd32e171927059Brian Paul rgba[0][i], 11893d53d38d5e35386de4793162b9dd32e171927059Brian Paul rgba[1][i], 11903d53d38d5e35386de4793162b9dd32e171927059Brian Paul rgba[2][i], 11913d53d38d5e35386de4793162b9dd32e171927059Brian Paul rgba[3][i]); 11923d53d38d5e35386de4793162b9dd32e171927059Brian Paul } 11933d53d38d5e35386de4793162b9dd32e171927059Brian Paul } 11943d53d38d5e35386de4793162b9dd32e171927059Brian Paul#endif 119534a48abd5ff82ce9748fc29191e35a0985d47c5fBrian} 119634a48abd5ff82ce9748fc29191e35a0985d47c5fBrian 1197