s_texfilter.c revision 26b8dfc8cadf0f1a8604fc77b226cc7de005f9ca
12cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/* 22cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Mesa 3-D graphics library 3249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian * Version: 7.3 42cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * 5249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 62cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * 72cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Permission is hereby granted, free of charge, to any person obtaining a 82cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * copy of this software and associated documentation files (the "Software"), 92cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * to deal in the Software without restriction, including without limitation 102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * the rights to use, copy, modify, merge, publish, distribute, sublicense, 112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * and/or sell copies of the Software, and to permit persons to whom the 122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Software is furnished to do so, subject to the following conditions: 132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * 142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * The above copyright notice and this permission notice shall be included 152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * in all copies or substantial portions of the Software. 162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * 172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 26bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/glheader.h" 27bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/context.h" 28bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/colormac.h" 29bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/imports.h" 302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#include "s_context.h" 322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#include "s_texfilter.h" 332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 35249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian/* 36249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian * Note, the FRAC macro has to work perfectly. Otherwise you'll sometimes 37249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian * see 1-pixel bands of improperly weighted linear-filtered textures. 38249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian * The tests/texwrap.c demo is a good test. 39249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0. 40249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x). 41249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian */ 42249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian#define FRAC(f) ((f) - IFLOOR(f)) 43249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian 44249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian 452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/** 47bd32640f77c72e79fb5dda0e5fd077e564b33b02Brian Paul * Linear interpolation macro 482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#define LERP(T, A, B) ( (A) + (T) * ((B) - (A)) ) 502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/** 532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Do 2D/biliner interpolation of float values. 542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * v00, v10, v01 and v11 are typically four texture samples in a square/box. 552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * a and b are the horizontal and vertical interpolants. 562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * It's important that this function is inlined when compiled with 572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * optimization! If we find that's not true on some systems, convert 582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * to a macro. 592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 609520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLfloat 612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paullerp_2d(GLfloat a, GLfloat b, 622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLfloat v00, GLfloat v10, GLfloat v01, GLfloat v11) 632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat temp0 = LERP(a, v00, v10); 652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat temp1 = LERP(a, v01, v11); 662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return LERP(b, temp0, temp1); 672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/** 712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Do 3D/trilinear interpolation of float values. 722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * \sa lerp_2d 732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 749520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLfloat 752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paullerp_3d(GLfloat a, GLfloat b, GLfloat c, 762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLfloat v000, GLfloat v100, GLfloat v010, GLfloat v110, 772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLfloat v001, GLfloat v101, GLfloat v011, GLfloat v111) 782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat temp00 = LERP(a, v000, v100); 802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat temp10 = LERP(a, v010, v110); 812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat temp01 = LERP(a, v001, v101); 822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat temp11 = LERP(a, v011, v111); 832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat temp0 = LERP(b, temp00, temp10); 842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat temp1 = LERP(b, temp01, temp11); 852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return LERP(c, temp0, temp1); 862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/** 902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Do linear interpolation of colors. 912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 929520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 93de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paullerp_rgba(GLfloat result[4], GLfloat t, const GLfloat a[4], const GLfloat b[4]) 942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul result[0] = LERP(t, a[0], b[0]); 962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul result[1] = LERP(t, a[1], b[1]); 972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul result[2] = LERP(t, a[2], b[2]); 982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul result[3] = LERP(t, a[3], b[3]); 992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 1002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 1012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 1022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/** 1032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Do bilinear interpolation of colors. 1042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 1059520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 106de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paullerp_rgba_2d(GLfloat result[4], GLfloat a, GLfloat b, 107de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat t00[4], const GLfloat t10[4], 108de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat t01[4], const GLfloat t11[4]) 1092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 1102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul result[0] = lerp_2d(a, b, t00[0], t10[0], t01[0], t11[0]); 1112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul result[1] = lerp_2d(a, b, t00[1], t10[1], t01[1], t11[1]); 1122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul result[2] = lerp_2d(a, b, t00[2], t10[2], t01[2], t11[2]); 1132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul result[3] = lerp_2d(a, b, t00[3], t10[3], t01[3], t11[3]); 1142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 1152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 1162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 1172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/** 1180f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul * Do trilinear interpolation of colors. 1190f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul */ 1209520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 121de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paullerp_rgba_3d(GLfloat result[4], GLfloat a, GLfloat b, GLfloat c, 122de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat t000[4], const GLfloat t100[4], 123de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat t010[4], const GLfloat t110[4], 124de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat t001[4], const GLfloat t101[4], 125de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat t011[4], const GLfloat t111[4]) 1260f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul{ 1270f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul GLuint k; 1280f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul /* compiler should unroll these short loops */ 1290f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul for (k = 0; k < 4; k++) { 1300f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul result[k] = lerp_3d(a, b, c, t000[k], t100[k], t010[k], t110[k], 1310f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul t001[k], t101[k], t011[k], t111[k]); 1320f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 1330f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul} 1340f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul 1350f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul 1360f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul/** 1375ba62cd4139e95c752453a1591eb3e47b6b18238Brian Paul * Used for GL_REPEAT wrap mode. Using A % B doesn't produce the 1385ba62cd4139e95c752453a1591eb3e47b6b18238Brian Paul * right results for A<0. Casting to A to be unsigned only works if B 1395ba62cd4139e95c752453a1591eb3e47b6b18238Brian Paul * is a power of two. Adding a bias to A (which is a multiple of B) 1405ba62cd4139e95c752453a1591eb3e47b6b18238Brian Paul * avoids the problems with A < 0 (for reasonable A) without using a 1415ba62cd4139e95c752453a1591eb3e47b6b18238Brian Paul * conditional. 1422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 143ed7f4b42307bff4633689d6781cd3643f10041e5Brian Paul#define REMAINDER(A, B) (((A) + (B) * 1024) % (B)) 1442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 1452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 1462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/** 1472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Used to compute texel locations for linear sampling. 1482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Input: 1492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * wrapMode = GL_REPEAT, GL_CLAMP, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER 150249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian * s = texcoord in [0,1] 151249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian * size = width (or height or depth) of texture 1522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Output: 153249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian * i0, i1 = returns two nearest texel indexes 154249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian * weight = returns blend factor between texels 1552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 1569520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 157249e1e4d30759cd3c55cef0dba75f531cc7c6269Brianlinear_texel_locations(GLenum wrapMode, 158249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const struct gl_texture_image *img, 159249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian GLint size, GLfloat s, 160249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian GLint *i0, GLint *i1, GLfloat *weight) 161249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian{ 162eaf376ba354db11f7729452060570b48a029c9a0Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 163249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian GLfloat u; 164249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian switch (wrapMode) { 165249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_REPEAT: 166249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = s * size - 0.5F; 167eaf376ba354db11f7729452060570b48a029c9a0Brian Paul if (swImg->_IsPowerOfTwo) { 168249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i0 = IFLOOR(u) & (size - 1); 169249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i1 = (*i0 + 1) & (size - 1); 170249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian } 171249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else { 172249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i0 = REMAINDER(IFLOOR(u), size); 173249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i1 = REMAINDER(*i0 + 1, size); 174249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian } 175249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian break; 176249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_CLAMP_TO_EDGE: 177249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (s <= 0.0F) 178249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = 0.0F; 179249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else if (s >= 1.0F) 180249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = (GLfloat) size; 181249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 182249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = s * size; 183249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u -= 0.5F; 184249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i0 = IFLOOR(u); 185249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i1 = *i0 + 1; 186249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (*i0 < 0) 187249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i0 = 0; 188249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (*i1 >= (GLint) size) 189249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i1 = size - 1; 190249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian break; 191249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_CLAMP_TO_BORDER: 192249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian { 193249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat min = -1.0F / (2.0F * size); 194249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat max = 1.0F - min; 195249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (s <= min) 196249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = min * size; 197249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else if (s >= max) 198249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = max * size; 199249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 200249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = s * size; 201249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u -= 0.5F; 202249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i0 = IFLOOR(u); 203249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i1 = *i0 + 1; 204249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian } 205249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian break; 206249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_MIRRORED_REPEAT: 207249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian { 208249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLint flr = IFLOOR(s); 209249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (flr & 1) 210249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = 1.0F - (s - (GLfloat) flr); 211249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 212249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = s - (GLfloat) flr; 213249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = (u * size) - 0.5F; 214249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i0 = IFLOOR(u); 215249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i1 = *i0 + 1; 216249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (*i0 < 0) 217249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i0 = 0; 218249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (*i1 >= (GLint) size) 219249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i1 = size - 1; 220249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian } 221249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian break; 222249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_MIRROR_CLAMP_EXT: 223249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = FABSF(s); 224249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (u >= 1.0F) 225249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = (GLfloat) size; 226249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 227249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u *= size; 228249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u -= 0.5F; 229249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i0 = IFLOOR(u); 230249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i1 = *i0 + 1; 231249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian break; 232249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_MIRROR_CLAMP_TO_EDGE_EXT: 233249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = FABSF(s); 234249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (u >= 1.0F) 235249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = (GLfloat) size; 236249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 237249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u *= size; 238249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u -= 0.5F; 239249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i0 = IFLOOR(u); 240249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i1 = *i0 + 1; 241249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (*i0 < 0) 242249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i0 = 0; 243249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (*i1 >= (GLint) size) 244249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i1 = size - 1; 245249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian break; 246249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_MIRROR_CLAMP_TO_BORDER_EXT: 247249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian { 248249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat min = -1.0F / (2.0F * size); 249249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat max = 1.0F - min; 250249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = FABSF(s); 251249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (u <= min) 252249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = min * size; 253249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else if (u >= max) 254249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = max * size; 255249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 256249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u *= size; 257249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u -= 0.5F; 258249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i0 = IFLOOR(u); 259249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i1 = *i0 + 1; 260249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian } 261249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian break; 262249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_CLAMP: 263249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (s <= 0.0F) 264249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = 0.0F; 265249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else if (s >= 1.0F) 266249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = (GLfloat) size; 267249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 268249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = s * size; 269249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u -= 0.5F; 270249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i0 = IFLOOR(u); 271249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i1 = *i0 + 1; 272249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian break; 273249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian default: 274249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian _mesa_problem(NULL, "Bad wrap mode"); 275249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = 0.0F; 276249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian } 277249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *weight = FRAC(u); 2782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 2792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 2802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 2812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/** 2822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Used to compute texel location for nearest sampling. 2832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 2849520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLint 285249e1e4d30759cd3c55cef0dba75f531cc7c6269Briannearest_texel_location(GLenum wrapMode, 286249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const struct gl_texture_image *img, 287249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian GLint size, GLfloat s) 288249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian{ 289eaf376ba354db11f7729452060570b48a029c9a0Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 290249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian GLint i; 291249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian 292249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian switch (wrapMode) { 293249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_REPEAT: 294249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian /* s limited to [0,1) */ 295249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian /* i limited to [0,size-1] */ 296249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = IFLOOR(s * size); 297eaf376ba354db11f7729452060570b48a029c9a0Brian Paul if (swImg->_IsPowerOfTwo) 298249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i &= (size - 1); 299249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 300249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = REMAINDER(i, size); 301249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian return i; 302249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_CLAMP_TO_EDGE: 303249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian { 304249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian /* s limited to [min,max] */ 305249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian /* i limited to [0, size-1] */ 306249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat min = 1.0F / (2.0F * size); 307249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat max = 1.0F - min; 308249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (s < min) 309249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = 0; 310249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else if (s > max) 311249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = size - 1; 312249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 313249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = IFLOOR(s * size); 314249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian } 315249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian return i; 316249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_CLAMP_TO_BORDER: 317249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian { 318249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian /* s limited to [min,max] */ 319249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian /* i limited to [-1, size] */ 320249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat min = -1.0F / (2.0F * size); 321249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat max = 1.0F - min; 322249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (s <= min) 323249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = -1; 324249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else if (s >= max) 325249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = size; 326249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 327249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = IFLOOR(s * size); 328249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian } 329249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian return i; 330249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_MIRRORED_REPEAT: 331249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian { 332249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat min = 1.0F / (2.0F * size); 333249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat max = 1.0F - min; 334249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLint flr = IFLOOR(s); 335249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian GLfloat u; 336249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (flr & 1) 337249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = 1.0F - (s - (GLfloat) flr); 338249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 339249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = s - (GLfloat) flr; 340249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (u < min) 341249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = 0; 342249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else if (u > max) 343249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = size - 1; 344249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 345249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = IFLOOR(u * size); 346249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian } 347249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian return i; 348249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_MIRROR_CLAMP_EXT: 349249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian { 350249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian /* s limited to [0,1] */ 351249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian /* i limited to [0,size-1] */ 352249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat u = FABSF(s); 353249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (u <= 0.0F) 354249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = 0; 355249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else if (u >= 1.0F) 356249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = size - 1; 357249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 358249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = IFLOOR(u * size); 359249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian } 360249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian return i; 361249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_MIRROR_CLAMP_TO_EDGE_EXT: 362249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian { 363249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian /* s limited to [min,max] */ 364249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian /* i limited to [0, size-1] */ 365249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat min = 1.0F / (2.0F * size); 366249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat max = 1.0F - min; 367249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat u = FABSF(s); 368249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (u < min) 369249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = 0; 370249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else if (u > max) 371249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = size - 1; 372249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 373249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = IFLOOR(u * size); 374249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian } 375249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian return i; 376249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_MIRROR_CLAMP_TO_BORDER_EXT: 377249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian { 378249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian /* s limited to [min,max] */ 379249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian /* i limited to [0, size-1] */ 380249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat min = -1.0F / (2.0F * size); 381249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat max = 1.0F - min; 382249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat u = FABSF(s); 383249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (u < min) 384249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = -1; 385249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else if (u > max) 386249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = size; 387249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 388249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = IFLOOR(u * size); 389249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian } 390249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian return i; 391249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_CLAMP: 392249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian /* s limited to [0,1] */ 393249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian /* i limited to [0,size-1] */ 394249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (s <= 0.0F) 395249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = 0; 396249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else if (s >= 1.0F) 397249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = size - 1; 398249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 399249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = IFLOOR(s * size); 400249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian return i; 401249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian default: 402249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian _mesa_problem(NULL, "Bad wrap mode"); 403249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian return 0; 404249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian } 4052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 4062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 4072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 4082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/* Power of two image sizes only */ 4099520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 410249e1e4d30759cd3c55cef0dba75f531cc7c6269Brianlinear_repeat_texel_location(GLuint size, GLfloat s, 411249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian GLint *i0, GLint *i1, GLfloat *weight) 412249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian{ 413249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian GLfloat u = s * size - 0.5F; 414249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i0 = IFLOOR(u) & (size - 1); 415249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i1 = (*i0 + 1) & (size - 1); 416249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *weight = FRAC(u); 4172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 4182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 4192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 420792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul/** 421a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul * Do clamp/wrap for a texture rectangle coord, GL_NEAREST filter mode. 422a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul */ 4239520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLint 424a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paulclamp_rect_coord_nearest(GLenum wrapMode, GLfloat coord, GLint max) 425a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul{ 426a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul switch (wrapMode) { 427a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_CLAMP: 428a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return IFLOOR( CLAMP(coord, 0.0F, max - 1) ); 429a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_CLAMP_TO_EDGE: 430a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return IFLOOR( CLAMP(coord, 0.5F, max - 0.5F) ); 431a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_CLAMP_TO_BORDER: 432a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return IFLOOR( CLAMP(coord, -0.5F, max + 0.5F) ); 433a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul default: 434a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul _mesa_problem(NULL, "bad wrapMode in clamp_rect_coord_nearest"); 435a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return 0; 436a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul } 437a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul} 438a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 439a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 440a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul/** 441a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul * As above, but GL_LINEAR filtering. 442a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul */ 4439520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 444a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paulclamp_rect_coord_linear(GLenum wrapMode, GLfloat coord, GLint max, 445a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul GLint *i0out, GLint *i1out, GLfloat *weight) 446a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul{ 447a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul GLfloat fcol; 448a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul GLint i0, i1; 449a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul switch (wrapMode) { 450a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_CLAMP: 451a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul /* Not exactly what the spec says, but it matches NVIDIA output */ 452880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul fcol = CLAMP(coord - 0.5F, 0.0F, max - 1); 453a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul i0 = IFLOOR(fcol); 454a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul i1 = i0 + 1; 455a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul break; 456a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_CLAMP_TO_EDGE: 457a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul fcol = CLAMP(coord, 0.5F, max - 0.5F); 458a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul fcol -= 0.5F; 459a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul i0 = IFLOOR(fcol); 460a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul i1 = i0 + 1; 461a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul if (i1 > max - 1) 462a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul i1 = max - 1; 463a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul break; 464a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_CLAMP_TO_BORDER: 465a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul fcol = CLAMP(coord, -0.5F, max + 0.5F); 466a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul fcol -= 0.5F; 467a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul i0 = IFLOOR(fcol); 468a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul i1 = i0 + 1; 469dcf571aff9de1a4298c4d2c4148d84cdc4daf02eBrian Paul break; 470a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul default: 471a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul _mesa_problem(NULL, "bad wrapMode in clamp_rect_coord_linear"); 472a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul i0 = i1 = 0; 473a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul fcol = 0.0F; 474a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul } 475a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul *i0out = i0; 476a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul *i1out = i1; 477a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul *weight = FRAC(fcol); 478a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul} 479a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 480a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 481a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul/** 48258ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul * Compute slice/image to use for 1D or 2D array texture. 48358ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul */ 4849520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLint 48558ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paultex_array_slice(GLfloat coord, GLsizei size) 48658ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul{ 487bdbb5f8170f48713b741ad68c26464231a01ca7aBrian Paul GLint slice = IFLOOR(coord + 0.5f); 48858ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul slice = CLAMP(slice, 0, size - 1); 48958ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul return slice; 49058ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul} 49158ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul 49258ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul 49358ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul/** 494a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul * Compute nearest integer texcoords for given texobj and coordinate. 4952b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul * NOTE: only used for depth texture sampling. 496a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul */ 4979520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 498a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paulnearest_texcoord(const struct gl_texture_object *texObj, 4992b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul GLuint level, 500a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul const GLfloat texcoord[4], 501a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul GLint *i, GLint *j, GLint *k) 502a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul{ 5032b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul const struct gl_texture_image *img = texObj->Image[0][level]; 504a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul const GLint width = img->Width; 505a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul const GLint height = img->Height; 506a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul const GLint depth = img->Depth; 507a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 508a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul switch (texObj->Target) { 509a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_TEXTURE_RECTANGLE_ARB: 510ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul *i = clamp_rect_coord_nearest(texObj->Sampler.WrapS, texcoord[0], width); 511ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul *j = clamp_rect_coord_nearest(texObj->Sampler.WrapT, texcoord[1], height); 512a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul *k = 0; 513a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul break; 514a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_TEXTURE_1D: 515ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul *i = nearest_texel_location(texObj->Sampler.WrapS, img, width, texcoord[0]); 516a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul *j = 0; 517a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul *k = 0; 518a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul break; 519a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_TEXTURE_2D: 520ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul *i = nearest_texel_location(texObj->Sampler.WrapS, img, width, texcoord[0]); 521ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul *j = nearest_texel_location(texObj->Sampler.WrapT, img, height, texcoord[1]); 522a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul *k = 0; 523a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul break; 524a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_TEXTURE_1D_ARRAY_EXT: 525ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul *i = nearest_texel_location(texObj->Sampler.WrapS, img, width, texcoord[0]); 52658ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul *j = tex_array_slice(texcoord[1], height); 527a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul *k = 0; 528a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul break; 529a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_TEXTURE_2D_ARRAY_EXT: 530ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul *i = nearest_texel_location(texObj->Sampler.WrapS, img, width, texcoord[0]); 531ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul *j = nearest_texel_location(texObj->Sampler.WrapT, img, height, texcoord[1]); 53258ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul *k = tex_array_slice(texcoord[2], depth); 533a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul break; 534a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul default: 535a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul *i = *j = *k = 0; 536a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul } 537a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul} 538a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 539a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 540a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul/** 541a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul * Compute linear integer texcoords for given texobj and coordinate. 5422b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul * NOTE: only used for depth texture sampling. 543a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul */ 5449520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 545a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paullinear_texcoord(const struct gl_texture_object *texObj, 5462b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul GLuint level, 547a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul const GLfloat texcoord[4], 548a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul GLint *i0, GLint *i1, GLint *j0, GLint *j1, GLint *slice, 549a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul GLfloat *wi, GLfloat *wj) 550a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul{ 5512b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul const struct gl_texture_image *img = texObj->Image[0][level]; 552a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul const GLint width = img->Width; 553a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul const GLint height = img->Height; 554a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul const GLint depth = img->Depth; 555a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 556a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul switch (texObj->Target) { 557a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_TEXTURE_RECTANGLE_ARB: 558ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul clamp_rect_coord_linear(texObj->Sampler.WrapS, texcoord[0], 559a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul width, i0, i1, wi); 560ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul clamp_rect_coord_linear(texObj->Sampler.WrapT, texcoord[1], 561a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul height, j0, j1, wj); 562a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul *slice = 0; 563a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul break; 564a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 565a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_TEXTURE_1D: 566a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_TEXTURE_2D: 567ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul linear_texel_locations(texObj->Sampler.WrapS, img, width, 568a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul texcoord[0], i0, i1, wi); 569ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul linear_texel_locations(texObj->Sampler.WrapT, img, height, 570a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul texcoord[1], j0, j1, wj); 571a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul *slice = 0; 572a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul break; 573a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 574a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_TEXTURE_1D_ARRAY_EXT: 575ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul linear_texel_locations(texObj->Sampler.WrapS, img, width, 576a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul texcoord[0], i0, i1, wi); 57758ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul *j0 = tex_array_slice(texcoord[1], height); 578a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul *j1 = *j0; 579a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul *slice = 0; 580a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul break; 581a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 582a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_TEXTURE_2D_ARRAY_EXT: 583ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul linear_texel_locations(texObj->Sampler.WrapS, img, width, 584a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul texcoord[0], i0, i1, wi); 585ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul linear_texel_locations(texObj->Sampler.WrapT, img, height, 586a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul texcoord[1], j0, j1, wj); 58758ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul *slice = tex_array_slice(texcoord[2], depth); 588a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul break; 589a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 590a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul default: 591a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul *slice = 0; 592a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul } 593a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul} 594a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 595a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 596a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 597a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul/** 598792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul * For linear interpolation between mipmap levels N and N+1, this function 599792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul * computes N. 6002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 6019520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLint 602792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paullinear_mipmap_level(const struct gl_texture_object *tObj, GLfloat lambda) 603792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul{ 604792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul if (lambda < 0.0F) 605792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul return tObj->BaseLevel; 606792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul else if (lambda > tObj->_MaxLambda) 607792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul return (GLint) (tObj->BaseLevel + tObj->_MaxLambda); 608792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul else 609792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul return (GLint) (tObj->BaseLevel + lambda); 6102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 6112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 6122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 613792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul/** 614792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul * Compute the nearest mipmap level to take texels from. 6152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 6169520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLint 617792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paulnearest_mipmap_level(const struct gl_texture_object *tObj, GLfloat lambda) 618792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul{ 619792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLfloat l; 620792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level; 621792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul if (lambda <= 0.5F) 622792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul l = 0.0F; 623792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul else if (lambda > tObj->_MaxLambda + 0.4999F) 624792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul l = tObj->_MaxLambda + 0.4999F; 625792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul else 626792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul l = lambda; 627792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul level = (GLint) (tObj->BaseLevel + l + 0.5F); 628792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul if (level > tObj->_MaxLevel) 629792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul level = tObj->_MaxLevel; 630792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul return level; 6312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 6322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 6332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 6342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 6352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/* 6362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Bitflags for texture border color sampling. 6372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 6382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#define I0BIT 1 6392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#define I1BIT 2 6402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#define J0BIT 4 6412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#define J1BIT 8 6422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#define K0BIT 16 6432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#define K1BIT 32 6442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 6452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 6462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 6476e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** 6482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * The lambda[] array values are always monotonic. Either the whole span 6492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * will be minified, magnified, or split between the two. This function 6502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * determines the subranges in [0, n-1] that are to be minified or magnified. 6512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 6529520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 653aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paulcompute_min_mag_ranges(const struct gl_texture_object *tObj, 654aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul GLuint n, const GLfloat lambda[], 655aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul GLuint *minStart, GLuint *minEnd, 656aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul GLuint *magStart, GLuint *magEnd) 6572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 658aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul GLfloat minMagThresh; 659aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul 660aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul /* we shouldn't be here if minfilter == magfilter */ 661ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul ASSERT(tObj->Sampler.MinFilter != tObj->Sampler.MagFilter); 662aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul 663aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul /* This bit comes from the OpenGL spec: */ 664ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul if (tObj->Sampler.MagFilter == GL_LINEAR 665ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul && (tObj->Sampler.MinFilter == GL_NEAREST_MIPMAP_NEAREST || 666ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul tObj->Sampler.MinFilter == GL_NEAREST_MIPMAP_LINEAR)) { 667aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul minMagThresh = 0.5F; 668aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul } 669aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul else { 670aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul minMagThresh = 0.0F; 671aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul } 672792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul 6732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#if 0 674792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul /* DEBUG CODE: Verify that lambda[] is monotonic. 6752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * We can't really use this because the inaccuracy in the LOG2 function 6762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * causes this test to fail, yet the resulting texturing is correct. 6772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 6782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (n > 1) { 6792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 6802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul printf("lambda delta = %g\n", lambda[0] - lambda[n-1]); 6812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (lambda[0] >= lambda[n-1]) { /* decreasing */ 6822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n - 1; i++) { 6832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT((GLint) (lambda[i] * 10) >= (GLint) (lambda[i+1] * 10)); 6842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 6852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 6862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { /* increasing */ 6872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n - 1; i++) { 6882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT((GLint) (lambda[i] * 10) <= (GLint) (lambda[i+1] * 10)); 6892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 6902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 6912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 6922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#endif /* DEBUG */ 6932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 694876b41bc03c9a92263b824378fc2191f85e0a403Brian Paul if (lambda[0] <= minMagThresh && (n <= 1 || lambda[n-1] <= minMagThresh)) { 6952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* magnification for whole span */ 6962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *magStart = 0; 6972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *magEnd = n; 6982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *minStart = *minEnd = 0; 6992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 700876b41bc03c9a92263b824378fc2191f85e0a403Brian Paul else if (lambda[0] > minMagThresh && (n <=1 || lambda[n-1] > minMagThresh)) { 7012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* minification for whole span */ 7022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *minStart = 0; 7032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *minEnd = n; 7042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *magStart = *magEnd = 0; 7052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 7062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 7072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* a mix of minification and magnification */ 7082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 7092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (lambda[0] > minMagThresh) { 7102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* start with minification */ 7112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 1; i < n; i++) { 7122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (lambda[i] <= minMagThresh) 7132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 7142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 7152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *minStart = 0; 7162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *minEnd = i; 7172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *magStart = i; 7182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *magEnd = n; 7192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 7202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 7212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* start with magnification */ 7222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 1; i < n; i++) { 7232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (lambda[i] > minMagThresh) 7242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 7252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 7262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *magStart = 0; 7272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *magEnd = i; 7282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *minStart = i; 7292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *minEnd = n; 7302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 7312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 7322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 7332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#if 0 7342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* Verify the min/mag Start/End values 7352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * We don't use this either (see above) 7362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 7372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul { 7382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLint i; 7392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 7402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (lambda[i] > minMagThresh) { 7412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* minification */ 7422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(i >= *minStart); 7432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(i < *minEnd); 7442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 7452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 7462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* magnification */ 7472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(i >= *magStart); 7482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(i < *magEnd); 7492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 7502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 7512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 7522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#endif 7532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 7542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 7552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 756b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul/** 757b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul * When we sample the border color, it must be interpreted according to 758b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul * the base texture format. Ex: if the texture base format it GL_ALPHA, 759b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul * we return (0,0,0,BorderAlpha). 760b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul */ 7619520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 762b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paulget_border_color(const struct gl_texture_object *tObj, 763b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul const struct gl_texture_image *img, 764b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul GLfloat rgba[4]) 765b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul{ 7661f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul switch (img->_BaseFormat) { 767b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul case GL_RGB: 768ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul rgba[0] = tObj->Sampler.BorderColor.f[0]; 769ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul rgba[1] = tObj->Sampler.BorderColor.f[1]; 770ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul rgba[2] = tObj->Sampler.BorderColor.f[2]; 771b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul rgba[3] = 1.0F; 772b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul break; 773b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul case GL_ALPHA: 774b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul rgba[0] = rgba[1] = rgba[2] = 0.0; 775ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul rgba[3] = tObj->Sampler.BorderColor.f[3]; 776b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul break; 777b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul case GL_LUMINANCE: 778ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul rgba[0] = rgba[1] = rgba[2] = tObj->Sampler.BorderColor.f[0]; 779b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul rgba[3] = 1.0; 780b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul break; 781b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul case GL_LUMINANCE_ALPHA: 782ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul rgba[0] = rgba[1] = rgba[2] = tObj->Sampler.BorderColor.f[0]; 783ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul rgba[3] = tObj->Sampler.BorderColor.f[3]; 784b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul break; 785b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul case GL_INTENSITY: 786ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul rgba[0] = rgba[1] = rgba[2] = rgba[3] = tObj->Sampler.BorderColor.f[0]; 787b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul break; 788b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul default: 789ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul COPY_4V(rgba, tObj->Sampler.BorderColor.f); 790b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul } 791b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul} 792b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul 793b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul 7942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/ 7952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/* 1-D Texture Sampling Functions */ 7962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/ 7972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 7986e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** 7992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Return the texture sample for coordinate (s) using GL_NEAREST filter. 8002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 8019520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 802f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_nearest(struct gl_context *ctx, 8032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 8042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image *img, 805de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat texcoord[4], GLfloat rgba[4]) 8062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 807a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 8082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint width = img->Width2; /* without border, power of two */ 8092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLint i; 810ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul i = nearest_texel_location(tObj->Sampler.WrapS, img, width, texcoord[0]); 8112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* skip over the border, if any */ 8122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul i += img->Border; 8132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (i < 0 || i >= (GLint) img->Width) { 8142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* Need this test for GL_CLAMP_TO_BORDER mode */ 815b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, rgba); 8162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 8172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 818a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i, 0, 0, rgba); 8192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 8202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 8212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 8222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 8236e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** 8242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Return the texture sample for coordinate (s) using GL_LINEAR filter. 8252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 8269520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 827f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_linear(struct gl_context *ctx, 8282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 8292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image *img, 830de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat texcoord[4], GLfloat rgba[4]) 8312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 832a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 8332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint width = img->Width2; 8342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLint i0, i1; 8350f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul GLbitfield useBorderColor = 0x0; 8360f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul GLfloat a; 837de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; /* texels */ 8382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 839ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul linear_texel_locations(tObj->Sampler.WrapS, img, width, texcoord[0], &i0, &i1, &a); 8402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 8412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (img->Border) { 8422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul i0 += img->Border; 8432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul i1 += img->Border; 8442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 8452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 8462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT; 8472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT; 8482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 8492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 8500f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul /* fetch texel colors */ 8510f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul if (useBorderColor & I0BIT) { 852b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, t0); 8532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 8540f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul else { 855a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i0, 0, 0, t0); 8560f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 8570f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul if (useBorderColor & I1BIT) { 858b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, t1); 8590f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 8600f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul else { 861a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i1, 0, 0, t1); 8620f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 8630f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul 8640f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul lerp_rgba(rgba, a, t0, t1); 8652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 8662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 8672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 8682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 869f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_nearest_mipmap_nearest(struct gl_context *ctx, 8702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 8712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 872de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 8732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 8742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 8752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 8762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 877792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = nearest_mipmap_level(tObj, lambda[i]); 8782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_1d_nearest(ctx, tObj, tObj->Image[0][level], texcoord[i], rgba[i]); 8792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 8802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 8812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 8822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 8832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 884f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_linear_mipmap_nearest(struct gl_context *ctx, 8852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 8862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 887de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 8882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 8892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 8902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 8912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 892792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = nearest_mipmap_level(tObj, lambda[i]); 8932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_1d_linear(ctx, tObj, tObj->Image[0][level], texcoord[i], rgba[i]); 8942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 8952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 8962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 8972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 8982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 899f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_nearest_mipmap_linear(struct gl_context *ctx, 9002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 9012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 902de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 9032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 9042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 9052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 9062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 907792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = linear_mipmap_level(tObj, lambda[i]); 9082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (level >= tObj->_MaxLevel) { 9092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_1d_nearest(ctx, tObj, tObj->Image[0][tObj->_MaxLevel], 9102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoord[i], rgba[i]); 9112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 9122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 913de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; 9142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat f = FRAC(lambda[i]); 9152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_1d_nearest(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0); 9162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_1d_nearest(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1); 9172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lerp_rgba(rgba[i], f, t0, t1); 9182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 9192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 9202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 9212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 9222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 9232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 924f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_linear_mipmap_linear(struct gl_context *ctx, 9252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 9262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 927de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 9282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 9292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 9302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 9312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 932792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = linear_mipmap_level(tObj, lambda[i]); 9332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (level >= tObj->_MaxLevel) { 9342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_1d_linear(ctx, tObj, tObj->Image[0][tObj->_MaxLevel], 9352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoord[i], rgba[i]); 9362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 9372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 938de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; 9392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat f = FRAC(lambda[i]); 9402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_1d_linear(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0); 9412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_1d_linear(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1); 9422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lerp_rgba(rgba[i], f, t0, t1); 9432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 9442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 9452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 9462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 9472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 9486e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 1D texture, nearest filtering for both min/magnification */ 9492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 950f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_nearest_1d( struct gl_context *ctx, 9512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, GLuint n, 9522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoords[][4], const GLfloat lambda[], 953de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[][4] ) 9542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 9552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 9562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; 9572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) lambda; 9586e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian for (i = 0; i < n; i++) { 9592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_1d_nearest(ctx, tObj, image, texcoords[i], rgba[i]); 9602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 9612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 9622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 9632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 9646e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 1D texture, linear filtering for both min/magnification */ 9652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 966f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_linear_1d( struct gl_context *ctx, 9672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, GLuint n, 9682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoords[][4], const GLfloat lambda[], 969de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[][4] ) 9702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 9712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 9722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; 9732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) lambda; 9746e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian for (i = 0; i < n; i++) { 9752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_1d_linear(ctx, tObj, image, texcoords[i], rgba[i]); 9762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 9772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 9782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 9792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 9806e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 1D texture, using lambda to choose between min/magnification */ 9812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 982f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_lambda_1d( struct gl_context *ctx, 9832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, GLuint n, 9842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoords[][4], 985de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4] ) 9862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 9872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint minStart, minEnd; /* texels with minification */ 9882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint magStart, magEnd; /* texels with magnification */ 9892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 9902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 9912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 992aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul compute_min_mag_ranges(tObj, n, lambda, 993aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul &minStart, &minEnd, &magStart, &magEnd); 9942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 9952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (minStart < minEnd) { 9962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* do the minified texels */ 9972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLuint m = minEnd - minStart; 998ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul switch (tObj->Sampler.MinFilter) { 9992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST: 10002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = minStart; i < minEnd; i++) 10012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_1d_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel], 10022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoords[i], rgba[i]); 10032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 10042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR: 10052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = minStart; i < minEnd; i++) 10062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_1d_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel], 10072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoords[i], rgba[i]); 10082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 10092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST_MIPMAP_NEAREST: 10102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_1d_nearest_mipmap_nearest(ctx, tObj, m, texcoords + minStart, 10112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 10122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 10132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR_MIPMAP_NEAREST: 10142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_1d_linear_mipmap_nearest(ctx, tObj, m, texcoords + minStart, 10152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 10162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 10172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST_MIPMAP_LINEAR: 10182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_1d_nearest_mipmap_linear(ctx, tObj, m, texcoords + minStart, 10192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 10202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 10212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR_MIPMAP_LINEAR: 10222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_1d_linear_mipmap_linear(ctx, tObj, m, texcoords + minStart, 10232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 10242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 10252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul default: 10262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul _mesa_problem(ctx, "Bad min filter in sample_1d_texture"); 10272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return; 10282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 10292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 10302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 10312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (magStart < magEnd) { 10322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* do the magnified texels */ 1033ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul switch (tObj->Sampler.MagFilter) { 10342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST: 10352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = magStart; i < magEnd; i++) 10362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_1d_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel], 10372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoords[i], rgba[i]); 10382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 10392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR: 10402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = magStart; i < magEnd; i++) 10412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_1d_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel], 10422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoords[i], rgba[i]); 10432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 10442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul default: 10452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul _mesa_problem(ctx, "Bad mag filter in sample_1d_texture"); 10462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return; 10472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 10482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 10492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 10502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 10512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 10522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/ 10532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/* 2-D Texture Sampling Functions */ 10542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/ 10552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 10562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 10576e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** 10582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Return the texture sample for coordinate (s,t) using GL_NEAREST filter. 10592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 10609520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 1061f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_nearest(struct gl_context *ctx, 10622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 10632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image *img, 10642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoord[4], 1065de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[]) 10662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 1067a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 10682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint width = img->Width2; /* without border, power of two */ 10692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint height = img->Height2; /* without border, power of two */ 10702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLint i, j; 10712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) ctx; 10722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 1073ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul i = nearest_texel_location(tObj->Sampler.WrapS, img, width, texcoord[0]); 1074ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul j = nearest_texel_location(tObj->Sampler.WrapT, img, height, texcoord[1]); 10752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 10762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* skip over the border, if any */ 10772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul i += img->Border; 10782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul j += img->Border; 10792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 10802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (i < 0 || i >= (GLint) img->Width || j < 0 || j >= (GLint) img->Height) { 10812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* Need this test for GL_CLAMP_TO_BORDER mode */ 1082b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, rgba); 10832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 10842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 1085a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i, j, 0, rgba); 10862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 10872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 10882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 10892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 10902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/** 10912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Return the texture sample for coordinate (s,t) using GL_LINEAR filter. 10922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * New sampling code contributed by Lynn Quam <quam@ai.sri.com>. 10932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 10949520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 1095f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_linear(struct gl_context *ctx, 10962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 10972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image *img, 10982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoord[4], 1099de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[]) 11002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 1101a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 11022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint width = img->Width2; 11032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint height = img->Height2; 11042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLint i0, j0, i1, j1; 11050f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul GLbitfield useBorderColor = 0x0; 11060f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul GLfloat a, b; 1107de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t00[4], t10[4], t01[4], t11[4]; /* sampled texel colors */ 11082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 1109ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul linear_texel_locations(tObj->Sampler.WrapS, img, width, texcoord[0], &i0, &i1, &a); 1110ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul linear_texel_locations(tObj->Sampler.WrapT, img, height, texcoord[1], &j0, &j1, &b); 11112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 11122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (img->Border) { 11132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul i0 += img->Border; 11142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul i1 += img->Border; 11152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul j0 += img->Border; 11162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul j1 += img->Border; 11172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 11182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 11192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT; 11202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT; 11212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (j0 < 0 || j0 >= height) useBorderColor |= J0BIT; 11222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (j1 < 0 || j1 >= height) useBorderColor |= J1BIT; 11232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 11242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 11250f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul /* fetch four texel colors */ 11260f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul if (useBorderColor & (I0BIT | J0BIT)) { 1127b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, t00); 11280f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 11290f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul else { 1130a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i0, j0, 0, t00); 11310f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 11320f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul if (useBorderColor & (I1BIT | J0BIT)) { 1133b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, t10); 11340f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 11350f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul else { 1136a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i1, j0, 0, t10); 11370f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 11380f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul if (useBorderColor & (I0BIT | J1BIT)) { 1139b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, t01); 11400f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 11410f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul else { 1142a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i0, j1, 0, t01); 11430f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 11440f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul if (useBorderColor & (I1BIT | J1BIT)) { 1145b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, t11); 11460f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 11470f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul else { 1148a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i1, j1, 0, t11); 11492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 11500f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul 11510f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul lerp_rgba_2d(rgba, a, b, t00, t10, t01, t11); 11522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 11532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 11542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 11556e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** 11562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * As above, but we know WRAP_S == REPEAT and WRAP_T == REPEAT. 11572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * We don't have to worry about the texture border. 11582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 11599520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 1160f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_linear_repeat(struct gl_context *ctx, 11612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 11622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image *img, 11632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoord[4], 1164de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[]) 11652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 1166a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 11672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint width = img->Width2; 11682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint height = img->Height2; 11692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLint i0, j0, i1, j1; 1170249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian GLfloat wi, wj; 1171de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t00[4], t10[4], t01[4], t11[4]; /* sampled texel colors */ 11720f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul 11739ebe3b6d369c946e41b5f6a684a4ac4e3509b67cBrian Paul (void) ctx; 11749ebe3b6d369c946e41b5f6a684a4ac4e3509b67cBrian Paul 1175ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul ASSERT(tObj->Sampler.WrapS == GL_REPEAT); 1176ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul ASSERT(tObj->Sampler.WrapT == GL_REPEAT); 11772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(img->Border == 0); 1178eaf376ba354db11f7729452060570b48a029c9a0Brian Paul ASSERT(swImg->_IsPowerOfTwo); 11792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 1180249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian linear_repeat_texel_location(width, texcoord[0], &i0, &i1, &wi); 1181249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian linear_repeat_texel_location(height, texcoord[1], &j0, &j1, &wj); 11822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 1183a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i0, j0, 0, t00); 1184a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i1, j0, 0, t10); 1185a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i0, j1, 0, t01); 1186a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i1, j1, 0, t11); 11872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 1188249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian lerp_rgba_2d(rgba, wi, wj, t00, t10, t01, t11); 11892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 11902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 11912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 11922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 1193f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_nearest_mipmap_nearest(struct gl_context *ctx, 11942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 11952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 1196de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 11972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 11982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 11992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 1200792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = nearest_mipmap_level(tObj, lambda[i]); 12012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_2d_nearest(ctx, tObj, tObj->Image[0][level], texcoord[i], rgba[i]); 12022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 12032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 12042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 12052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 12062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 1207f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_linear_mipmap_nearest(struct gl_context *ctx, 12082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 12092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 1210de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 12112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 12122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 12132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 12142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 1215792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = nearest_mipmap_level(tObj, lambda[i]); 12162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_2d_linear(ctx, tObj, tObj->Image[0][level], texcoord[i], rgba[i]); 12172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 12182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 12192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 12202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 12212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 1222f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_nearest_mipmap_linear(struct gl_context *ctx, 12232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 12242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 1225de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 12262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 12272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 12282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 12292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 1230792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = linear_mipmap_level(tObj, lambda[i]); 12312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (level >= tObj->_MaxLevel) { 12322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_2d_nearest(ctx, tObj, tObj->Image[0][tObj->_MaxLevel], 12332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoord[i], rgba[i]); 12342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 12352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 1236de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; /* texels */ 12372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat f = FRAC(lambda[i]); 12382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_2d_nearest(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0); 12392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_2d_nearest(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1); 12402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lerp_rgba(rgba[i], f, t0, t1); 12412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 12422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 12432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 12442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 12452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 12462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 1247f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_linear_mipmap_linear( struct gl_context *ctx, 12482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 12492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 1250de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4] ) 12512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 12522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 12532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 12542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 1255792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = linear_mipmap_level(tObj, lambda[i]); 12562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (level >= tObj->_MaxLevel) { 12572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_2d_linear(ctx, tObj, tObj->Image[0][tObj->_MaxLevel], 12582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoord[i], rgba[i]); 12592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 12602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 1261de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; /* texels */ 12622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat f = FRAC(lambda[i]); 12632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_2d_linear(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0); 12642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_2d_linear(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1); 12652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lerp_rgba(rgba[i], f, t0, t1); 12662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 12672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 12682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 12692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 12702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 12712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 1272f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_linear_mipmap_linear_repeat(struct gl_context *ctx, 12736e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const struct gl_texture_object *tObj, 12746e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian GLuint n, const GLfloat texcoord[][4], 1275de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 12762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 12772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 12782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 1279ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul ASSERT(tObj->Sampler.WrapS == GL_REPEAT); 1280ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul ASSERT(tObj->Sampler.WrapT == GL_REPEAT); 12812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 1282792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = linear_mipmap_level(tObj, lambda[i]); 12832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (level >= tObj->_MaxLevel) { 12842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_2d_linear_repeat(ctx, tObj, tObj->Image[0][tObj->_MaxLevel], 12852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoord[i], rgba[i]); 12862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 12872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 1288de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; /* texels */ 12892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat f = FRAC(lambda[i]); 12906e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian sample_2d_linear_repeat(ctx, tObj, tObj->Image[0][level ], 12916e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian texcoord[i], t0); 12926e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian sample_2d_linear_repeat(ctx, tObj, tObj->Image[0][level+1], 12936e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian texcoord[i], t1); 12942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lerp_rgba(rgba[i], f, t0, t1); 12952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 12962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 12972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 12982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 12992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 13006e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 2D texture, nearest filtering for both min/magnification */ 13012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 1302f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_nearest_2d(struct gl_context *ctx, 13036e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const struct gl_texture_object *tObj, GLuint n, 13046e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const GLfloat texcoords[][4], 1305de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 13062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 13072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 13082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; 13092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) lambda; 13106e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian for (i = 0; i < n; i++) { 13112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_2d_nearest(ctx, tObj, image, texcoords[i], rgba[i]); 13122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 13132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 13142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 13152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 13166e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 2D texture, linear filtering for both min/magnification */ 13172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 1318f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_linear_2d(struct gl_context *ctx, 13196e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const struct gl_texture_object *tObj, GLuint n, 13206e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const GLfloat texcoords[][4], 1321de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 13222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 13232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 13242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; 1325eaf376ba354db11f7729452060570b48a029c9a0Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(image); 13262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) lambda; 1327ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul if (tObj->Sampler.WrapS == GL_REPEAT && 1328ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul tObj->Sampler.WrapT == GL_REPEAT && 1329eaf376ba354db11f7729452060570b48a029c9a0Brian Paul swImg->_IsPowerOfTwo && 1330c14d969a69d7b9a060c6701d3f18c51eabc56635Brian image->Border == 0) { 13316e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian for (i = 0; i < n; i++) { 13322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_2d_linear_repeat(ctx, tObj, image, texcoords[i], rgba[i]); 13332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 13342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 13352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 13366e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian for (i = 0; i < n; i++) { 13372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_2d_linear(ctx, tObj, image, texcoords[i], rgba[i]); 13382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 13392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 13402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 13412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 13422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 13436e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** 13442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Optimized 2-D texture sampling: 13452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * S and T wrap mode == GL_REPEAT 13462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * GL_NEAREST min/mag filter 13472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * No border, 13482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * RowStride == Width, 13492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Format = GL_RGB 13502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 13512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 1352f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergopt_sample_rgb_2d(struct gl_context *ctx, 13536e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const struct gl_texture_object *tObj, 13546e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian GLuint n, const GLfloat texcoords[][4], 13556d63dec41f5399dbe5561175c1652d2ac5ffd4bbBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 13562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 13572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image *img = tObj->Image[0][tObj->BaseLevel]; 1358eaf376ba354db11f7729452060570b48a029c9a0Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 13592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat width = (GLfloat) img->Width; 13602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat height = (GLfloat) img->Height; 13612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint colMask = img->Width - 1; 13622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint rowMask = img->Height - 1; 13632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint shift = img->WidthLog2; 13642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint k; 13652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) ctx; 13662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) lambda; 1367ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul ASSERT(tObj->Sampler.WrapS==GL_REPEAT); 1368ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul ASSERT(tObj->Sampler.WrapT==GL_REPEAT); 13692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(img->Border==0); 13703fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul ASSERT(img->TexFormat == MESA_FORMAT_RGB888); 1371eaf376ba354db11f7729452060570b48a029c9a0Brian Paul ASSERT(swImg->_IsPowerOfTwo); 137226b8dfc8cadf0f1a8604fc77b226cc7de005f9caBrian Paul (void) swImg; 13732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 13742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (k=0; k<n; k++) { 13752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLint i = IFLOOR(texcoords[k][0] * width) & colMask; 13762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLint j = IFLOOR(texcoords[k][1] * height) & rowMask; 13772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLint pos = (j << shift) | i; 13783fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul GLubyte *texel = ((GLubyte *) img->Data) + 3*pos; 13798c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul rgba[k][RCOMP] = UBYTE_TO_FLOAT(texel[2]); 13803fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul rgba[k][GCOMP] = UBYTE_TO_FLOAT(texel[1]); 13818c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul rgba[k][BCOMP] = UBYTE_TO_FLOAT(texel[0]); 13826a0255122a7d7c0aa09bceacda90a5cea67d5ee2Brian Paul rgba[k][ACOMP] = 1.0F; 13832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 13842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 13852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 13862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 13876e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** 13882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Optimized 2-D texture sampling: 13892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * S and T wrap mode == GL_REPEAT 13902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * GL_NEAREST min/mag filter 13912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * No border 13922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * RowStride == Width, 13932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Format = GL_RGBA 13942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 13952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 1396f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergopt_sample_rgba_2d(struct gl_context *ctx, 13976e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const struct gl_texture_object *tObj, 13986e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian GLuint n, const GLfloat texcoords[][4], 13996d63dec41f5399dbe5561175c1652d2ac5ffd4bbBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 14002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 14012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image *img = tObj->Image[0][tObj->BaseLevel]; 1402eaf376ba354db11f7729452060570b48a029c9a0Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 14032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat width = (GLfloat) img->Width; 14042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat height = (GLfloat) img->Height; 14052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint colMask = img->Width - 1; 14062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint rowMask = img->Height - 1; 14072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint shift = img->WidthLog2; 14082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 14092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) ctx; 14102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) lambda; 1411ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul ASSERT(tObj->Sampler.WrapS==GL_REPEAT); 1412ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul ASSERT(tObj->Sampler.WrapT==GL_REPEAT); 14132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(img->Border==0); 14143fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul ASSERT(img->TexFormat == MESA_FORMAT_RGBA8888); 1415eaf376ba354db11f7729452060570b48a029c9a0Brian Paul ASSERT(swImg->_IsPowerOfTwo); 141626b8dfc8cadf0f1a8604fc77b226cc7de005f9caBrian Paul (void) swImg; 14172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 14182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 14192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint col = IFLOOR(texcoords[i][0] * width) & colMask; 14202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint row = IFLOOR(texcoords[i][1] * height) & rowMask; 14212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint pos = (row << shift) | col; 14221e7517f059b1f3601502a199b05453eabfe56cdbBrian Paul const GLuint texel = *((GLuint *) img->Data + pos); 14231e7517f059b1f3601502a199b05453eabfe56cdbBrian Paul rgba[i][RCOMP] = UBYTE_TO_FLOAT( (texel >> 24) ); 14241e7517f059b1f3601502a199b05453eabfe56cdbBrian Paul rgba[i][GCOMP] = UBYTE_TO_FLOAT( (texel >> 16) & 0xff ); 14251e7517f059b1f3601502a199b05453eabfe56cdbBrian Paul rgba[i][BCOMP] = UBYTE_TO_FLOAT( (texel >> 8) & 0xff ); 14261e7517f059b1f3601502a199b05453eabfe56cdbBrian Paul rgba[i][ACOMP] = UBYTE_TO_FLOAT( (texel ) & 0xff ); 14272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 14282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 14292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 14302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 14316e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 2D texture, using lambda to choose between min/magnification */ 14322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 1433f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_lambda_2d(struct gl_context *ctx, 14346e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const struct gl_texture_object *tObj, 14356e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian GLuint n, const GLfloat texcoords[][4], 1436de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 14372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 14382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image *tImg = tObj->Image[0][tObj->BaseLevel]; 1439eaf376ba354db11f7729452060570b48a029c9a0Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(tImg); 14402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint minStart, minEnd; /* texels with minification */ 14412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint magStart, magEnd; /* texels with magnification */ 14422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 1443ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul const GLboolean repeatNoBorderPOT = (tObj->Sampler.WrapS == GL_REPEAT) 1444ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul && (tObj->Sampler.WrapT == GL_REPEAT) 14452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul && (tImg->Border == 0 && (tImg->Width == tImg->RowStride)) 1446eaf376ba354db11f7729452060570b48a029c9a0Brian Paul && swImg->_IsPowerOfTwo; 14472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 14482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 1449aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul compute_min_mag_ranges(tObj, n, lambda, 1450aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul &minStart, &minEnd, &magStart, &magEnd); 14512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 14522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (minStart < minEnd) { 14532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* do the minified texels */ 14542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLuint m = minEnd - minStart; 1455ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul switch (tObj->Sampler.MinFilter) { 14562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST: 14572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (repeatNoBorderPOT) { 14581f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul switch (tImg->TexFormat) { 14593fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul case MESA_FORMAT_RGB888: 1460aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul opt_sample_rgb_2d(ctx, tObj, m, texcoords + minStart, 14612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul NULL, rgba + minStart); 14622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 14633fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul case MESA_FORMAT_RGBA8888: 1464aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul opt_sample_rgba_2d(ctx, tObj, m, texcoords + minStart, 14652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul NULL, rgba + minStart); 14662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 14672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul default: 1468aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul sample_nearest_2d(ctx, tObj, m, texcoords + minStart, 14692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul NULL, rgba + minStart ); 14702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 14712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 14722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 1473aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul sample_nearest_2d(ctx, tObj, m, texcoords + minStart, 14742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul NULL, rgba + minStart); 14752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 14762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 14772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR: 1478aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul sample_linear_2d(ctx, tObj, m, texcoords + minStart, 14792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul NULL, rgba + minStart); 14802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 14812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST_MIPMAP_NEAREST: 14822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_2d_nearest_mipmap_nearest(ctx, tObj, m, 14832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoords + minStart, 14842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 14852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 14862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR_MIPMAP_NEAREST: 14872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_2d_linear_mipmap_nearest(ctx, tObj, m, texcoords + minStart, 14882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 14892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 14902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST_MIPMAP_LINEAR: 14912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_2d_nearest_mipmap_linear(ctx, tObj, m, texcoords + minStart, 14922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 14932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 14942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR_MIPMAP_LINEAR: 14952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (repeatNoBorderPOT) 14962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_2d_linear_mipmap_linear_repeat(ctx, tObj, m, 14972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoords + minStart, lambda + minStart, rgba + minStart); 14982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else 14992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_2d_linear_mipmap_linear(ctx, tObj, m, texcoords + minStart, 15002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 15012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 15022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul default: 15032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul _mesa_problem(ctx, "Bad min filter in sample_2d_texture"); 15042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return; 15052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 15062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 15072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 15082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (magStart < magEnd) { 15092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* do the magnified texels */ 15102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLuint m = magEnd - magStart; 15112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 1512ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul switch (tObj->Sampler.MagFilter) { 15132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST: 15142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (repeatNoBorderPOT) { 15151f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul switch (tImg->TexFormat) { 15163fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul case MESA_FORMAT_RGB888: 1517aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul opt_sample_rgb_2d(ctx, tObj, m, texcoords + magStart, 15182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul NULL, rgba + magStart); 15192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 15203fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul case MESA_FORMAT_RGBA8888: 1521aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul opt_sample_rgba_2d(ctx, tObj, m, texcoords + magStart, 15222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul NULL, rgba + magStart); 15232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 15242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul default: 1525aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul sample_nearest_2d(ctx, tObj, m, texcoords + magStart, 15262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul NULL, rgba + magStart ); 15272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 15282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 15292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 1530aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul sample_nearest_2d(ctx, tObj, m, texcoords + magStart, 15312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul NULL, rgba + magStart); 15322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 15332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 15342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR: 1535aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul sample_linear_2d(ctx, tObj, m, texcoords + magStart, 15362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul NULL, rgba + magStart); 15372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 15382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul default: 15392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul _mesa_problem(ctx, "Bad mag filter in sample_lambda_2d"); 15402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 15412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 15422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 15432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 15442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 15458a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger/* For anisotropic filtering */ 15468a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger#define WEIGHT_LUT_SIZE 1024 15478a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 15488a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengerstatic GLfloat *weightLut = NULL; 15498a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 15508a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger/** 15518a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * Creates the look-up table used to speed-up EWA sampling 15528a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 15538a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengerstatic void 15548a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengercreate_filter_table(void) 15558a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger{ 15568a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLuint i; 15578a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger if (!weightLut) { 15588a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger weightLut = (GLfloat *) malloc(WEIGHT_LUT_SIZE * sizeof(GLfloat)); 15598a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 15608a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger for (i = 0; i < WEIGHT_LUT_SIZE; ++i) { 15618a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat alpha = 2; 15628a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat r2 = (GLfloat) i / (GLfloat) (WEIGHT_LUT_SIZE - 1); 15638a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat weight = (GLfloat) exp(-alpha * r2); 15648a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger weightLut[i] = weight; 15658a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 15668a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 15678a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger} 15688a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 15698a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 15708a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger/** 15718a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * Elliptical weighted average (EWA) filter for producing high quality 15728a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * anisotropic filtered results. 15738a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * Based on the Higher Quality Elliptical Weighted Avarage Filter 15748a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * published by Paul S. Heckbert in his Master's Thesis 15758a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * "Fundamentals of Texture Mapping and Image Warping" (1989) 15768a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 15778a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengerstatic void 15788a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengersample_2d_ewa(struct gl_context *ctx, 15798a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const struct gl_texture_object *tObj, 15808a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat texcoord[4], 15818a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat dudx, const GLfloat dvdx, 15828a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat dudy, const GLfloat dvdy, const GLint lod, 15838a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat rgba[]) 15848a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger{ 15858a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLint level = lod > 0 ? lod : 0; 15868a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat scaling = 1.0 / (1 << level); 15878a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const struct gl_texture_image *img = tObj->Image[0][level]; 15888a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const struct gl_texture_image *mostDetailedImage = 15898a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger tObj->Image[0][tObj->BaseLevel]; 1590980f6f1b37ca88529b3e000235156eab93254facBrian Paul const struct swrast_texture_image *swImg = 1591980f6f1b37ca88529b3e000235156eab93254facBrian Paul swrast_texture_image_const(mostDetailedImage); 1592980f6f1b37ca88529b3e000235156eab93254facBrian Paul GLfloat tex_u=-0.5 + texcoord[0] * swImg->WidthScale * scaling; 1593980f6f1b37ca88529b3e000235156eab93254facBrian Paul GLfloat tex_v=-0.5 + texcoord[1] * swImg->HeightScale * scaling; 15948a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 15958a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat ux = dudx * scaling; 15968a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat vx = dvdx * scaling; 15978a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat uy = dudy * scaling; 15988a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat vy = dvdy * scaling; 15998a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 16008a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* compute ellipse coefficients to bound the region: 16018a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * A*x*x + B*x*y + C*y*y = F. 16028a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 16038a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat A = vx*vx+vy*vy+1; 16048a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat B = -2*(ux*vx+uy*vy); 16058a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat C = ux*ux+uy*uy+1; 16068a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat F = A*C-B*B/4.0; 16078a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 16088a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* check if it is an ellipse */ 16098a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* ASSERT(F > 0.0); */ 16108a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 16118a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* Compute the ellipse's (u,v) bounding box in texture space */ 16128a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat d = -B*B+4.0*C*A; 16138a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat box_u = 2.0 / d * sqrt(d*C*F); /* box_u -> half of bbox with */ 16148a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat box_v = 2.0 / d * sqrt(A*d*F); /* box_v -> half of bbox height */ 16158a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 16168a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLint u0 = floor(tex_u - box_u); 16178a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLint u1 = ceil (tex_u + box_u); 16188a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLint v0 = floor(tex_v - box_v); 16198a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLint v1 = ceil (tex_v + box_v); 16208a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 16218a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat num[4] = {0.0F, 0.0F, 0.0F, 0.0F}; 16228a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat newCoord[2]; 16238a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat den = 0.0F; 16248a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat ddq; 16258a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat U = u0 - tex_u; 16268a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLint v; 16278a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 16288a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* Scale ellipse formula to directly index the Filter Lookup Table. 16298a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * i.e. scale so that F = WEIGHT_LUT_SIZE-1 16308a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 16318a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger double formScale = (double) (WEIGHT_LUT_SIZE - 1) / F; 16328a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger A *= formScale; 16338a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger B *= formScale; 16348a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger C *= formScale; 16358a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* F *= formScale; */ /* no need to scale F as we don't use it below here */ 16368a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 16378a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* Heckbert MS thesis, p. 59; scan over the bounding box of the ellipse 16388a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * and incrementally update the value of Ax^2+Bxy*Cy^2; when this 16398a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * value, q, is less than F, we're inside the ellipse 16408a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 16418a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger ddq = 2 * A; 16428a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger for (v = v0; v <= v1; ++v) { 16438a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat V = v - tex_v; 16448a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat dq = A * (2 * U + 1) + B * V; 16458a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat q = (C * V + B * U) * V + A * U * U; 16468a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 16478a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLint u; 16488a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger for (u = u0; u <= u1; ++u) { 16498a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* Note that the ellipse has been pre-scaled so F = WEIGHT_LUT_SIZE - 1 */ 16508a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger if (q < WEIGHT_LUT_SIZE) { 16518a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* as a LUT is used, q must never be negative; 16528a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * should not happen, though 16538a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 16548a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLint qClamped = q >= 0.0F ? q : 0; 16558a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat weight = weightLut[qClamped]; 16568a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 16578a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger newCoord[0] = u / ((GLfloat) img->Width2); 16588a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger newCoord[1] = v / ((GLfloat) img->Height2); 16598a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 16608a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger sample_2d_nearest(ctx, tObj, img, newCoord, rgba); 16618a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger num[0] += weight * rgba[0]; 16628a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger num[1] += weight * rgba[1]; 16638a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger num[2] += weight * rgba[2]; 16648a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger num[3] += weight * rgba[3]; 16658a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 16668a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger den += weight; 16678a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 16688a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger q += dq; 16698a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger dq += ddq; 16708a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 16718a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 16728a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 16738a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger if (den <= 0.0F) { 16748a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* Reaching this place would mean 16758a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * that no pixels intersected the ellipse. 16768a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * This should never happen because 16778a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * the filter we use always 16788a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * intersects at least one pixel. 16798a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 16808a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 16818a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /*rgba[0]=0; 16828a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger rgba[1]=0; 16838a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger rgba[2]=0; 16848a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger rgba[3]=0;*/ 16858a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* not enough pixels in resampling, resort to direct interpolation */ 16868a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger sample_2d_linear(ctx, tObj, img, texcoord, rgba); 16878a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger return; 16888a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 16898a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 16908a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger rgba[0] = num[0] / den; 16918a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger rgba[1] = num[1] / den; 16928a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger rgba[2] = num[2] / den; 16938a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger rgba[3] = num[3] / den; 16948a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger} 16958a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 16968a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 16978a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger/** 16988a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * Anisotropic filtering using footprint assembly as outlined in the 16998a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * EXT_texture_filter_anisotropic spec: 17008a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * http://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt 17018a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * Faster than EWA but has less quality (more aliasing effects) 17028a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 17038a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengerstatic void 17048a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengersample_2d_footprint(struct gl_context *ctx, 17058a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const struct gl_texture_object *tObj, 17068a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat texcoord[4], 17078a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat dudx, const GLfloat dvdx, 17088a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat dudy, const GLfloat dvdy, const GLint lod, 17098a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat rgba[]) 17108a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger{ 17118a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLint level = lod > 0 ? lod : 0; 17128a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat scaling = 1.0F / (1 << level); 17138a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const struct gl_texture_image *img = tObj->Image[0][level]; 17148a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 17158a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat ux = dudx * scaling; 17168a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat vx = dvdx * scaling; 17178a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat uy = dudy * scaling; 17188a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat vy = dvdy * scaling; 17198a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 17208a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat Px2 = ux * ux + vx * vx; /* squared length of dx */ 17218a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat Py2 = uy * uy + vy * vy; /* squared length of dy */ 17228a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 17238a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLint numSamples; 17248a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat ds; 17258a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat dt; 17268a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 17278a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat num[4] = {0.0F, 0.0F, 0.0F, 0.0F}; 17288a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat newCoord[2]; 17298a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLint s; 17308a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 17318a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* Calculate the per anisotropic sample offsets in s,t space. */ 17328a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger if (Px2 > Py2) { 17338a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger numSamples = ceil(SQRTF(Px2)); 17348a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger ds = ux / ((GLfloat) img->Width2); 17358a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger dt = vx / ((GLfloat) img->Height2); 17368a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 17378a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger else { 17388a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger numSamples = ceil(SQRTF(Py2)); 17398a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger ds = uy / ((GLfloat) img->Width2); 17408a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger dt = vy / ((GLfloat) img->Height2); 17418a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 17428a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 17438a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger for (s = 0; s<numSamples; s++) { 17448a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger newCoord[0] = texcoord[0] + ds * ((GLfloat)(s+1) / (numSamples+1) -0.5); 17458a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger newCoord[1] = texcoord[1] + dt * ((GLfloat)(s+1) / (numSamples+1) -0.5); 17468a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 17478a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger sample_2d_linear(ctx, tObj, img, newCoord, rgba); 17488a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger num[0] += rgba[0]; 17498a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger num[1] += rgba[1]; 17508a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger num[2] += rgba[2]; 17518a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger num[3] += rgba[3]; 17528a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 17538a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 17548a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger rgba[0] = num[0] / numSamples; 17558a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger rgba[1] = num[1] / numSamples; 17568a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger rgba[2] = num[2] / numSamples; 17578a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger rgba[3] = num[3] / numSamples; 17588a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger} 17598a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 17608a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 17618a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger/** 17628a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * Returns the index of the specified texture object in the 17638a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * gl_context texture unit array. 17648a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 17659520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLuint 17668a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengertexture_unit_index(const struct gl_context *ctx, 17678a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const struct gl_texture_object *tObj) 17688a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger{ 17698a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLuint maxUnit 17708a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger = (ctx->Texture._EnabledCoordUnits > 1) ? ctx->Const.MaxTextureUnits : 1; 17718a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLuint u; 17728a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 17738a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* XXX CoordUnits vs. ImageUnits */ 17748a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger for (u = 0; u < maxUnit; u++) { 17758a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger if (ctx->Texture.Unit[u]._Current == tObj) 17768a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger break; /* found */ 17778a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 17788a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger if (u >= maxUnit) 17798a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger u = 0; /* not found, use 1st one; should never happen */ 17808a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 17818a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger return u; 17828a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger} 17838a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 17848a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 17858a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger/** 17868a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * Sample 2D texture using an anisotropic filter. 17878a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * NOTE: the const GLfloat lambda_iso[] parameter does *NOT* contain 17888a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * the lambda float array but a "hidden" SWspan struct which is required 17898a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * by this function but is not available in the texture_sample_func signature. 17908a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * See _swrast_texture_span( struct gl_context *ctx, SWspan *span ) on how 17918a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * this function is called. 17928a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 17938a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengerstatic void 17948a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengersample_lambda_2d_aniso(struct gl_context *ctx, 17958a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const struct gl_texture_object *tObj, 17968a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLuint n, const GLfloat texcoords[][4], 17978a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat lambda_iso[], GLfloat rgba[][4]) 17988a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger{ 17998a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const struct gl_texture_image *tImg = tObj->Image[0][tObj->BaseLevel]; 1800980f6f1b37ca88529b3e000235156eab93254facBrian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(tImg); 18018a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat maxEccentricity = 18028a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger tObj->Sampler.MaxAnisotropy * tObj->Sampler.MaxAnisotropy; 18038a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 18048a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* re-calculate the lambda values so that they are usable with anisotropic 18058a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * filtering 18068a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 18078a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger SWspan *span = (SWspan *)lambda_iso; /* access the "hidden" SWspan struct */ 18088a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 18098a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* based on interpolate_texcoords(struct gl_context *ctx, SWspan *span) 18108a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * in swrast/s_span.c 18118a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 18128a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 18138a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* find the texture unit index by looking up the current texture object 18148a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * from the context list of available texture objects. 18158a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 18168a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLuint u = texture_unit_index(ctx, tObj); 18178a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLuint attr = FRAG_ATTRIB_TEX0 + u; 18188a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat texW, texH; 18198a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 18208a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat dsdx = span->attrStepX[attr][0]; 18218a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat dsdy = span->attrStepY[attr][0]; 18228a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat dtdx = span->attrStepX[attr][1]; 18238a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat dtdy = span->attrStepY[attr][1]; 18248a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat dqdx = span->attrStepX[attr][3]; 18258a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat dqdy = span->attrStepY[attr][3]; 18268a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat s = span->attrStart[attr][0] + span->leftClip * dsdx; 18278a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat t = span->attrStart[attr][1] + span->leftClip * dtdx; 18288a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat q = span->attrStart[attr][3] + span->leftClip * dqdx; 18298a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 18308a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* from swrast/s_texcombine.c _swrast_texture_span */ 18318a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u]; 18328a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLboolean adjustLOD = 18338a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger (texUnit->LodBias + tObj->Sampler.LodBias != 0.0F) 18348a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger || (tObj->Sampler.MinLod != -1000.0 || tObj->Sampler.MaxLod != 1000.0); 18358a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 18368a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLuint i; 18378a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 18388a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* on first access create the lookup table containing the filter weights. */ 18398a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger if (!weightLut) { 18408a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger create_filter_table(); 18418a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 18428a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 1843980f6f1b37ca88529b3e000235156eab93254facBrian Paul texW = swImg->WidthScale; 1844980f6f1b37ca88529b3e000235156eab93254facBrian Paul texH = swImg->HeightScale; 18458a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 18468a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger for (i = 0; i < n; i++) { 18478a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 18488a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 18498a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat dudx = texW * ((s + dsdx) / (q + dqdx) - s * invQ); 18508a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat dvdx = texH * ((t + dtdx) / (q + dqdx) - t * invQ); 18518a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat dudy = texW * ((s + dsdy) / (q + dqdy) - s * invQ); 18528a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat dvdy = texH * ((t + dtdy) / (q + dqdy) - t * invQ); 18538a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 18548a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* note: instead of working with Px and Py, we will use the 18558a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * squared length instead, to avoid sqrt. 18568a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 18578a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat Px2 = dudx * dudx + dvdx * dvdx; 18588a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat Py2 = dudy * dudy + dvdy * dvdy; 18598a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 18608a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat Pmax2; 18618a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat Pmin2; 18628a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat e; 18638a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat lod; 18648a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 18658a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger s += dsdx; 18668a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger t += dtdx; 18678a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger q += dqdx; 18688a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 18698a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger if (Px2 < Py2) { 18708a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger Pmax2 = Py2; 18718a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger Pmin2 = Px2; 18728a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 18738a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger else { 18748a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger Pmax2 = Px2; 18758a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger Pmin2 = Py2; 18768a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 18778a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 18788a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* if the eccentricity of the ellipse is too big, scale up the shorter 18798a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * of the two vectors to limit the maximum amount of work per pixel 18808a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 18818a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger e = Pmax2 / Pmin2; 18828a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger if (e > maxEccentricity) { 18838a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* GLfloat s=e / maxEccentricity; 18848a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger minor[0] *= s; 18858a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger minor[1] *= s; 18868a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger Pmin2 *= s; */ 18878a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger Pmin2 = Pmax2 / maxEccentricity; 18888a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 18898a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 18908a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* note: we need to have Pmin=sqrt(Pmin2) here, but we can avoid 18918a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * this since 0.5*log(x) = log(sqrt(x)) 18928a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 18938a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger lod = 0.5 * LOG2(Pmin2); 18948a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 18958a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger if (adjustLOD) { 18968a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* from swrast/s_texcombine.c _swrast_texture_span */ 18978a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger if (texUnit->LodBias + tObj->Sampler.LodBias != 0.0F) { 18988a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* apply LOD bias, but don't clamp yet */ 18998a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat bias = 19008a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger CLAMP(texUnit->LodBias + tObj->Sampler.LodBias, 19018a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger -ctx->Const.MaxTextureLodBias, 19028a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger ctx->Const.MaxTextureLodBias); 19038a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger lod += bias; 19048a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 19058a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger if (tObj->Sampler.MinLod != -1000.0 || 19068a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger tObj->Sampler.MaxLod != 1000.0) { 19078a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* apply LOD clamping to lambda */ 19088a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger lod = CLAMP(lod, tObj->Sampler.MinLod, tObj->Sampler.MaxLod); 19098a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 19108a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 19118a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 19128a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 19138a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* If the ellipse covers the whole image, we can 19148a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * simply return the average of the whole image. 19158a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 19168a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger if (lod >= tObj->_MaxLevel) { 19178a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger sample_2d_linear(ctx, tObj, tObj->Image[0][tObj->_MaxLevel], 19188a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger texcoords[i], rgba[i]); 19198a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 19208a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger else { 19218a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* don't bother interpolating between multiple LODs; it doesn't 19228a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * seem to be worth the extra running time. 19238a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 19248a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger sample_2d_ewa(ctx, tObj, texcoords[i], 19258a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger dudx, dvdx, dudy, dvdy, floor(lod), rgba[i]); 19268a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 19278a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* unused: */ 19288a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger (void) sample_2d_footprint; 19298a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* 19308a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger sample_2d_footprint(ctx, tObj, texcoords[i], 19318a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger dudx, dvdx, dudy, dvdy, floor(lod), rgba[i]); 19328a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 19338a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 19348a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 19358a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger} 19368a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 19378a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 19382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 19392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/ 19402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/* 3-D Texture Sampling Functions */ 19412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/ 19422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 19436e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** 19442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter. 19452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 19469520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 1947f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_3d_nearest(struct gl_context *ctx, 19482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 19492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image *img, 19502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoord[4], 1951de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[4]) 19522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 1953a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 19542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint width = img->Width2; /* without border, power of two */ 19552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint height = img->Height2; /* without border, power of two */ 19562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint depth = img->Depth2; /* without border, power of two */ 19572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLint i, j, k; 19582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) ctx; 19592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 1960ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul i = nearest_texel_location(tObj->Sampler.WrapS, img, width, texcoord[0]); 1961ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul j = nearest_texel_location(tObj->Sampler.WrapT, img, height, texcoord[1]); 1962ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul k = nearest_texel_location(tObj->Sampler.WrapR, img, depth, texcoord[2]); 19632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 19642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (i < 0 || i >= (GLint) img->Width || 19652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul j < 0 || j >= (GLint) img->Height || 19662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul k < 0 || k >= (GLint) img->Depth) { 19672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* Need this test for GL_CLAMP_TO_BORDER mode */ 1968b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, rgba); 19692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 19702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 1971a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i, j, k, rgba); 19722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 19732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 19742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 19752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 19766e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** 19772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter. 19782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 19792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 1980f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_3d_linear(struct gl_context *ctx, 19812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 19822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image *img, 19832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoord[4], 1984de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[4]) 19852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 1986a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 19872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint width = img->Width2; 19882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint height = img->Height2; 19892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint depth = img->Depth2; 19902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLint i0, j0, k0, i1, j1, k1; 19910f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul GLbitfield useBorderColor = 0x0; 19920f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul GLfloat a, b, c; 1993de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t000[4], t010[4], t001[4], t011[4]; 1994de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t100[4], t110[4], t101[4], t111[4]; 19952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 1996ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul linear_texel_locations(tObj->Sampler.WrapS, img, width, texcoord[0], &i0, &i1, &a); 1997ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul linear_texel_locations(tObj->Sampler.WrapT, img, height, texcoord[1], &j0, &j1, &b); 1998ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul linear_texel_locations(tObj->Sampler.WrapR, img, depth, texcoord[2], &k0, &k1, &c); 19992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 20002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (img->Border) { 20012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul i0 += img->Border; 20022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul i1 += img->Border; 20032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul j0 += img->Border; 20042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul j1 += img->Border; 20052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul k0 += img->Border; 20062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul k1 += img->Border; 20072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 20082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 20092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* check if sampling texture border color */ 20102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT; 20112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT; 20122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (j0 < 0 || j0 >= height) useBorderColor |= J0BIT; 20132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (j1 < 0 || j1 >= height) useBorderColor |= J1BIT; 20142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (k0 < 0 || k0 >= depth) useBorderColor |= K0BIT; 20152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (k1 < 0 || k1 >= depth) useBorderColor |= K1BIT; 20162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 20172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 20180f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul /* Fetch texels */ 20190f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul if (useBorderColor & (I0BIT | J0BIT | K0BIT)) { 2020b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, t000); 20210f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 20220f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul else { 2023a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i0, j0, k0, t000); 20240f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 20250f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul if (useBorderColor & (I1BIT | J0BIT | K0BIT)) { 2026b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, t100); 20270f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 20280f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul else { 2029a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i1, j0, k0, t100); 20300f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 20310f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul if (useBorderColor & (I0BIT | J1BIT | K0BIT)) { 2032b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, t010); 20330f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 20340f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul else { 2035a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i0, j1, k0, t010); 20360f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 20370f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul if (useBorderColor & (I1BIT | J1BIT | K0BIT)) { 2038b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, t110); 20390f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 20400f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul else { 2041a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i1, j1, k0, t110); 20420f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 20432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 20440f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul if (useBorderColor & (I0BIT | J0BIT | K1BIT)) { 2045b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, t001); 20460f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 20470f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul else { 2048a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i0, j0, k1, t001); 20490f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 20500f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul if (useBorderColor & (I1BIT | J0BIT | K1BIT)) { 2051b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, t101); 20520f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 20530f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul else { 2054a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i1, j0, k1, t101); 20550f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 20560f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul if (useBorderColor & (I0BIT | J1BIT | K1BIT)) { 2057b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, t011); 20580f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 20590f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul else { 2060a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i0, j1, k1, t011); 20612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 20620f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul if (useBorderColor & (I1BIT | J1BIT | K1BIT)) { 2063b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, t111); 20640f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 20650f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul else { 2066a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i1, j1, k1, t111); 20670f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 20680f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul 20690f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul /* trilinear interpolation of samples */ 20700f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul lerp_rgba_3d(rgba, a, b, c, t000, t100, t010, t110, t001, t101, t011, t111); 20712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 20722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 20732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 20742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2075f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_3d_nearest_mipmap_nearest(struct gl_context *ctx, 20762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 20772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 2078de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4] ) 20792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 20802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 20812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 2082792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = nearest_mipmap_level(tObj, lambda[i]); 20832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_3d_nearest(ctx, tObj, tObj->Image[0][level], texcoord[i], rgba[i]); 20842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 20852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 20862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 20872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 20882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2089f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_3d_linear_mipmap_nearest(struct gl_context *ctx, 20902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 20912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 2092de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 20932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 20942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 20952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 20962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 2097792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = nearest_mipmap_level(tObj, lambda[i]); 20982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_3d_linear(ctx, tObj, tObj->Image[0][level], texcoord[i], rgba[i]); 20992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 21002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 21012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 21022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 21032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2104f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_3d_nearest_mipmap_linear(struct gl_context *ctx, 21052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 21062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 2107de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 21082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 21092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 21102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 21112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 2112792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = linear_mipmap_level(tObj, lambda[i]); 21132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (level >= tObj->_MaxLevel) { 21142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_3d_nearest(ctx, tObj, tObj->Image[0][tObj->_MaxLevel], 21152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoord[i], rgba[i]); 21162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 21172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 2118de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; /* texels */ 21192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat f = FRAC(lambda[i]); 21202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_3d_nearest(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0); 21212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_3d_nearest(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1); 21222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lerp_rgba(rgba[i], f, t0, t1); 21232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 21242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 21252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 21262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 21272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 21282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2129f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_3d_linear_mipmap_linear(struct gl_context *ctx, 21302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 21312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 2132de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 21332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 21342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 21352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 21362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 2137792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = linear_mipmap_level(tObj, lambda[i]); 21382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (level >= tObj->_MaxLevel) { 21392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_3d_linear(ctx, tObj, tObj->Image[0][tObj->_MaxLevel], 21402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoord[i], rgba[i]); 21412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 21422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 2143de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; /* texels */ 21442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat f = FRAC(lambda[i]); 21452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_3d_linear(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0); 21462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_3d_linear(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1); 21472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lerp_rgba(rgba[i], f, t0, t1); 21482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 21492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 21502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 21512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 21522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 21536e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 3D texture, nearest filtering for both min/magnification */ 21542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2155f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_nearest_3d(struct gl_context *ctx, 21562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, GLuint n, 21572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoords[][4], const GLfloat lambda[], 2158de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[][4]) 21592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 21602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 21612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; 21622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) lambda; 21636e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian for (i = 0; i < n; i++) { 21642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_3d_nearest(ctx, tObj, image, texcoords[i], rgba[i]); 21652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 21662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 21672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 21682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 21696e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 3D texture, linear filtering for both min/magnification */ 21702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2171f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_linear_3d(struct gl_context *ctx, 21726e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const struct gl_texture_object *tObj, GLuint n, 21736e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const GLfloat texcoords[][4], 2174de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 21752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 21762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 21772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; 21782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) lambda; 21796e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian for (i = 0; i < n; i++) { 21802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_3d_linear(ctx, tObj, image, texcoords[i], rgba[i]); 21812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 21822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 21832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 21842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 21856e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 3D texture, using lambda to choose between min/magnification */ 21862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2187f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_lambda_3d(struct gl_context *ctx, 21886e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const struct gl_texture_object *tObj, GLuint n, 21896e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const GLfloat texcoords[][4], const GLfloat lambda[], 2190de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[][4]) 21912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 21922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint minStart, minEnd; /* texels with minification */ 21932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint magStart, magEnd; /* texels with magnification */ 21942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 21952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 21962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 2197aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul compute_min_mag_ranges(tObj, n, lambda, 2198aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul &minStart, &minEnd, &magStart, &magEnd); 21992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 22002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (minStart < minEnd) { 22012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* do the minified texels */ 22022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint m = minEnd - minStart; 2203ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul switch (tObj->Sampler.MinFilter) { 22042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST: 22052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = minStart; i < minEnd; i++) 22062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_3d_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel], 22072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoords[i], rgba[i]); 22082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 22092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR: 22102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = minStart; i < minEnd; i++) 22112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_3d_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel], 22122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoords[i], rgba[i]); 22132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 22142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST_MIPMAP_NEAREST: 22152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_3d_nearest_mipmap_nearest(ctx, tObj, m, texcoords + minStart, 22162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 22172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 22182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR_MIPMAP_NEAREST: 22192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_3d_linear_mipmap_nearest(ctx, tObj, m, texcoords + minStart, 22202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 22212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 22222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST_MIPMAP_LINEAR: 22232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_3d_nearest_mipmap_linear(ctx, tObj, m, texcoords + minStart, 22242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 22252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 22262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR_MIPMAP_LINEAR: 22272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_3d_linear_mipmap_linear(ctx, tObj, m, texcoords + minStart, 22282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 22292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 22302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul default: 22312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul _mesa_problem(ctx, "Bad min filter in sample_3d_texture"); 22322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return; 22332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 22342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 22352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 22362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (magStart < magEnd) { 22372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* do the magnified texels */ 2238ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul switch (tObj->Sampler.MagFilter) { 22392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST: 22402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = magStart; i < magEnd; i++) 22412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_3d_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel], 22422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoords[i], rgba[i]); 22432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 22442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR: 22452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = magStart; i < magEnd; i++) 22462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_3d_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel], 22472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoords[i], rgba[i]); 22482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 22492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul default: 22502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul _mesa_problem(ctx, "Bad mag filter in sample_3d_texture"); 22512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return; 22522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 22532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 22542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 22552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 22562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 22572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/ 22582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/* Texture Cube Map Sampling Functions */ 22592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/ 22602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 22612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/** 22622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Choose one of six sides of a texture cube map given the texture 22632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * coord (rx,ry,rz). Return pointer to corresponding array of texture 22642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * images. 22652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 22662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic const struct gl_texture_image ** 22672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulchoose_cube_face(const struct gl_texture_object *texObj, 22682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoord[4], GLfloat newCoord[4]) 22692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 22702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* 22712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul major axis 22722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul direction target sc tc ma 22732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ---------- ------------------------------- --- --- --- 22742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul +rx TEXTURE_CUBE_MAP_POSITIVE_X_EXT -rz -ry rx 22752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul -rx TEXTURE_CUBE_MAP_NEGATIVE_X_EXT +rz -ry rx 22762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul +ry TEXTURE_CUBE_MAP_POSITIVE_Y_EXT +rx +rz ry 22772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul -ry TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT +rx -rz ry 22782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul +rz TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz 22792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul -rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz 22802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 22812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat rx = texcoord[0]; 22822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat ry = texcoord[1]; 22832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat rz = texcoord[2]; 22842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat arx = FABSF(rx), ary = FABSF(ry), arz = FABSF(rz); 22852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint face; 22862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLfloat sc, tc, ma; 22872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 2288d504a7669d7b71229c2d15503a095d71ee1584e6Brian Paul if (arx >= ary && arx >= arz) { 22892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (rx >= 0.0F) { 22902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul face = FACE_POS_X; 22912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sc = -rz; 22922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul tc = -ry; 22932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ma = arx; 22942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 22952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 22962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul face = FACE_NEG_X; 22972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sc = rz; 22982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul tc = -ry; 22992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ma = arx; 23002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 23012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 2302d504a7669d7b71229c2d15503a095d71ee1584e6Brian Paul else if (ary >= arx && ary >= arz) { 23032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (ry >= 0.0F) { 23042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul face = FACE_POS_Y; 23052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sc = rx; 23062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul tc = rz; 23072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ma = ary; 23082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 23092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 23102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul face = FACE_NEG_Y; 23112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sc = rx; 23122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul tc = -rz; 23132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ma = ary; 23142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 23152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 23162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 23172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (rz > 0.0F) { 23182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul face = FACE_POS_Z; 23192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sc = rx; 23202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul tc = -ry; 23212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ma = arz; 23222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 23232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 23242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul face = FACE_NEG_Z; 23252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sc = -rx; 23262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul tc = -ry; 23272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ma = arz; 23282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 23292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 23302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 233167d4a5b15cfd8583c19a5776b0ec1564b60239ebKeith Whitwell { 233267d4a5b15cfd8583c19a5776b0ec1564b60239ebKeith Whitwell const float ima = 1.0F / ma; 233367d4a5b15cfd8583c19a5776b0ec1564b60239ebKeith Whitwell newCoord[0] = ( sc * ima + 1.0F ) * 0.5F; 233467d4a5b15cfd8583c19a5776b0ec1564b60239ebKeith Whitwell newCoord[1] = ( tc * ima + 1.0F ) * 0.5F; 233567d4a5b15cfd8583c19a5776b0ec1564b60239ebKeith Whitwell } 233667d4a5b15cfd8583c19a5776b0ec1564b60239ebKeith Whitwell 23372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return (const struct gl_texture_image **) texObj->Image[face]; 23382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 23392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 23402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 23412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2342f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_nearest_cube(struct gl_context *ctx, 23432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, GLuint n, 23442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoords[][4], const GLfloat lambda[], 2345de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[][4]) 23462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 23472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 23482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) lambda; 23492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 23502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image **images; 23512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLfloat newCoord[4]; 23522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul images = choose_cube_face(tObj, texcoords[i], newCoord); 23532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_2d_nearest(ctx, tObj, images[tObj->BaseLevel], 23542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul newCoord, rgba[i]); 23552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 23562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 23572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 23582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 23592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2360f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_linear_cube(struct gl_context *ctx, 23612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, GLuint n, 23622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoords[][4], 2363de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 23642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 23652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 23662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) lambda; 23672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 23682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image **images; 23692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLfloat newCoord[4]; 23702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul images = choose_cube_face(tObj, texcoords[i], newCoord); 23712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_2d_linear(ctx, tObj, images[tObj->BaseLevel], 23722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul newCoord, rgba[i]); 23732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 23742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 23752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 23762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 23772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2378f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_cube_nearest_mipmap_nearest(struct gl_context *ctx, 23792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 23802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 2381de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 23822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 23832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 23842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 23852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 23862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image **images; 23872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLfloat newCoord[4]; 238821177c8764638e1d4b3b29fed64adec62a14e936Brian Paul GLint level; 23892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul images = choose_cube_face(tObj, texcoord[i], newCoord); 239021177c8764638e1d4b3b29fed64adec62a14e936Brian Paul 239121177c8764638e1d4b3b29fed64adec62a14e936Brian Paul /* XXX we actually need to recompute lambda here based on the newCoords. 239221177c8764638e1d4b3b29fed64adec62a14e936Brian Paul * But we would need the texcoords of adjacent fragments to compute that 239321177c8764638e1d4b3b29fed64adec62a14e936Brian Paul * properly, and we don't have those here. 239421177c8764638e1d4b3b29fed64adec62a14e936Brian Paul * For now, do an approximation: subtracting 1 from the chosen mipmap 239521177c8764638e1d4b3b29fed64adec62a14e936Brian Paul * level seems to work in some test cases. 239621177c8764638e1d4b3b29fed64adec62a14e936Brian Paul * The same adjustment is done in the next few functions. 239721177c8764638e1d4b3b29fed64adec62a14e936Brian Paul */ 239821177c8764638e1d4b3b29fed64adec62a14e936Brian Paul level = nearest_mipmap_level(tObj, lambda[i]); 239921177c8764638e1d4b3b29fed64adec62a14e936Brian Paul level = MAX2(level - 1, 0); 240021177c8764638e1d4b3b29fed64adec62a14e936Brian Paul 24012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_2d_nearest(ctx, tObj, images[level], newCoord, rgba[i]); 24022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 24032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 24042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 24052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 24062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2407f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_cube_linear_mipmap_nearest(struct gl_context *ctx, 24082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 24092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 2410de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 24112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 24122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 24132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 24142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 24152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image **images; 24162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLfloat newCoord[4]; 2417792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = nearest_mipmap_level(tObj, lambda[i]); 241821177c8764638e1d4b3b29fed64adec62a14e936Brian Paul level = MAX2(level - 1, 0); /* see comment above */ 24192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul images = choose_cube_face(tObj, texcoord[i], newCoord); 24202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_2d_linear(ctx, tObj, images[level], newCoord, rgba[i]); 24212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 24222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 24232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 24242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 24252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2426f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_cube_nearest_mipmap_linear(struct gl_context *ctx, 24272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 24282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 2429de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 24302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 24312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 24322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 24332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 24342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image **images; 24352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLfloat newCoord[4]; 2436792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = linear_mipmap_level(tObj, lambda[i]); 243721177c8764638e1d4b3b29fed64adec62a14e936Brian Paul level = MAX2(level - 1, 0); /* see comment above */ 24382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul images = choose_cube_face(tObj, texcoord[i], newCoord); 24392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (level >= tObj->_MaxLevel) { 24402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_2d_nearest(ctx, tObj, images[tObj->_MaxLevel], 24412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul newCoord, rgba[i]); 24422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 24432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 2444de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; /* texels */ 24452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat f = FRAC(lambda[i]); 24462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_2d_nearest(ctx, tObj, images[level ], newCoord, t0); 24472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_2d_nearest(ctx, tObj, images[level+1], newCoord, t1); 24482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lerp_rgba(rgba[i], f, t0, t1); 24492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 24502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 24512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 24522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 24532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 24542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2455f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_cube_linear_mipmap_linear(struct gl_context *ctx, 24562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 24572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 2458de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 24592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 24602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 24612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 24622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 24632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image **images; 24642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLfloat newCoord[4]; 2465792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = linear_mipmap_level(tObj, lambda[i]); 246621177c8764638e1d4b3b29fed64adec62a14e936Brian Paul level = MAX2(level - 1, 0); /* see comment above */ 24672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul images = choose_cube_face(tObj, texcoord[i], newCoord); 24682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (level >= tObj->_MaxLevel) { 24692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_2d_linear(ctx, tObj, images[tObj->_MaxLevel], 24702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul newCoord, rgba[i]); 24712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 24722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 2473de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; 24742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat f = FRAC(lambda[i]); 24752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_2d_linear(ctx, tObj, images[level ], newCoord, t0); 24762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sample_2d_linear(ctx, tObj, images[level+1], newCoord, t1); 24772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lerp_rgba(rgba[i], f, t0, t1); 24782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 24792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 24802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 24812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 24822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 24836e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample cube texture, using lambda to choose between min/magnification */ 24842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2485f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_lambda_cube(struct gl_context *ctx, 24866e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const struct gl_texture_object *tObj, GLuint n, 24876e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const GLfloat texcoords[][4], const GLfloat lambda[], 2488de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[][4]) 24892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 24902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint minStart, minEnd; /* texels with minification */ 24912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint magStart, magEnd; /* texels with magnification */ 24922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 24932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 2494aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul compute_min_mag_ranges(tObj, n, lambda, 2495aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul &minStart, &minEnd, &magStart, &magEnd); 24962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 24972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (minStart < minEnd) { 24982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* do the minified texels */ 24992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLuint m = minEnd - minStart; 2500ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul switch (tObj->Sampler.MinFilter) { 25012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST: 2502aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul sample_nearest_cube(ctx, tObj, m, texcoords + minStart, 25032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 25042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 25052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR: 2506aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul sample_linear_cube(ctx, tObj, m, texcoords + minStart, 25072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 25082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 25092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST_MIPMAP_NEAREST: 2510aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul sample_cube_nearest_mipmap_nearest(ctx, tObj, m, 25112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoords + minStart, 25122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 25132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 25142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR_MIPMAP_NEAREST: 2515aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul sample_cube_linear_mipmap_nearest(ctx, tObj, m, 25162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoords + minStart, 25172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 25182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 25192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST_MIPMAP_LINEAR: 2520aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul sample_cube_nearest_mipmap_linear(ctx, tObj, m, 25212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoords + minStart, 25222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 25232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 25242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR_MIPMAP_LINEAR: 2525aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul sample_cube_linear_mipmap_linear(ctx, tObj, m, 25262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoords + minStart, 25272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 25282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 25292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul default: 25302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul _mesa_problem(ctx, "Bad min filter in sample_lambda_cube"); 25312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 25322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 25332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 25342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (magStart < magEnd) { 25352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* do the magnified texels */ 25362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLuint m = magEnd - magStart; 2537ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul switch (tObj->Sampler.MagFilter) { 25382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST: 2539aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul sample_nearest_cube(ctx, tObj, m, texcoords + magStart, 25402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + magStart, rgba + magStart); 25412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 25422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR: 2543aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul sample_linear_cube(ctx, tObj, m, texcoords + magStart, 25442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + magStart, rgba + magStart); 25452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 25462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul default: 25472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul _mesa_problem(ctx, "Bad mag filter in sample_lambda_cube"); 25482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 25492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 25502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 25512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 25522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 25532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/ 25542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/* Texture Rectangle Sampling Functions */ 25552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/ 25562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 2557fde15a2bae2f2ca552763705f12d53e4606feabfBrian 25582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2559f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_nearest_rect(struct gl_context *ctx, 25602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, GLuint n, 25612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoords[][4], const GLfloat lambda[], 2562de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[][4]) 25632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 25642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image *img = tObj->Image[0][0]; 2565a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 25666e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const GLint width = img->Width; 25676e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const GLint height = img->Height; 25682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 25692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 25702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) ctx; 25712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) lambda; 25722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 2573ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul ASSERT(tObj->Sampler.WrapS == GL_CLAMP || 2574ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul tObj->Sampler.WrapS == GL_CLAMP_TO_EDGE || 2575ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul tObj->Sampler.WrapS == GL_CLAMP_TO_BORDER); 2576ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul ASSERT(tObj->Sampler.WrapT == GL_CLAMP || 2577ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul tObj->Sampler.WrapT == GL_CLAMP_TO_EDGE || 2578ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul tObj->Sampler.WrapT == GL_CLAMP_TO_BORDER); 25792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 25802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 25812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLint row, col; 2582ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul col = clamp_rect_coord_nearest(tObj->Sampler.WrapS, texcoords[i][0], width); 2583ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul row = clamp_rect_coord_nearest(tObj->Sampler.WrapT, texcoords[i][1], height); 25846e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian if (col < 0 || col >= width || row < 0 || row >= height) 2585b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, rgba[i]); 25862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else 2587a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, col, row, 0, rgba[i]); 25882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 25892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 25902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 25912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 25922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2593f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_linear_rect(struct gl_context *ctx, 25942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, GLuint n, 25952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoords[][4], 2596de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 25972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 25982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image *img = tObj->Image[0][0]; 2599a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 26006e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const GLint width = img->Width; 26016e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const GLint height = img->Height; 26022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 26032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 26042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) ctx; 26052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) lambda; 26062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 2607ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul ASSERT(tObj->Sampler.WrapS == GL_CLAMP || 2608ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul tObj->Sampler.WrapS == GL_CLAMP_TO_EDGE || 2609ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul tObj->Sampler.WrapS == GL_CLAMP_TO_BORDER); 2610ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul ASSERT(tObj->Sampler.WrapT == GL_CLAMP || 2611ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul tObj->Sampler.WrapT == GL_CLAMP_TO_EDGE || 2612ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul tObj->Sampler.WrapT == GL_CLAMP_TO_BORDER); 26132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 26142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 26152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLint i0, j0, i1, j1; 2616de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t00[4], t01[4], t10[4], t11[4]; 26172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLfloat a, b; 26180f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul GLbitfield useBorderColor = 0x0; 26192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 2620ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul clamp_rect_coord_linear(tObj->Sampler.WrapS, texcoords[i][0], width, 2621249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian &i0, &i1, &a); 2622ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul clamp_rect_coord_linear(tObj->Sampler.WrapT, texcoords[i][1], height, 2623249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian &j0, &j1, &b); 26242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 26252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* compute integer rows/columns */ 26266e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT; 26276e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT; 26286e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian if (j0 < 0 || j0 >= height) useBorderColor |= J0BIT; 26296e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian if (j1 < 0 || j1 >= height) useBorderColor |= J1BIT; 26302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 26312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* get four texel samples */ 26322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (useBorderColor & (I0BIT | J0BIT)) 2633b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, t00); 26342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else 2635a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i0, j0, 0, t00); 26362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 26372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (useBorderColor & (I1BIT | J0BIT)) 2638b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, t10); 26392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else 2640a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i1, j0, 0, t10); 26412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 26422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (useBorderColor & (I0BIT | J1BIT)) 2643b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, t01); 26442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else 2645a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i0, j1, 0, t01); 26462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 26472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (useBorderColor & (I1BIT | J1BIT)) 2648b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, t11); 26492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else 2650a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i1, j1, 0, t11); 26512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 26522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lerp_rgba_2d(rgba[i], a, b, t00, t10, t01, t11); 26532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 26542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 26552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 26562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 26576e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample Rect texture, using lambda to choose between min/magnification */ 26582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2659f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_lambda_rect(struct gl_context *ctx, 26606e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const struct gl_texture_object *tObj, GLuint n, 26616e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const GLfloat texcoords[][4], const GLfloat lambda[], 2662de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[][4]) 26632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 26642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint minStart, minEnd, magStart, magEnd; 26652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 26662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* We only need lambda to decide between minification and magnification. 26672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * There is no mipmapping with rectangular textures. 26682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 2669aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul compute_min_mag_ranges(tObj, n, lambda, 2670aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul &minStart, &minEnd, &magStart, &magEnd); 26712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 26722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (minStart < minEnd) { 2673ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul if (tObj->Sampler.MinFilter == GL_NEAREST) { 26746e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian sample_nearest_rect(ctx, tObj, minEnd - minStart, 26756e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian texcoords + minStart, NULL, rgba + minStart); 26762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 26772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 26786e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian sample_linear_rect(ctx, tObj, minEnd - minStart, 26796e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian texcoords + minStart, NULL, rgba + minStart); 26802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 26812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 26822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (magStart < magEnd) { 2683ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul if (tObj->Sampler.MagFilter == GL_NEAREST) { 26846e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian sample_nearest_rect(ctx, tObj, magEnd - magStart, 26856e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian texcoords + magStart, NULL, rgba + magStart); 26862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 26872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 26886e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian sample_linear_rect(ctx, tObj, magEnd - magStart, 26896e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian texcoords + magStart, NULL, rgba + magStart); 26902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 26912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 26922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 26932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 26942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 2695bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick/**********************************************************************/ 2696bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick/* 2D Texture Array Sampling Functions */ 2697bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick/**********************************************************************/ 2698bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 26996e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** 2700bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter. 2701bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick */ 2702bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 2703f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_array_nearest(struct gl_context *ctx, 2704bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_object *tObj, 2705bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_image *img, 2706bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLfloat texcoord[4], 2707de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[4]) 2708bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 2709a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 2710bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLint width = img->Width2; /* without border, power of two */ 2711bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLint height = img->Height2; /* without border, power of two */ 2712bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLint depth = img->Depth; 2713bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint i, j; 2714bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint array; 2715bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick (void) ctx; 2716bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2717ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul i = nearest_texel_location(tObj->Sampler.WrapS, img, width, texcoord[0]); 2718ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul j = nearest_texel_location(tObj->Sampler.WrapT, img, height, texcoord[1]); 271958ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul array = tex_array_slice(texcoord[2], depth); 2720bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2721bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (i < 0 || i >= (GLint) img->Width || 2722bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick j < 0 || j >= (GLint) img->Height || 2723bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick array < 0 || array >= (GLint) img->Depth) { 2724bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick /* Need this test for GL_CLAMP_TO_BORDER mode */ 2725b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, rgba); 2726bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2727bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 2728a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i, j, array, rgba); 2729bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2730bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 2731bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2732bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 27336e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** 2734bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter. 2735bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick */ 2736bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 2737f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_array_linear(struct gl_context *ctx, 2738bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_object *tObj, 2739bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_image *img, 2740bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLfloat texcoord[4], 2741de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[4]) 2742bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 2743a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 2744bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLint width = img->Width2; 2745bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLint height = img->Height2; 2746bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLint depth = img->Depth; 2747bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint i0, j0, i1, j1; 2748bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint array; 2749bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLbitfield useBorderColor = 0x0; 2750bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLfloat a, b; 2751de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t00[4], t01[4], t10[4], t11[4]; 2752bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2753ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul linear_texel_locations(tObj->Sampler.WrapS, img, width, texcoord[0], &i0, &i1, &a); 2754ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul linear_texel_locations(tObj->Sampler.WrapT, img, height, texcoord[1], &j0, &j1, &b); 275558ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul array = tex_array_slice(texcoord[2], depth); 2756bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2757bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (array < 0 || array >= depth) { 2758ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul COPY_4V(rgba, tObj->Sampler.BorderColor.f); 2759bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2760bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 2761bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (img->Border) { 2762bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick i0 += img->Border; 2763bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick i1 += img->Border; 2764bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick j0 += img->Border; 2765bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick j1 += img->Border; 2766bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2767bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 2768bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick /* check if sampling texture border color */ 2769bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT; 2770bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT; 2771bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (j0 < 0 || j0 >= height) useBorderColor |= J0BIT; 2772bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (j1 < 0 || j1 >= height) useBorderColor |= J1BIT; 2773bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2774bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2775bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick /* Fetch texels */ 2776bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (useBorderColor & (I0BIT | J0BIT)) { 2777b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, t00); 2778bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2779bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 2780a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i0, j0, array, t00); 2781bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2782bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (useBorderColor & (I1BIT | J0BIT)) { 2783b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, t10); 2784bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2785bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 2786a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i1, j0, array, t10); 2787bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2788bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (useBorderColor & (I0BIT | J1BIT)) { 2789b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, t01); 2790bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2791bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 2792a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i0, j1, array, t01); 2793bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2794bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (useBorderColor & (I1BIT | J1BIT)) { 2795b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, t11); 2796bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2797bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 2798a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i1, j1, array, t11); 2799bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2800bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2801bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick /* trilinear interpolation of samples */ 2802bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick lerp_rgba_2d(rgba, a, b, t00, t10, t01, t11); 2803bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2804bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 2805bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2806bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2807bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 2808f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_array_nearest_mipmap_nearest(struct gl_context *ctx, 2809bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_object *tObj, 2810bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint n, const GLfloat texcoord[][4], 2811de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 2812bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 2813bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint i; 2814bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = 0; i < n; i++) { 2815bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint level = nearest_mipmap_level(tObj, lambda[i]); 2816bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_2d_array_nearest(ctx, tObj, tObj->Image[0][level], texcoord[i], 2817bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick rgba[i]); 2818bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2819bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 2820bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2821bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2822bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 2823f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_array_linear_mipmap_nearest(struct gl_context *ctx, 2824bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_object *tObj, 2825bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint n, const GLfloat texcoord[][4], 2826de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 2827bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 2828bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint i; 2829bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick ASSERT(lambda != NULL); 2830bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = 0; i < n; i++) { 2831bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint level = nearest_mipmap_level(tObj, lambda[i]); 2832bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_2d_array_linear(ctx, tObj, tObj->Image[0][level], 2833bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoord[i], rgba[i]); 2834bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2835bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 2836bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2837bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2838bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 2839f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_array_nearest_mipmap_linear(struct gl_context *ctx, 2840bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_object *tObj, 2841bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint n, const GLfloat texcoord[][4], 2842de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 2843bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 2844bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint i; 2845bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick ASSERT(lambda != NULL); 2846bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = 0; i < n; i++) { 2847bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint level = linear_mipmap_level(tObj, lambda[i]); 2848bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (level >= tObj->_MaxLevel) { 2849bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_2d_array_nearest(ctx, tObj, tObj->Image[0][tObj->_MaxLevel], 2850bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoord[i], rgba[i]); 2851bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2852bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 2853de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; /* texels */ 2854bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLfloat f = FRAC(lambda[i]); 28556e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian sample_2d_array_nearest(ctx, tObj, tObj->Image[0][level ], 28566e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian texcoord[i], t0); 28576e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian sample_2d_array_nearest(ctx, tObj, tObj->Image[0][level+1], 28586e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian texcoord[i], t1); 2859bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick lerp_rgba(rgba[i], f, t0, t1); 2860bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2861bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2862bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 2863bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2864bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2865bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 2866f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_array_linear_mipmap_linear(struct gl_context *ctx, 28676e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const struct gl_texture_object *tObj, 28686e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian GLuint n, const GLfloat texcoord[][4], 2869de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 2870bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 2871bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint i; 2872bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick ASSERT(lambda != NULL); 2873bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = 0; i < n; i++) { 2874bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint level = linear_mipmap_level(tObj, lambda[i]); 2875bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (level >= tObj->_MaxLevel) { 2876bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_2d_array_linear(ctx, tObj, tObj->Image[0][tObj->_MaxLevel], 2877bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoord[i], rgba[i]); 2878bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2879bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 2880de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; /* texels */ 2881bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLfloat f = FRAC(lambda[i]); 28826e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian sample_2d_array_linear(ctx, tObj, tObj->Image[0][level ], 28836e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian texcoord[i], t0); 28846e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian sample_2d_array_linear(ctx, tObj, tObj->Image[0][level+1], 28856e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian texcoord[i], t1); 2886bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick lerp_rgba(rgba[i], f, t0, t1); 2887bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2888bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2889bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 2890bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2891bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 28926e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 2D Array texture, nearest filtering for both min/magnification */ 2893bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 2894f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_nearest_2d_array(struct gl_context *ctx, 28956e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const struct gl_texture_object *tObj, GLuint n, 28966e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const GLfloat texcoords[][4], const GLfloat lambda[], 2897de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[][4]) 2898bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 2899bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint i; 2900bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; 2901bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick (void) lambda; 29026e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian for (i = 0; i < n; i++) { 2903bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_2d_array_nearest(ctx, tObj, image, texcoords[i], rgba[i]); 2904bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2905bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 2906bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2907bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2908bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 29096e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 2D Array texture, linear filtering for both min/magnification */ 2910bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 2911f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_linear_2d_array(struct gl_context *ctx, 2912bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_object *tObj, GLuint n, 2913bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLfloat texcoords[][4], 2914de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 2915bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 2916bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint i; 2917bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; 2918bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick (void) lambda; 29196e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian for (i = 0; i < n; i++) { 2920bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_2d_array_linear(ctx, tObj, image, texcoords[i], rgba[i]); 2921bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2922bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 2923bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2924bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 29256e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 2D Array texture, using lambda to choose between min/magnification */ 2926bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 2927f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_lambda_2d_array(struct gl_context *ctx, 2928bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_object *tObj, GLuint n, 2929bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLfloat texcoords[][4], const GLfloat lambda[], 2930de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[][4]) 2931bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 2932bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint minStart, minEnd; /* texels with minification */ 2933bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint magStart, magEnd; /* texels with magnification */ 2934bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint i; 2935bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2936bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick ASSERT(lambda != NULL); 2937bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick compute_min_mag_ranges(tObj, n, lambda, 2938bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick &minStart, &minEnd, &magStart, &magEnd); 2939bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2940bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (minStart < minEnd) { 2941bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick /* do the minified texels */ 2942bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint m = minEnd - minStart; 2943ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul switch (tObj->Sampler.MinFilter) { 2944bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_NEAREST: 2945bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = minStart; i < minEnd; i++) 2946bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_2d_array_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel], 2947bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoords[i], rgba[i]); 2948bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 2949bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_LINEAR: 2950bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = minStart; i < minEnd; i++) 2951bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_2d_array_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel], 2952bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoords[i], rgba[i]); 2953bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 2954bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_NEAREST_MIPMAP_NEAREST: 29556e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian sample_2d_array_nearest_mipmap_nearest(ctx, tObj, m, 29566e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian texcoords + minStart, 29576e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian lambda + minStart, 29586e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian rgba + minStart); 2959bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 2960bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_LINEAR_MIPMAP_NEAREST: 2961bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_2d_array_linear_mipmap_nearest(ctx, tObj, m, 2962bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoords + minStart, 2963bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick lambda + minStart, 2964bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick rgba + minStart); 2965bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 2966bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_NEAREST_MIPMAP_LINEAR: 29676e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian sample_2d_array_nearest_mipmap_linear(ctx, tObj, m, 29686e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian texcoords + minStart, 29696e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian lambda + minStart, 29706e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian rgba + minStart); 2971bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 2972bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_LINEAR_MIPMAP_LINEAR: 2973bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_2d_array_linear_mipmap_linear(ctx, tObj, m, 2974bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoords + minStart, 2975bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick lambda + minStart, 2976bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick rgba + minStart); 2977bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 2978bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick default: 2979bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick _mesa_problem(ctx, "Bad min filter in sample_2d_array_texture"); 2980bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick return; 2981bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2982bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2983bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2984bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (magStart < magEnd) { 2985bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick /* do the magnified texels */ 2986ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul switch (tObj->Sampler.MagFilter) { 2987bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_NEAREST: 2988bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = magStart; i < magEnd; i++) 2989bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_2d_array_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel], 2990bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoords[i], rgba[i]); 2991bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 2992bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_LINEAR: 2993bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = magStart; i < magEnd; i++) 2994bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_2d_array_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel], 2995bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoords[i], rgba[i]); 2996bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 2997bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick default: 2998bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick _mesa_problem(ctx, "Bad mag filter in sample_2d_array_texture"); 2999bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick return; 3000bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3001bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3002bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 3003bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3004bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3005bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3006bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3007bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick/**********************************************************************/ 3008bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick/* 1D Texture Array Sampling Functions */ 3009bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick/**********************************************************************/ 3010bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 30116e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** 3012bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter. 3013bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick */ 3014bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 3015f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_array_nearest(struct gl_context *ctx, 3016bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_object *tObj, 3017bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_image *img, 3018bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLfloat texcoord[4], 3019de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[4]) 3020bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 3021a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 3022bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLint width = img->Width2; /* without border, power of two */ 3023bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLint height = img->Height; 3024bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint i; 3025bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint array; 3026bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick (void) ctx; 3027bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3028ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul i = nearest_texel_location(tObj->Sampler.WrapS, img, width, texcoord[0]); 302958ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul array = tex_array_slice(texcoord[1], height); 3030bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3031bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (i < 0 || i >= (GLint) img->Width || 3032bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick array < 0 || array >= (GLint) img->Height) { 3033bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick /* Need this test for GL_CLAMP_TO_BORDER mode */ 3034b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, rgba); 3035bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3036bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 3037a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i, array, 0, rgba); 3038bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3039bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 3040bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3041bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 30426e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** 3043bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter. 3044bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick */ 3045bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 3046f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_array_linear(struct gl_context *ctx, 3047bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_object *tObj, 3048bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_image *img, 3049bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLfloat texcoord[4], 3050de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[4]) 3051bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 3052a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 3053bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLint width = img->Width2; 3054bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLint height = img->Height; 3055bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint i0, i1; 3056bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint array; 3057bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLbitfield useBorderColor = 0x0; 3058bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLfloat a; 3059de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; 3060bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3061ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul linear_texel_locations(tObj->Sampler.WrapS, img, width, texcoord[0], &i0, &i1, &a); 306258ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul array = tex_array_slice(texcoord[1], height); 3063bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3064bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (img->Border) { 3065bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick i0 += img->Border; 3066bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick i1 += img->Border; 3067bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3068bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 3069bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick /* check if sampling texture border color */ 3070bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT; 3071bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT; 3072bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3073bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3074bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (array < 0 || array >= height) useBorderColor |= K0BIT; 3075bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3076bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick /* Fetch texels */ 3077bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (useBorderColor & (I0BIT | K0BIT)) { 3078b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, t0); 3079bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3080bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 3081a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i0, array, 0, t0); 3082bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3083bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (useBorderColor & (I1BIT | K0BIT)) { 3084b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul get_border_color(tObj, img, t1); 3085bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3086bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 3087a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i1, array, 0, t1); 3088bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3089bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3090bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick /* bilinear interpolation of samples */ 3091bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick lerp_rgba(rgba, a, t0, t1); 3092bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 3093bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3094bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3095bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 3096f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_array_nearest_mipmap_nearest(struct gl_context *ctx, 3097bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_object *tObj, 3098bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint n, const GLfloat texcoord[][4], 3099de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 3100bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 3101bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint i; 3102bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = 0; i < n; i++) { 3103bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint level = nearest_mipmap_level(tObj, lambda[i]); 3104bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_1d_array_nearest(ctx, tObj, tObj->Image[0][level], texcoord[i], 3105bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick rgba[i]); 3106bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3107bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 3108bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3109bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3110bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 3111f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_array_linear_mipmap_nearest(struct gl_context *ctx, 3112bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_object *tObj, 3113bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint n, const GLfloat texcoord[][4], 3114de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 3115bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 3116bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint i; 3117bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick ASSERT(lambda != NULL); 3118bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = 0; i < n; i++) { 3119bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint level = nearest_mipmap_level(tObj, lambda[i]); 3120bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_1d_array_linear(ctx, tObj, tObj->Image[0][level], 3121bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoord[i], rgba[i]); 3122bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3123bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 3124bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3125bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3126bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 3127f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_array_nearest_mipmap_linear(struct gl_context *ctx, 3128bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_object *tObj, 3129bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint n, const GLfloat texcoord[][4], 3130de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 3131bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 3132bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint i; 3133bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick ASSERT(lambda != NULL); 3134bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = 0; i < n; i++) { 3135bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint level = linear_mipmap_level(tObj, lambda[i]); 3136bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (level >= tObj->_MaxLevel) { 3137bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_1d_array_nearest(ctx, tObj, tObj->Image[0][tObj->_MaxLevel], 3138bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoord[i], rgba[i]); 3139bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3140bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 3141de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; /* texels */ 3142bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLfloat f = FRAC(lambda[i]); 3143bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_1d_array_nearest(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0); 3144bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_1d_array_nearest(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1); 3145bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick lerp_rgba(rgba[i], f, t0, t1); 3146bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3147bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3148bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 3149bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3150bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3151bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 3152f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_array_linear_mipmap_linear(struct gl_context *ctx, 31536e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const struct gl_texture_object *tObj, 31546e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian GLuint n, const GLfloat texcoord[][4], 3155de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 3156bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 3157bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint i; 3158bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick ASSERT(lambda != NULL); 3159bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = 0; i < n; i++) { 3160bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint level = linear_mipmap_level(tObj, lambda[i]); 3161bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (level >= tObj->_MaxLevel) { 3162bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_1d_array_linear(ctx, tObj, tObj->Image[0][tObj->_MaxLevel], 3163bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoord[i], rgba[i]); 3164bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3165bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 3166de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; /* texels */ 3167bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLfloat f = FRAC(lambda[i]); 3168bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_1d_array_linear(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0); 3169bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_1d_array_linear(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1); 3170bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick lerp_rgba(rgba[i], f, t0, t1); 3171bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3172bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3173bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 3174bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3175bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 31766e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 1D Array texture, nearest filtering for both min/magnification */ 3177bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 3178f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_nearest_1d_array(struct gl_context *ctx, 31796e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const struct gl_texture_object *tObj, GLuint n, 31806e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const GLfloat texcoords[][4], const GLfloat lambda[], 3181de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[][4]) 3182bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 3183bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint i; 3184bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; 3185bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick (void) lambda; 31866e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian for (i = 0; i < n; i++) { 3187bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_1d_array_nearest(ctx, tObj, image, texcoords[i], rgba[i]); 3188bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3189bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 3190bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3191bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 31926e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 1D Array texture, linear filtering for both min/magnification */ 3193bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 3194f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_linear_1d_array(struct gl_context *ctx, 3195bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_object *tObj, GLuint n, 3196bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLfloat texcoords[][4], 3197de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 3198bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 3199bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint i; 3200bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; 3201bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick (void) lambda; 32026e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian for (i = 0; i < n; i++) { 3203bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_1d_array_linear(ctx, tObj, image, texcoords[i], rgba[i]); 3204bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3205bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 3206bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3207bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 32086e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 1D Array texture, using lambda to choose between min/magnification */ 3209bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 3210f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_lambda_1d_array(struct gl_context *ctx, 3211bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_object *tObj, GLuint n, 3212bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLfloat texcoords[][4], const GLfloat lambda[], 3213de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[][4]) 3214bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 3215bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint minStart, minEnd; /* texels with minification */ 3216bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint magStart, magEnd; /* texels with magnification */ 3217bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint i; 3218bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3219bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick ASSERT(lambda != NULL); 3220bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick compute_min_mag_ranges(tObj, n, lambda, 3221bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick &minStart, &minEnd, &magStart, &magEnd); 3222bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3223bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (minStart < minEnd) { 3224bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick /* do the minified texels */ 3225bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint m = minEnd - minStart; 3226ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul switch (tObj->Sampler.MinFilter) { 3227bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_NEAREST: 3228bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = minStart; i < minEnd; i++) 3229bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_1d_array_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel], 3230bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoords[i], rgba[i]); 3231bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 3232bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_LINEAR: 3233bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = minStart; i < minEnd; i++) 3234bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_1d_array_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel], 3235bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoords[i], rgba[i]); 3236bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 3237bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_NEAREST_MIPMAP_NEAREST: 3238bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_1d_array_nearest_mipmap_nearest(ctx, tObj, m, texcoords + minStart, 3239bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick lambda + minStart, rgba + minStart); 3240bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 3241bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_LINEAR_MIPMAP_NEAREST: 3242bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_1d_array_linear_mipmap_nearest(ctx, tObj, m, 3243bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoords + minStart, 3244bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick lambda + minStart, 3245bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick rgba + minStart); 3246bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 3247bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_NEAREST_MIPMAP_LINEAR: 3248bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_1d_array_nearest_mipmap_linear(ctx, tObj, m, texcoords + minStart, 3249bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick lambda + minStart, rgba + minStart); 3250bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 3251bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_LINEAR_MIPMAP_LINEAR: 3252bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_1d_array_linear_mipmap_linear(ctx, tObj, m, 3253bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoords + minStart, 3254bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick lambda + minStart, 3255bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick rgba + minStart); 3256bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 3257bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick default: 3258bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick _mesa_problem(ctx, "Bad min filter in sample_1d_array_texture"); 3259bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick return; 3260bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3261bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3262bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3263bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (magStart < magEnd) { 3264bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick /* do the magnified texels */ 3265ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul switch (tObj->Sampler.MagFilter) { 3266bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_NEAREST: 3267bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = magStart; i < magEnd; i++) 3268bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_1d_array_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel], 3269bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoords[i], rgba[i]); 3270bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 3271bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_LINEAR: 3272bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = magStart; i < magEnd; i++) 3273bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick sample_1d_array_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel], 3274bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoords[i], rgba[i]); 3275bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 3276bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick default: 3277bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick _mesa_problem(ctx, "Bad mag filter in sample_1d_array_texture"); 3278bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick return; 3279bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3280bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3281bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 3282bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3283bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 32846e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** 3285a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul * Compare texcoord against depth sample. Return 1.0 or the ambient value. 3286a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul */ 32879520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLfloat 3288a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paulshadow_compare(GLenum function, GLfloat coord, GLfloat depthSample, 3289a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul GLfloat ambient) 3290a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul{ 3291a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul switch (function) { 3292a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_LEQUAL: 3293a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return (coord <= depthSample) ? 1.0F : ambient; 3294a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_GEQUAL: 3295a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return (coord >= depthSample) ? 1.0F : ambient; 3296a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_LESS: 3297a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return (coord < depthSample) ? 1.0F : ambient; 3298a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_GREATER: 3299a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return (coord > depthSample) ? 1.0F : ambient; 3300a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_EQUAL: 3301a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return (coord == depthSample) ? 1.0F : ambient; 3302a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_NOTEQUAL: 3303a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return (coord != depthSample) ? 1.0F : ambient; 3304a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_ALWAYS: 3305a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return 1.0F; 3306a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_NEVER: 3307a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return ambient; 3308a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_NONE: 3309a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return depthSample; 3310a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul default: 3311a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul _mesa_problem(NULL, "Bad compare func in shadow_compare"); 3312a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return ambient; 3313a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul } 3314a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul} 3315a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 3316a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 3317a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul/** 3318a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul * Compare texcoord against four depth samples. 3319a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul */ 33209520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLfloat 3321a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paulshadow_compare4(GLenum function, GLfloat coord, 3322a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul GLfloat depth00, GLfloat depth01, 3323a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul GLfloat depth10, GLfloat depth11, 3324a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul GLfloat ambient, GLfloat wi, GLfloat wj) 3325a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul{ 3326a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul const GLfloat d = (1.0F - (GLfloat) ambient) * 0.25F; 3327a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul GLfloat luminance = 1.0F; 3328a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 3329a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul switch (function) { 3330a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_LEQUAL: 33314a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord > depth00) luminance -= d; 33324a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord > depth01) luminance -= d; 33334a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord > depth10) luminance -= d; 33344a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord > depth11) luminance -= d; 3335a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return luminance; 3336d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor case GL_GEQUAL: 33374a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord < depth00) luminance -= d; 33384a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord < depth01) luminance -= d; 33394a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord < depth10) luminance -= d; 33404a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord < depth11) luminance -= d; 3341a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return luminance; 3342d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor case GL_LESS: 33434a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord >= depth00) luminance -= d; 33444a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord >= depth01) luminance -= d; 33454a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord >= depth10) luminance -= d; 33464a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord >= depth11) luminance -= d; 3347a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return luminance; 3348d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor case GL_GREATER: 33494a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord <= depth00) luminance -= d; 33504a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord <= depth01) luminance -= d; 33514a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord <= depth10) luminance -= d; 33524a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord <= depth11) luminance -= d; 3353d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor return luminance; 3354d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor case GL_EQUAL: 33554a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord != depth00) luminance -= d; 33564a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord != depth01) luminance -= d; 33574a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord != depth10) luminance -= d; 33584a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord != depth11) luminance -= d; 3359a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return luminance; 3360d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor case GL_NOTEQUAL: 33614a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord == depth00) luminance -= d; 33624a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord == depth01) luminance -= d; 33634a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord == depth10) luminance -= d; 33644a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord == depth11) luminance -= d; 3365d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor return luminance; 3366a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_ALWAYS: 3367d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor return 1.0F; 3368a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_NEVER: 3369a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return ambient; 3370a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_NONE: 3371a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul /* ordinary bilinear filtering */ 3372a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return lerp_2d(wi, wj, depth00, depth10, depth01, depth11); 3373a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul default: 3374d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor _mesa_problem(NULL, "Bad compare func in sample_compare4"); 3375d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor return ambient; 3376a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul } 3377a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul} 3378a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 3379a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 3380a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul/** 33812b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul * Choose the mipmap level to use when sampling from a depth texture. 33822b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul */ 33832b5de09b3ea8754fb004d4f216bca29303f99490Brian Paulstatic int 33842b5de09b3ea8754fb004d4f216bca29303f99490Brian Paulchoose_depth_texture_level(const struct gl_texture_object *tObj, GLfloat lambda) 33852b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul{ 33862b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul GLint level; 33872b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul 3388ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul if (tObj->Sampler.MinFilter == GL_NEAREST || tObj->Sampler.MinFilter == GL_LINEAR) { 3389fb5e6f88fc426e53af26e98d1c336222a8952cc5Brian Paul /* no mipmapping - use base level */ 3390fb5e6f88fc426e53af26e98d1c336222a8952cc5Brian Paul level = tObj->BaseLevel; 3391fb5e6f88fc426e53af26e98d1c336222a8952cc5Brian Paul } 3392fb5e6f88fc426e53af26e98d1c336222a8952cc5Brian Paul else { 3393fb5e6f88fc426e53af26e98d1c336222a8952cc5Brian Paul /* choose mipmap level */ 3394ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul lambda = CLAMP(lambda, tObj->Sampler.MinLod, tObj->Sampler.MaxLod); 3395fb5e6f88fc426e53af26e98d1c336222a8952cc5Brian Paul level = (GLint) lambda; 3396fb5e6f88fc426e53af26e98d1c336222a8952cc5Brian Paul level = CLAMP(level, tObj->BaseLevel, tObj->_MaxLevel); 3397fb5e6f88fc426e53af26e98d1c336222a8952cc5Brian Paul } 33982b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul 33992b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul return level; 34002b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul} 34012b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul 34022b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul 34032b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul/** 34042b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul * Sample a shadow/depth texture. This function is incomplete. It doesn't 34052b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul * check for minification vs. magnification, etc. 34062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 34072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 3408f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_depth_texture( struct gl_context *ctx, 34092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, GLuint n, 34102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoords[][4], const GLfloat lambda[], 3411de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat texel[][4] ) 34122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 34132b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul const GLint level = choose_depth_texture_level(tObj, lambda[0]); 34142b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul const struct gl_texture_image *img = tObj->Image[0][level]; 3415a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 34169ebe3b6d369c946e41b5f6a684a4ac4e3509b67cBrian Paul const GLint width = img->Width; 34179ebe3b6d369c946e41b5f6a684a4ac4e3509b67cBrian Paul const GLint height = img->Height; 3418bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLint depth = img->Depth; 3419bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLuint compare_coord = (tObj->Target == GL_TEXTURE_2D_ARRAY_EXT) 3420bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick ? 3 : 2; 3421de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat ambient; 34222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLenum function; 3423de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat result; 34242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 34251f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul ASSERT(img->_BaseFormat == GL_DEPTH_COMPONENT || 34261f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul img->_BaseFormat == GL_DEPTH_STENCIL_EXT); 3427b0a0ca8bd9edc13e495a39709cc28953dd3fbd9cBrian Paul 34282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(tObj->Target == GL_TEXTURE_1D || 34292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul tObj->Target == GL_TEXTURE_2D || 3430bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick tObj->Target == GL_TEXTURE_RECTANGLE_NV || 3431bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick tObj->Target == GL_TEXTURE_1D_ARRAY_EXT || 3432bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick tObj->Target == GL_TEXTURE_2D_ARRAY_EXT); 34332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 3434ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul ambient = tObj->Sampler.CompareFailValue; 34352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 3436ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul /* XXXX if tObj->Sampler.MinFilter != tObj->Sampler.MagFilter, we're ignoring lambda */ 34372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 3438ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul function = (tObj->Sampler.CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) ? 3439ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul tObj->Sampler.CompareFunc : GL_NONE; 3440590f6fe05030cb274067a9e58af9d8306d97d0b9Brian Paul 3441ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul if (tObj->Sampler.MagFilter == GL_NEAREST) { 34422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 34432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 3444d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor GLfloat depthSample, depthRef; 3445bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint col, row, slice; 3446fde15a2bae2f2ca552763705f12d53e4606feabfBrian 34472b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul nearest_texcoord(tObj, level, texcoords[i], &col, &row, &slice); 3448bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3449bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (col >= 0 && row >= 0 && col < width && row < height && 3450bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick slice >= 0 && slice < depth) { 3451a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, col, row, slice, &depthSample); 34529ebe3b6d369c946e41b5f6a684a4ac4e3509b67cBrian Paul } 34539ebe3b6d369c946e41b5f6a684a4ac4e3509b67cBrian Paul else { 3454ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul depthSample = tObj->Sampler.BorderColor.f[0]; 34559ebe3b6d369c946e41b5f6a684a4ac4e3509b67cBrian Paul } 34562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 3457d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor depthRef = CLAMP(texcoords[i][compare_coord], 0.0F, 1.0F); 3458d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor 3459d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor result = shadow_compare(function, depthRef, depthSample, ambient); 34602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 3461ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul switch (tObj->Sampler.DepthMode) { 34622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LUMINANCE: 3463de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul ASSIGN_4V(texel[i], result, result, result, 1.0F); 34642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 34652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_INTENSITY: 3466de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul ASSIGN_4V(texel[i], result, result, result, result); 34672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 34682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_ALPHA: 3469de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul ASSIGN_4V(texel[i], 0.0F, 0.0F, 0.0F, result); 34702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 3471cd5dea640144b45ba2e88c2451f1f01ee08c1c4aIan Romanick case GL_RED: 3472cd5dea640144b45ba2e88c2451f1f01ee08c1c4aIan Romanick ASSIGN_4V(texel[i], result, 0.0F, 0.0F, 1.0F); 3473cd5dea640144b45ba2e88c2451f1f01ee08c1c4aIan Romanick break; 34742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul default: 34752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul _mesa_problem(ctx, "Bad depth texture mode"); 34762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 34772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 34782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 34792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 34802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 3481ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul ASSERT(tObj->Sampler.MagFilter == GL_LINEAR); 34822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 3483d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor GLfloat depth00, depth01, depth10, depth11, depthRef; 34842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLint i0, i1, j0, j1; 3485bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint slice; 3486a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul GLfloat wi, wj; 34872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint useBorderTexel; 34882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 34892b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul linear_texcoord(tObj, level, texcoords[i], &i0, &i1, &j0, &j1, &slice, 3490a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul &wi, &wj); 34912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 34922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul useBorderTexel = 0; 349306f606ce5761e673fca3f6b1f7dd40dace8a9906Brian Paul if (img->Border) { 349406f606ce5761e673fca3f6b1f7dd40dace8a9906Brian Paul i0 += img->Border; 349506f606ce5761e673fca3f6b1f7dd40dace8a9906Brian Paul i1 += img->Border; 3496bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (tObj->Target != GL_TEXTURE_1D_ARRAY_EXT) { 3497bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick j0 += img->Border; 3498bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick j1 += img->Border; 3499bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 35002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 35012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 35022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (i0 < 0 || i0 >= (GLint) width) useBorderTexel |= I0BIT; 35032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (i1 < 0 || i1 >= (GLint) width) useBorderTexel |= I1BIT; 35042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (j0 < 0 || j0 >= (GLint) height) useBorderTexel |= J0BIT; 35052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (j1 < 0 || j1 >= (GLint) height) useBorderTexel |= J1BIT; 35062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 35072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 3508bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (slice < 0 || slice >= (GLint) depth) { 3509ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul depth00 = tObj->Sampler.BorderColor.f[0]; 3510ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul depth01 = tObj->Sampler.BorderColor.f[0]; 3511ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul depth10 = tObj->Sampler.BorderColor.f[0]; 3512ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul depth11 = tObj->Sampler.BorderColor.f[0]; 35132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 35142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 3515bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick /* get four depth samples from the texture */ 3516bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (useBorderTexel & (I0BIT | J0BIT)) { 3517ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul depth00 = tObj->Sampler.BorderColor.f[0]; 3518bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3519bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 3520a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i0, j0, slice, &depth00); 3521bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3522bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (useBorderTexel & (I1BIT | J0BIT)) { 3523ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul depth10 = tObj->Sampler.BorderColor.f[0]; 3524bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3525bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 3526a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i1, j0, slice, &depth10); 3527bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3528bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3529bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (tObj->Target != GL_TEXTURE_1D_ARRAY_EXT) { 3530bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (useBorderTexel & (I0BIT | J1BIT)) { 3531ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul depth01 = tObj->Sampler.BorderColor.f[0]; 3532bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3533bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 3534a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i0, j1, slice, &depth01); 3535bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3536bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (useBorderTexel & (I1BIT | J1BIT)) { 3537ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul depth11 = tObj->Sampler.BorderColor.f[0]; 3538bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3539bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 3540a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul swImg->FetchTexelf(swImg, i1, j1, slice, &depth11); 3541bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3542bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3543bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 3544bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick depth01 = depth00; 3545bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick depth11 = depth10; 3546bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 35472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 35482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 3549d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor depthRef = CLAMP(texcoords[i][compare_coord], 0.0F, 1.0F); 3550d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor 3551d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor result = shadow_compare4(function, depthRef, 3552a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul depth00, depth01, depth10, depth11, 3553a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul ambient, wi, wj); 35542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 3555ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul switch (tObj->Sampler.DepthMode) { 35562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LUMINANCE: 3557a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul ASSIGN_4V(texel[i], result, result, result, 1.0F); 35582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 35592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_INTENSITY: 3560a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul ASSIGN_4V(texel[i], result, result, result, result); 35612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 35622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_ALPHA: 3563a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul ASSIGN_4V(texel[i], 0.0F, 0.0F, 0.0F, result); 35642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 35652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul default: 35662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul _mesa_problem(ctx, "Bad depth texture mode"); 35672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 3568a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 35692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } /* for */ 35702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } /* if filter */ 35712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 35722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 35732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 35742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/** 35752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * We use this function when a texture object is in an "incomplete" state. 35762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * When a fragment program attempts to sample an incomplete texture we 35772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * return black (see issue 23 in GL_ARB_fragment_program spec). 35785bfb9356d6df4c8b1e177ebda01631d99355ba25Brian Paul * Note: fragment programs don't observe the texture enable/disable flags. 35792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 35802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 3581f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnull_sample_func( struct gl_context *ctx, 35822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, GLuint n, 35832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoords[][4], const GLfloat lambda[], 3584de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[][4]) 35852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 35862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 35872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) ctx; 35882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) tObj; 35892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) texcoords; 35902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) lambda; 35912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 35922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul rgba[i][RCOMP] = 0; 35932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul rgba[i][GCOMP] = 0; 35942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul rgba[i][BCOMP] = 0; 35953fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul rgba[i][ACOMP] = 1.0; 35962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 35972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 35982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 35992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 36002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/** 36012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Choose the texture sampling function for the given texture object. 36022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 36032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paultexture_sample_func 3604f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_choose_texture_sample_func( struct gl_context *ctx, 36052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *t ) 36062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 3607227315278dea9095cee6e508d03b28720b2e7880Brian if (!t || !t->_Complete) { 36082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &null_sample_func; 36092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 36102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 3611ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul const GLboolean needLambda = 3612ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul (GLboolean) (t->Sampler.MinFilter != t->Sampler.MagFilter); 36131f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul const GLenum format = t->Image[0][t->BaseLevel]->_BaseFormat; 36142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 36152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul switch (t->Target) { 36162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_TEXTURE_1D: 3617b0a0ca8bd9edc13e495a39709cc28953dd3fbd9cBrian Paul if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT) { 36182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_depth_texture; 36192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 36202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else if (needLambda) { 36212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_lambda_1d; 36222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 3623ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul else if (t->Sampler.MinFilter == GL_LINEAR) { 36242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_linear_1d; 36252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 36262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 3627ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul ASSERT(t->Sampler.MinFilter == GL_NEAREST); 36282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_nearest_1d; 36292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 36302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_TEXTURE_2D: 3631b0a0ca8bd9edc13e495a39709cc28953dd3fbd9cBrian Paul if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT) { 36322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_depth_texture; 36332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 36342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else if (needLambda) { 36358a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* Anisotropic filtering extension. Activated only if mipmaps are used */ 36368a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger if (t->Sampler.MaxAnisotropy > 1.0 && 36378a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger t->Sampler.MinFilter == GL_LINEAR_MIPMAP_LINEAR) { 36388a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger return &sample_lambda_2d_aniso; 36398a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 36402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_lambda_2d; 36412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 3642ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul else if (t->Sampler.MinFilter == GL_LINEAR) { 36432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_linear_2d; 36442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 36452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 364606f606ce5761e673fca3f6b1f7dd40dace8a9906Brian Paul /* check for a few optimized cases */ 364706f606ce5761e673fca3f6b1f7dd40dace8a9906Brian Paul const struct gl_texture_image *img = t->Image[0][t->BaseLevel]; 3648eaf376ba354db11f7729452060570b48a029c9a0Brian Paul const struct swrast_texture_image *swImg = 3649eaf376ba354db11f7729452060570b48a029c9a0Brian Paul swrast_texture_image_const(img); 3650eaf376ba354db11f7729452060570b48a029c9a0Brian Paul 3651ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul ASSERT(t->Sampler.MinFilter == GL_NEAREST); 3652ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul if (t->Sampler.WrapS == GL_REPEAT && 3653ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul t->Sampler.WrapT == GL_REPEAT && 3654eaf376ba354db11f7729452060570b48a029c9a0Brian Paul swImg->_IsPowerOfTwo && 365506f606ce5761e673fca3f6b1f7dd40dace8a9906Brian Paul img->Border == 0 && 36563fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul img->TexFormat == MESA_FORMAT_RGB888) { 36572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &opt_sample_rgb_2d; 36582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 3659ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul else if (t->Sampler.WrapS == GL_REPEAT && 3660ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul t->Sampler.WrapT == GL_REPEAT && 3661eaf376ba354db11f7729452060570b48a029c9a0Brian Paul swImg->_IsPowerOfTwo && 366206f606ce5761e673fca3f6b1f7dd40dace8a9906Brian Paul img->Border == 0 && 36633fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul img->TexFormat == MESA_FORMAT_RGBA8888) { 36642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &opt_sample_rgba_2d; 36652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 36662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 36672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_nearest_2d; 36682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 36692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 36702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_TEXTURE_3D: 36712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (needLambda) { 36722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_lambda_3d; 36732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 3674ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul else if (t->Sampler.MinFilter == GL_LINEAR) { 36752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_linear_3d; 36762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 36772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 3678ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul ASSERT(t->Sampler.MinFilter == GL_NEAREST); 36792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_nearest_3d; 36802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 36812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_TEXTURE_CUBE_MAP: 36822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (needLambda) { 36832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_lambda_cube; 36842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 3685ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul else if (t->Sampler.MinFilter == GL_LINEAR) { 36862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_linear_cube; 36872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 36882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 3689ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul ASSERT(t->Sampler.MinFilter == GL_NEAREST); 36902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_nearest_cube; 36912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 36922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_TEXTURE_RECTANGLE_NV: 3693fde15a2bae2f2ca552763705f12d53e4606feabfBrian if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT) { 3694fde15a2bae2f2ca552763705f12d53e4606feabfBrian return &sample_depth_texture; 3695fde15a2bae2f2ca552763705f12d53e4606feabfBrian } 3696fde15a2bae2f2ca552763705f12d53e4606feabfBrian else if (needLambda) { 36972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_lambda_rect; 36982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 3699ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul else if (t->Sampler.MinFilter == GL_LINEAR) { 37002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_linear_rect; 37012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 37022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 3703ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul ASSERT(t->Sampler.MinFilter == GL_NEAREST); 37042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_nearest_rect; 37052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 3706bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_TEXTURE_1D_ARRAY_EXT: 3707bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (needLambda) { 3708bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick return &sample_lambda_1d_array; 3709bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3710ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul else if (t->Sampler.MinFilter == GL_LINEAR) { 3711bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick return &sample_linear_1d_array; 3712bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3713bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 3714ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul ASSERT(t->Sampler.MinFilter == GL_NEAREST); 3715bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick return &sample_nearest_1d_array; 3716bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3717bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_TEXTURE_2D_ARRAY_EXT: 3718bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (needLambda) { 3719bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick return &sample_lambda_2d_array; 3720bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3721ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul else if (t->Sampler.MinFilter == GL_LINEAR) { 3722bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick return &sample_linear_2d_array; 3723bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3724bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 3725ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul ASSERT(t->Sampler.MinFilter == GL_NEAREST); 3726bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick return &sample_nearest_2d_array; 3727bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 37282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul default: 37292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul _mesa_problem(ctx, 37302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul "invalid target in _swrast_choose_texture_sample_func"); 37312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &null_sample_func; 37322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 37332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 37342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 3735