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" 30f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul#include "main/texobj.h" 31cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen#include "main/samplerobj.h" 322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#include "s_context.h" 342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#include "s_texfilter.h" 352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 37249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian/* 38249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian * Note, the FRAC macro has to work perfectly. Otherwise you'll sometimes 39249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian * see 1-pixel bands of improperly weighted linear-filtered textures. 40249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian * The tests/texwrap.c demo is a good test. 41249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0. 42249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x). 43249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian */ 44249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian#define FRAC(f) ((f) - IFLOOR(f)) 45249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian 46249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian 472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/** 49bd32640f77c72e79fb5dda0e5fd077e564b33b02Brian Paul * Linear interpolation macro 502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#define LERP(T, A, B) ( (A) + (T) * ((B) - (A)) ) 522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/** 552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Do 2D/biliner interpolation of float values. 562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * v00, v10, v01 and v11 are typically four texture samples in a square/box. 572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * a and b are the horizontal and vertical interpolants. 582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * It's important that this function is inlined when compiled with 592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * optimization! If we find that's not true on some systems, convert 602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * to a macro. 612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 629520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLfloat 632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paullerp_2d(GLfloat a, GLfloat b, 642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLfloat v00, GLfloat v10, GLfloat v01, GLfloat v11) 652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat temp0 = LERP(a, v00, v10); 672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat temp1 = LERP(a, v01, v11); 682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return LERP(b, temp0, temp1); 692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/** 732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Do 3D/trilinear interpolation of float values. 742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * \sa lerp_2d 752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 769520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLfloat 772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paullerp_3d(GLfloat a, GLfloat b, GLfloat c, 782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLfloat v000, GLfloat v100, GLfloat v010, GLfloat v110, 792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLfloat v001, GLfloat v101, GLfloat v011, GLfloat v111) 802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat temp00 = LERP(a, v000, v100); 822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat temp10 = LERP(a, v010, v110); 832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat temp01 = LERP(a, v001, v101); 842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat temp11 = LERP(a, v011, v111); 852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat temp0 = LERP(b, temp00, temp10); 862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat temp1 = LERP(b, temp01, temp11); 872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return LERP(c, temp0, temp1); 882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/** 922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Do linear interpolation of colors. 932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 949520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 95de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paullerp_rgba(GLfloat result[4], GLfloat t, const GLfloat a[4], const GLfloat b[4]) 962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul result[0] = LERP(t, a[0], b[0]); 982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul result[1] = LERP(t, a[1], b[1]); 992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul result[2] = LERP(t, a[2], b[2]); 1002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul result[3] = LERP(t, a[3], b[3]); 1012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 1022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 1032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 1042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/** 1052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Do bilinear interpolation of colors. 1062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 1079520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 108de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paullerp_rgba_2d(GLfloat result[4], GLfloat a, GLfloat b, 109de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat t00[4], const GLfloat t10[4], 110de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat t01[4], const GLfloat t11[4]) 1112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 1122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul result[0] = lerp_2d(a, b, t00[0], t10[0], t01[0], t11[0]); 1132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul result[1] = lerp_2d(a, b, t00[1], t10[1], t01[1], t11[1]); 1142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul result[2] = lerp_2d(a, b, t00[2], t10[2], t01[2], t11[2]); 1152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul result[3] = lerp_2d(a, b, t00[3], t10[3], t01[3], t11[3]); 1162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 1172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 1182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 1192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/** 1200f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul * Do trilinear interpolation of colors. 1210f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul */ 1229520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 123de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paullerp_rgba_3d(GLfloat result[4], GLfloat a, GLfloat b, GLfloat c, 124de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat t000[4], const GLfloat t100[4], 125de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat t010[4], const GLfloat t110[4], 126de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat t001[4], const GLfloat t101[4], 127de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat t011[4], const GLfloat t111[4]) 1280f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul{ 1290f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul GLuint k; 1300f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul /* compiler should unroll these short loops */ 1310f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul for (k = 0; k < 4; k++) { 1320f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul result[k] = lerp_3d(a, b, c, t000[k], t100[k], t010[k], t110[k], 1330f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul t001[k], t101[k], t011[k], t111[k]); 1340f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 1350f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul} 1360f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul 1370f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul 1380f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul/** 1395ba62cd4139e95c752453a1591eb3e47b6b18238Brian Paul * Used for GL_REPEAT wrap mode. Using A % B doesn't produce the 1405ba62cd4139e95c752453a1591eb3e47b6b18238Brian Paul * right results for A<0. Casting to A to be unsigned only works if B 1415ba62cd4139e95c752453a1591eb3e47b6b18238Brian Paul * is a power of two. Adding a bias to A (which is a multiple of B) 1425ba62cd4139e95c752453a1591eb3e47b6b18238Brian Paul * avoids the problems with A < 0 (for reasonable A) without using a 1435ba62cd4139e95c752453a1591eb3e47b6b18238Brian Paul * conditional. 1442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 145ed7f4b42307bff4633689d6781cd3643f10041e5Brian Paul#define REMAINDER(A, B) (((A) + (B) * 1024) % (B)) 1462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 1472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 1482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/** 1492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Used to compute texel locations for linear sampling. 1502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Input: 1512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * wrapMode = GL_REPEAT, GL_CLAMP, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER 152249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian * s = texcoord in [0,1] 153249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian * size = width (or height or depth) of texture 1542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Output: 155249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian * i0, i1 = returns two nearest texel indexes 156249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian * weight = returns blend factor between texels 1572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 1589520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 159249e1e4d30759cd3c55cef0dba75f531cc7c6269Brianlinear_texel_locations(GLenum wrapMode, 160249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const struct gl_texture_image *img, 161249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian GLint size, GLfloat s, 162249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian GLint *i0, GLint *i1, GLfloat *weight) 163249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian{ 164eaf376ba354db11f7729452060570b48a029c9a0Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 165249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian GLfloat u; 166249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian switch (wrapMode) { 167249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_REPEAT: 168249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = s * size - 0.5F; 169eaf376ba354db11f7729452060570b48a029c9a0Brian Paul if (swImg->_IsPowerOfTwo) { 170249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i0 = IFLOOR(u) & (size - 1); 171249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i1 = (*i0 + 1) & (size - 1); 172249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian } 173249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else { 174249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i0 = REMAINDER(IFLOOR(u), size); 175249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i1 = REMAINDER(*i0 + 1, size); 176249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian } 177249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian break; 178249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_CLAMP_TO_EDGE: 179249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (s <= 0.0F) 180249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = 0.0F; 181249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else if (s >= 1.0F) 182249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = (GLfloat) size; 183249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 184249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = s * size; 185249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u -= 0.5F; 186249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i0 = IFLOOR(u); 187249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i1 = *i0 + 1; 188249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (*i0 < 0) 189249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i0 = 0; 190249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (*i1 >= (GLint) size) 191249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i1 = size - 1; 192249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian break; 193249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_CLAMP_TO_BORDER: 194249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian { 195249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat min = -1.0F / (2.0F * size); 196249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat max = 1.0F - min; 197249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (s <= min) 198249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = min * size; 199249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else if (s >= max) 200249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = max * size; 201249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 202249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = s * size; 203249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u -= 0.5F; 204249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i0 = IFLOOR(u); 205249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i1 = *i0 + 1; 206249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian } 207249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian break; 208249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_MIRRORED_REPEAT: 209249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian { 210249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLint flr = IFLOOR(s); 211249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (flr & 1) 212249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = 1.0F - (s - (GLfloat) flr); 213249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 214249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = s - (GLfloat) flr; 215249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = (u * size) - 0.5F; 216249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i0 = IFLOOR(u); 217249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i1 = *i0 + 1; 218249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (*i0 < 0) 219249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i0 = 0; 220249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (*i1 >= (GLint) size) 221249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i1 = size - 1; 222249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian } 223249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian break; 224249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_MIRROR_CLAMP_EXT: 225249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = FABSF(s); 226249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (u >= 1.0F) 227249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = (GLfloat) size; 228249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 229249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u *= size; 230249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u -= 0.5F; 231249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i0 = IFLOOR(u); 232249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i1 = *i0 + 1; 233249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian break; 234249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_MIRROR_CLAMP_TO_EDGE_EXT: 235249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = FABSF(s); 236249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (u >= 1.0F) 237249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = (GLfloat) size; 238249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 239249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u *= size; 240249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u -= 0.5F; 241249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i0 = IFLOOR(u); 242249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i1 = *i0 + 1; 243249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (*i0 < 0) 244249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i0 = 0; 245249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (*i1 >= (GLint) size) 246249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i1 = size - 1; 247249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian break; 248249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_MIRROR_CLAMP_TO_BORDER_EXT: 249249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian { 250249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat min = -1.0F / (2.0F * size); 251249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat max = 1.0F - min; 252249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = FABSF(s); 253249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (u <= min) 254249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = min * size; 255249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else if (u >= max) 256249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = max * size; 257249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 258249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u *= size; 259249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u -= 0.5F; 260249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i0 = IFLOOR(u); 261249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i1 = *i0 + 1; 262249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian } 263249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian break; 264249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_CLAMP: 265249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (s <= 0.0F) 266249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = 0.0F; 267249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else if (s >= 1.0F) 268249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = (GLfloat) size; 269249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 270249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = s * size; 271249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u -= 0.5F; 272249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i0 = IFLOOR(u); 273249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i1 = *i0 + 1; 274249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian break; 275249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian default: 276249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian _mesa_problem(NULL, "Bad wrap mode"); 277249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = 0.0F; 27803bbcd447cbaa28b52465ae1045013f1aff420c2Chad Versace break; 279249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian } 280249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *weight = FRAC(u); 2812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 2822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 2832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 2842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/** 2852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Used to compute texel location for nearest sampling. 2862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 2879520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLint 288249e1e4d30759cd3c55cef0dba75f531cc7c6269Briannearest_texel_location(GLenum wrapMode, 289249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const struct gl_texture_image *img, 290249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian GLint size, GLfloat s) 291249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian{ 292eaf376ba354db11f7729452060570b48a029c9a0Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 293249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian GLint i; 294249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian 295249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian switch (wrapMode) { 296249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_REPEAT: 297249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian /* s limited to [0,1) */ 298249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian /* i limited to [0,size-1] */ 299249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = IFLOOR(s * size); 300eaf376ba354db11f7729452060570b48a029c9a0Brian Paul if (swImg->_IsPowerOfTwo) 301249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i &= (size - 1); 302249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 303249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = REMAINDER(i, size); 304249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian return i; 305249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_CLAMP_TO_EDGE: 306249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian { 307249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian /* s limited to [min,max] */ 308249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian /* i limited to [0, size-1] */ 309249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat min = 1.0F / (2.0F * size); 310249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat max = 1.0F - min; 311249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (s < min) 312249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = 0; 313249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else if (s > max) 314249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = size - 1; 315249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 316249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = IFLOOR(s * size); 317249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian } 318249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian return i; 319249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_CLAMP_TO_BORDER: 320249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian { 321249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian /* s limited to [min,max] */ 322249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian /* i limited to [-1, size] */ 323249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat min = -1.0F / (2.0F * size); 324249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat max = 1.0F - min; 325249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (s <= min) 326249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = -1; 327249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else if (s >= max) 328249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = size; 329249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 330249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = IFLOOR(s * size); 331249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian } 332249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian return i; 333249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_MIRRORED_REPEAT: 334249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian { 335249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat min = 1.0F / (2.0F * size); 336249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat max = 1.0F - min; 337249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLint flr = IFLOOR(s); 338249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian GLfloat u; 339249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (flr & 1) 340249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = 1.0F - (s - (GLfloat) flr); 341249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 342249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian u = s - (GLfloat) flr; 343249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (u < min) 344249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = 0; 345249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else if (u > max) 346249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = size - 1; 347249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 348249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = IFLOOR(u * size); 349249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian } 350249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian return i; 351249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_MIRROR_CLAMP_EXT: 352249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian { 353249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian /* s limited to [0,1] */ 354249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian /* i limited to [0,size-1] */ 355249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat u = FABSF(s); 356249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (u <= 0.0F) 357249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = 0; 358249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else if (u >= 1.0F) 359249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = size - 1; 360249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 361249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = IFLOOR(u * size); 362249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian } 363249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian return i; 364249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_MIRROR_CLAMP_TO_EDGE_EXT: 365249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian { 366249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian /* s limited to [min,max] */ 367249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian /* i limited to [0, size-1] */ 368249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat min = 1.0F / (2.0F * size); 369249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat max = 1.0F - min; 370249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat u = FABSF(s); 371249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (u < min) 372249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = 0; 373249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else if (u > max) 374249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = size - 1; 375249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 376249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = IFLOOR(u * size); 377249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian } 378249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian return i; 379249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_MIRROR_CLAMP_TO_BORDER_EXT: 380249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian { 381249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian /* s limited to [min,max] */ 382249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian /* i limited to [0, size-1] */ 383249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat min = -1.0F / (2.0F * size); 384249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat max = 1.0F - min; 385249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian const GLfloat u = FABSF(s); 386249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (u < min) 387249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = -1; 388249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else if (u > max) 389249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = size; 390249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 391249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = IFLOOR(u * size); 392249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian } 393249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian return i; 394249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian case GL_CLAMP: 395249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian /* s limited to [0,1] */ 396249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian /* i limited to [0,size-1] */ 397249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian if (s <= 0.0F) 398249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = 0; 399249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else if (s >= 1.0F) 400249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = size - 1; 401249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian else 402249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian i = IFLOOR(s * size); 403249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian return i; 404249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian default: 405249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian _mesa_problem(NULL, "Bad wrap mode"); 406249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian return 0; 407249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian } 4082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 4092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 4102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 4112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/* Power of two image sizes only */ 4129520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 413249e1e4d30759cd3c55cef0dba75f531cc7c6269Brianlinear_repeat_texel_location(GLuint size, GLfloat s, 414249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian GLint *i0, GLint *i1, GLfloat *weight) 415249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian{ 416249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian GLfloat u = s * size - 0.5F; 417249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i0 = IFLOOR(u) & (size - 1); 418249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *i1 = (*i0 + 1) & (size - 1); 419249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian *weight = FRAC(u); 4202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 4212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 4222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 423792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul/** 424a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul * Do clamp/wrap for a texture rectangle coord, GL_NEAREST filter mode. 425a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul */ 4269520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLint 427a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paulclamp_rect_coord_nearest(GLenum wrapMode, GLfloat coord, GLint max) 428a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul{ 429a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul switch (wrapMode) { 430a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_CLAMP: 431a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return IFLOOR( CLAMP(coord, 0.0F, max - 1) ); 432a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_CLAMP_TO_EDGE: 433a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return IFLOOR( CLAMP(coord, 0.5F, max - 0.5F) ); 434a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_CLAMP_TO_BORDER: 435a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return IFLOOR( CLAMP(coord, -0.5F, max + 0.5F) ); 436a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul default: 437a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul _mesa_problem(NULL, "bad wrapMode in clamp_rect_coord_nearest"); 438a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return 0; 439a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul } 440a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul} 441a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 442a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 443a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul/** 444a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul * As above, but GL_LINEAR filtering. 445a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul */ 4469520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 447a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paulclamp_rect_coord_linear(GLenum wrapMode, GLfloat coord, GLint max, 448a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul GLint *i0out, GLint *i1out, GLfloat *weight) 449a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul{ 450a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul GLfloat fcol; 451a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul GLint i0, i1; 452a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul switch (wrapMode) { 453a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_CLAMP: 454a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul /* Not exactly what the spec says, but it matches NVIDIA output */ 455880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul fcol = CLAMP(coord - 0.5F, 0.0F, max - 1); 456a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul i0 = IFLOOR(fcol); 457a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul i1 = i0 + 1; 458a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul break; 459a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_CLAMP_TO_EDGE: 460a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul fcol = CLAMP(coord, 0.5F, max - 0.5F); 461a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul fcol -= 0.5F; 462a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul i0 = IFLOOR(fcol); 463a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul i1 = i0 + 1; 464a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul if (i1 > max - 1) 465a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul i1 = max - 1; 466a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul break; 467a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_CLAMP_TO_BORDER: 468a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul fcol = CLAMP(coord, -0.5F, max + 0.5F); 469a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul fcol -= 0.5F; 470a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul i0 = IFLOOR(fcol); 471a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul i1 = i0 + 1; 472dcf571aff9de1a4298c4d2c4148d84cdc4daf02eBrian Paul break; 473a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul default: 474a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul _mesa_problem(NULL, "bad wrapMode in clamp_rect_coord_linear"); 475a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul i0 = i1 = 0; 476a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul fcol = 0.0F; 47703bbcd447cbaa28b52465ae1045013f1aff420c2Chad Versace break; 478a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul } 479a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul *i0out = i0; 480a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul *i1out = i1; 481a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul *weight = FRAC(fcol); 482a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul} 483a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 484a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 485a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul/** 48658ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul * Compute slice/image to use for 1D or 2D array texture. 48758ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul */ 4889520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLint 48958ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paultex_array_slice(GLfloat coord, GLsizei size) 49058ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul{ 491bdbb5f8170f48713b741ad68c26464231a01ca7aBrian Paul GLint slice = IFLOOR(coord + 0.5f); 49258ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul slice = CLAMP(slice, 0, size - 1); 49358ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul return slice; 49458ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul} 49558ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul 49658ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul 49758ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul/** 498a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul * Compute nearest integer texcoords for given texobj and coordinate. 4992b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul * NOTE: only used for depth texture sampling. 500a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul */ 5019520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 502cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminennearest_texcoord(const struct gl_sampler_object *samp, 503cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_texture_object *texObj, 5042b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul GLuint level, 505a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul const GLfloat texcoord[4], 506a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul GLint *i, GLint *j, GLint *k) 507a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul{ 5082b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul const struct gl_texture_image *img = texObj->Image[0][level]; 509a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul const GLint width = img->Width; 510a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul const GLint height = img->Height; 511a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul const GLint depth = img->Depth; 512a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 513a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul switch (texObj->Target) { 514a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_TEXTURE_RECTANGLE_ARB: 515cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen *i = clamp_rect_coord_nearest(samp->WrapS, texcoord[0], width); 516cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen *j = clamp_rect_coord_nearest(samp->WrapT, texcoord[1], height); 517a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul *k = 0; 518a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul break; 519a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_TEXTURE_1D: 520cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen *i = nearest_texel_location(samp->WrapS, img, width, texcoord[0]); 521a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul *j = 0; 522a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul *k = 0; 523a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul break; 524a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_TEXTURE_2D: 525cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen *i = nearest_texel_location(samp->WrapS, img, width, texcoord[0]); 526cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen *j = nearest_texel_location(samp->WrapT, img, height, texcoord[1]); 527a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul *k = 0; 528a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul break; 529a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_TEXTURE_1D_ARRAY_EXT: 530cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen *i = nearest_texel_location(samp->WrapS, img, width, texcoord[0]); 53158ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul *j = tex_array_slice(texcoord[1], height); 532a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul *k = 0; 533a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul break; 534a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_TEXTURE_2D_ARRAY_EXT: 535cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen *i = nearest_texel_location(samp->WrapS, img, width, texcoord[0]); 536cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen *j = nearest_texel_location(samp->WrapT, img, height, texcoord[1]); 53758ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul *k = tex_array_slice(texcoord[2], depth); 538a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul break; 539a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul default: 540a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul *i = *j = *k = 0; 54103bbcd447cbaa28b52465ae1045013f1aff420c2Chad Versace break; 542a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul } 543a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul} 544a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 545a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 546a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul/** 547a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul * Compute linear integer texcoords for given texobj and coordinate. 5482b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul * NOTE: only used for depth texture sampling. 549a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul */ 5509520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 551cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminenlinear_texcoord(const struct gl_sampler_object *samp, 552cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_texture_object *texObj, 5532b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul GLuint level, 554a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul const GLfloat texcoord[4], 555a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul GLint *i0, GLint *i1, GLint *j0, GLint *j1, GLint *slice, 556a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul GLfloat *wi, GLfloat *wj) 557a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul{ 5582b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul const struct gl_texture_image *img = texObj->Image[0][level]; 559a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul const GLint width = img->Width; 560a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul const GLint height = img->Height; 561a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul const GLint depth = img->Depth; 562a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 563a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul switch (texObj->Target) { 564a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_TEXTURE_RECTANGLE_ARB: 565cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen clamp_rect_coord_linear(samp->WrapS, texcoord[0], 566a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul width, i0, i1, wi); 567cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen clamp_rect_coord_linear(samp->WrapT, texcoord[1], 568a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul height, j0, j1, wj); 569a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul *slice = 0; 570a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul break; 571a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 572a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_TEXTURE_1D: 573a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_TEXTURE_2D: 574cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen linear_texel_locations(samp->WrapS, img, width, 575a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul texcoord[0], i0, i1, wi); 576cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen linear_texel_locations(samp->WrapT, img, height, 577a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul texcoord[1], j0, j1, wj); 578a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul *slice = 0; 579a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul break; 580a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 581a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_TEXTURE_1D_ARRAY_EXT: 582cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen linear_texel_locations(samp->WrapS, img, width, 583a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul texcoord[0], i0, i1, wi); 58458ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul *j0 = tex_array_slice(texcoord[1], height); 585a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul *j1 = *j0; 586a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul *slice = 0; 587a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul break; 588a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 589a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_TEXTURE_2D_ARRAY_EXT: 590cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen linear_texel_locations(samp->WrapS, img, width, 591a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul texcoord[0], i0, i1, wi); 592cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen linear_texel_locations(samp->WrapT, img, height, 593a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul texcoord[1], j0, j1, wj); 59458ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul *slice = tex_array_slice(texcoord[2], depth); 595a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul break; 596a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 597a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul default: 598a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul *slice = 0; 59903bbcd447cbaa28b52465ae1045013f1aff420c2Chad Versace break; 600a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul } 601a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul} 602a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 603a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 604a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 605a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul/** 606792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul * For linear interpolation between mipmap levels N and N+1, this function 607792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul * computes N. 6082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 6099520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLint 610792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paullinear_mipmap_level(const struct gl_texture_object *tObj, GLfloat lambda) 611792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul{ 612792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul if (lambda < 0.0F) 613792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul return tObj->BaseLevel; 614792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul else if (lambda > tObj->_MaxLambda) 615792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul return (GLint) (tObj->BaseLevel + tObj->_MaxLambda); 616792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul else 617792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul return (GLint) (tObj->BaseLevel + lambda); 6182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 6192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 6202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 621792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul/** 622792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul * Compute the nearest mipmap level to take texels from. 6232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 6249520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLint 625792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paulnearest_mipmap_level(const struct gl_texture_object *tObj, GLfloat lambda) 626792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul{ 627792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLfloat l; 628792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level; 629792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul if (lambda <= 0.5F) 630792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul l = 0.0F; 631792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul else if (lambda > tObj->_MaxLambda + 0.4999F) 632792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul l = tObj->_MaxLambda + 0.4999F; 633792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul else 634792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul l = lambda; 635792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul level = (GLint) (tObj->BaseLevel + l + 0.5F); 636792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul if (level > tObj->_MaxLevel) 637792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul level = tObj->_MaxLevel; 638792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul return level; 6392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 6402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 6412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 6422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 6432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/* 6442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Bitflags for texture border color sampling. 6452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 6462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#define I0BIT 1 6472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#define I1BIT 2 6482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#define J0BIT 4 6492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#define J1BIT 8 6502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#define K0BIT 16 6512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#define K1BIT 32 6522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 6532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 6542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 6556e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** 6562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * The lambda[] array values are always monotonic. Either the whole span 6572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * will be minified, magnified, or split between the two. This function 6582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * determines the subranges in [0, n-1] that are to be minified or magnified. 6592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 6609520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 661cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminencompute_min_mag_ranges(const struct gl_sampler_object *samp, 662aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul GLuint n, const GLfloat lambda[], 663aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul GLuint *minStart, GLuint *minEnd, 664aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul GLuint *magStart, GLuint *magEnd) 6652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 666aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul GLfloat minMagThresh; 667aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul 668aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul /* we shouldn't be here if minfilter == magfilter */ 669cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen ASSERT(samp->MinFilter != samp->MagFilter); 670aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul 671aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul /* This bit comes from the OpenGL spec: */ 672cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen if (samp->MagFilter == GL_LINEAR 673cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen && (samp->MinFilter == GL_NEAREST_MIPMAP_NEAREST || 674cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen samp->MinFilter == GL_NEAREST_MIPMAP_LINEAR)) { 675aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul minMagThresh = 0.5F; 676aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul } 677aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul else { 678aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul minMagThresh = 0.0F; 679aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul } 680792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul 6812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#if 0 682792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul /* DEBUG CODE: Verify that lambda[] is monotonic. 6832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * We can't really use this because the inaccuracy in the LOG2 function 6842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * causes this test to fail, yet the resulting texturing is correct. 6852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 6862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (n > 1) { 6872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 6882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul printf("lambda delta = %g\n", lambda[0] - lambda[n-1]); 6892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (lambda[0] >= lambda[n-1]) { /* decreasing */ 6902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n - 1; i++) { 6912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT((GLint) (lambda[i] * 10) >= (GLint) (lambda[i+1] * 10)); 6922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 6932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 6942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { /* increasing */ 6952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n - 1; i++) { 6962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT((GLint) (lambda[i] * 10) <= (GLint) (lambda[i+1] * 10)); 6972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 6982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 6992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 7002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#endif /* DEBUG */ 7012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 702876b41bc03c9a92263b824378fc2191f85e0a403Brian Paul if (lambda[0] <= minMagThresh && (n <= 1 || lambda[n-1] <= minMagThresh)) { 7032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* magnification for whole span */ 7042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *magStart = 0; 7052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *magEnd = n; 7062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *minStart = *minEnd = 0; 7072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 708876b41bc03c9a92263b824378fc2191f85e0a403Brian Paul else if (lambda[0] > minMagThresh && (n <=1 || lambda[n-1] > minMagThresh)) { 7092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* minification for whole span */ 7102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *minStart = 0; 7112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *minEnd = n; 7122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *magStart = *magEnd = 0; 7132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 7142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 7152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* a mix of minification and magnification */ 7162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 7172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (lambda[0] > minMagThresh) { 7182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* start with minification */ 7192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 1; i < n; i++) { 7202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (lambda[i] <= minMagThresh) 7212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 7222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 7232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *minStart = 0; 7242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *minEnd = i; 7252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *magStart = i; 7262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *magEnd = n; 7272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 7282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 7292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* start with magnification */ 7302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 1; i < n; i++) { 7312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (lambda[i] > minMagThresh) 7322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 7332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 7342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *magStart = 0; 7352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *magEnd = i; 7362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *minStart = i; 7372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul *minEnd = n; 7382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 7392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 7402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 7412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#if 0 7422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* Verify the min/mag Start/End values 7432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * We don't use this either (see above) 7442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 7452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul { 7462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLint i; 7472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 7482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (lambda[i] > minMagThresh) { 7492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* minification */ 7502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(i >= *minStart); 7512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(i < *minEnd); 7522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 7532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 7542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* magnification */ 7552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(i >= *magStart); 7562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(i < *magEnd); 7572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 7582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 7592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 7602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#endif 7612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 7622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 7632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 764b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul/** 765b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul * When we sample the border color, it must be interpreted according to 766b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul * the base texture format. Ex: if the texture base format it GL_ALPHA, 767b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul * we return (0,0,0,BorderAlpha). 768b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul */ 7699520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 770cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminenget_border_color(const struct gl_sampler_object *samp, 771b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul const struct gl_texture_image *img, 772b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul GLfloat rgba[4]) 773b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul{ 7741f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul switch (img->_BaseFormat) { 775b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul case GL_RGB: 776cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen rgba[0] = samp->BorderColor.f[0]; 777cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen rgba[1] = samp->BorderColor.f[1]; 778cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen rgba[2] = samp->BorderColor.f[2]; 779b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul rgba[3] = 1.0F; 780b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul break; 781b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul case GL_ALPHA: 782b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul rgba[0] = rgba[1] = rgba[2] = 0.0; 783cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen rgba[3] = samp->BorderColor.f[3]; 784b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul break; 785b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul case GL_LUMINANCE: 786cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen rgba[0] = rgba[1] = rgba[2] = samp->BorderColor.f[0]; 787b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul rgba[3] = 1.0; 788b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul break; 789b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul case GL_LUMINANCE_ALPHA: 790cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen rgba[0] = rgba[1] = rgba[2] = samp->BorderColor.f[0]; 791cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen rgba[3] = samp->BorderColor.f[3]; 792b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul break; 793b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul case GL_INTENSITY: 794cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen rgba[0] = rgba[1] = rgba[2] = rgba[3] = samp->BorderColor.f[0]; 795b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul break; 796b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul default: 797cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen COPY_4V(rgba, samp->BorderColor.f); 79803bbcd447cbaa28b52465ae1045013f1aff420c2Chad Versace break; 799b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul } 800b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul} 801b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul 802b48eb05f1f547e2b03a22056f3e82ee7b9065337Brian Paul 8039282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul/** 8049282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul * Put z into texel according to GL_DEPTH_MODE. 8059282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul */ 8069282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paulstatic INLINE void 8079282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paulapply_depth_mode(GLenum depthMode, GLfloat z, GLfloat texel[4]) 8089282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul{ 8099282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul switch (depthMode) { 8109282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul case GL_LUMINANCE: 8119282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul ASSIGN_4V(texel, z, z, z, 1.0F); 8129282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul break; 8139282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul case GL_INTENSITY: 8149282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul ASSIGN_4V(texel, z, z, z, z); 8159282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul break; 8169282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul case GL_ALPHA: 8179282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul ASSIGN_4V(texel, 0.0F, 0.0F, 0.0F, z); 8189282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul break; 8199282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul case GL_RED: 8209282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul ASSIGN_4V(texel, z, 0.0F, 0.0F, 1.0F); 8219282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul break; 8229282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul default: 8239282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul _mesa_problem(NULL, "Bad depth texture mode"); 8249282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul } 8259282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul} 8269282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul 8279282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul 8289282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul/** 8299282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul * Is the given texture a depth (or depth/stencil) texture? 8309282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul */ 8319282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paulstatic GLboolean 8329282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paulis_depth_texture(const struct gl_texture_object *tObj) 8339282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul{ 8349282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul GLenum format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat; 8359282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul return format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT; 8369282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul} 8379282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul 8389282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul 8392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/ 8402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/* 1-D Texture Sampling Functions */ 8412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/ 8422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 8436e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** 8442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Return the texture sample for coordinate (s) using GL_NEAREST filter. 8452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 8469520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 847f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_nearest(struct gl_context *ctx, 848cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 8492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image *img, 850de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat texcoord[4], GLfloat rgba[4]) 8512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 852a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 8532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint width = img->Width2; /* without border, power of two */ 8542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLint i; 855cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen i = nearest_texel_location(samp->WrapS, img, width, texcoord[0]); 8562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* skip over the border, if any */ 8572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul i += img->Border; 8582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (i < 0 || i >= (GLint) img->Width) { 8592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* Need this test for GL_CLAMP_TO_BORDER mode */ 860cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, rgba); 8612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 8622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 8635ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i, 0, 0, rgba); 8642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 8652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 8662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 8672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 8686e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** 8692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Return the texture sample for coordinate (s) using GL_LINEAR filter. 8702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 8719520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 872f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_linear(struct gl_context *ctx, 873cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 8742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image *img, 875de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat texcoord[4], GLfloat rgba[4]) 8762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 877a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 8782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint width = img->Width2; 8792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLint i0, i1; 8800f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul GLbitfield useBorderColor = 0x0; 8810f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul GLfloat a; 882de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; /* texels */ 8832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 884cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen linear_texel_locations(samp->WrapS, img, width, texcoord[0], &i0, &i1, &a); 8852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 8862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (img->Border) { 8872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul i0 += img->Border; 8882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul i1 += img->Border; 8892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 8902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 8912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT; 8922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT; 8932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 8942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 8950f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul /* fetch texel colors */ 8960f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul if (useBorderColor & I0BIT) { 897cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, t0); 8982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 8990f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul else { 9005ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i0, 0, 0, t0); 9010f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 9020f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul if (useBorderColor & I1BIT) { 903cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, t1); 9040f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 9050f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul else { 9065ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i1, 0, 0, t1); 9070f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 9080f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul 9090f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul lerp_rgba(rgba, a, t0, t1); 9102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 9112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 9122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 9132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 914f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_nearest_mipmap_nearest(struct gl_context *ctx, 915cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 9162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 9172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 918de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 9192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 9202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 9212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 9222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 923792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = nearest_mipmap_level(tObj, lambda[i]); 924cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_nearest(ctx, samp, tObj->Image[0][level], texcoord[i], rgba[i]); 9252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 9262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 9272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 9282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 9292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 930f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_linear_mipmap_nearest(struct gl_context *ctx, 931cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 9322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 9332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 934de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 9352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 9362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 9372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 9382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 939792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = nearest_mipmap_level(tObj, lambda[i]); 940cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_linear(ctx, samp, tObj->Image[0][level], texcoord[i], rgba[i]); 9412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 9422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 9432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 9442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 9452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 946f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_nearest_mipmap_linear(struct gl_context *ctx, 947cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 9482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 9492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 950de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 9512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 9522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 9532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 9542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 955792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = linear_mipmap_level(tObj, lambda[i]); 9562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (level >= tObj->_MaxLevel) { 957cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_nearest(ctx, samp, tObj->Image[0][tObj->_MaxLevel], 9582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoord[i], rgba[i]); 9592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 9602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 961de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; 9622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat f = FRAC(lambda[i]); 963cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_nearest(ctx, samp, tObj->Image[0][level ], texcoord[i], t0); 964cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_nearest(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1); 9652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lerp_rgba(rgba[i], f, t0, t1); 9662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 9672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 9682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 9692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 9702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 9712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 972f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_linear_mipmap_linear(struct gl_context *ctx, 973cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 9742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 9752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 976de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 9772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 9782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 9792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 9802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 981792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = linear_mipmap_level(tObj, lambda[i]); 9822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (level >= tObj->_MaxLevel) { 983cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_linear(ctx, samp, tObj->Image[0][tObj->_MaxLevel], 9842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoord[i], rgba[i]); 9852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 9862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 987de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; 9882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat f = FRAC(lambda[i]); 989cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_linear(ctx, samp, tObj->Image[0][level ], texcoord[i], t0); 990cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_linear(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1); 9912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lerp_rgba(rgba[i], f, t0, t1); 9922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 9932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 9942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 9952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 9962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 9976e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 1D texture, nearest filtering for both min/magnification */ 9982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 999f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_nearest_1d( struct gl_context *ctx, 1000cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 10012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, GLuint n, 10022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoords[][4], const GLfloat lambda[], 1003de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[][4] ) 10042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 10052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 10062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; 10072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) lambda; 10086e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian for (i = 0; i < n; i++) { 1009cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_nearest(ctx, samp, image, texcoords[i], rgba[i]); 10102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 10112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 10122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 10132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 10146e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 1D texture, linear filtering for both min/magnification */ 10152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 1016f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_linear_1d( struct gl_context *ctx, 1017cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 10182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, GLuint n, 10192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoords[][4], const GLfloat lambda[], 1020de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[][4] ) 10212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 10222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 10232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; 10242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) lambda; 10256e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian for (i = 0; i < n; i++) { 1026cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_linear(ctx, samp, image, texcoords[i], rgba[i]); 10272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 10282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 10292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 10302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 10316e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 1D texture, using lambda to choose between min/magnification */ 10322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 1033f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_lambda_1d( struct gl_context *ctx, 1034cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 10352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, GLuint n, 10362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoords[][4], 1037de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4] ) 10382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 10392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint minStart, minEnd; /* texels with minification */ 10402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint magStart, magEnd; /* texels with magnification */ 10412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 10422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 10432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 1044cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen compute_min_mag_ranges(samp, n, lambda, 1045aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul &minStart, &minEnd, &magStart, &magEnd); 10462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 10472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (minStart < minEnd) { 10482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* do the minified texels */ 10492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLuint m = minEnd - minStart; 1050cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen switch (samp->MinFilter) { 10512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST: 10522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = minStart; i < minEnd; i++) 1053cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel], 10542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoords[i], rgba[i]); 10552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 10562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR: 10572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = minStart; i < minEnd; i++) 1058cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel], 10592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoords[i], rgba[i]); 10602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 10612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST_MIPMAP_NEAREST: 1062cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_nearest_mipmap_nearest(ctx, samp, tObj, m, texcoords + minStart, 10632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 10642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 10652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR_MIPMAP_NEAREST: 1066cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_linear_mipmap_nearest(ctx, samp, tObj, m, texcoords + minStart, 10672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 10682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 10692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST_MIPMAP_LINEAR: 1070cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_nearest_mipmap_linear(ctx, samp, tObj, m, texcoords + minStart, 10712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 10722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 10732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR_MIPMAP_LINEAR: 1074cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_linear_mipmap_linear(ctx, samp, tObj, m, texcoords + minStart, 10752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 10762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 10772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul default: 10782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul _mesa_problem(ctx, "Bad min filter in sample_1d_texture"); 10792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return; 10802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 10812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 10822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 10832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (magStart < magEnd) { 10842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* do the magnified texels */ 1085cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen switch (samp->MagFilter) { 10862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST: 10872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = magStart; i < magEnd; i++) 1088cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel], 10892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoords[i], rgba[i]); 10902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 10912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR: 10922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = magStart; i < magEnd; i++) 1093cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel], 10942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoords[i], rgba[i]); 10952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 10962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul default: 10972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul _mesa_problem(ctx, "Bad mag filter in sample_1d_texture"); 10982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return; 10992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 11002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 11012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 11022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 11032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 11042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/ 11052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/* 2-D Texture Sampling Functions */ 11062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/ 11072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 11082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 11096e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** 11102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Return the texture sample for coordinate (s,t) using GL_NEAREST filter. 11112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 11129520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 1113f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_nearest(struct gl_context *ctx, 1114cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 11152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image *img, 11162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoord[4], 1117de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[]) 11182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 1119a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 11202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint width = img->Width2; /* without border, power of two */ 11212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint height = img->Height2; /* without border, power of two */ 11222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLint i, j; 11232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) ctx; 11242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 1125cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen i = nearest_texel_location(samp->WrapS, img, width, texcoord[0]); 1126cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen j = nearest_texel_location(samp->WrapT, img, height, texcoord[1]); 11272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 11282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* skip over the border, if any */ 11292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul i += img->Border; 11302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul j += img->Border; 11312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 11322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (i < 0 || i >= (GLint) img->Width || j < 0 || j >= (GLint) img->Height) { 11332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* Need this test for GL_CLAMP_TO_BORDER mode */ 1134cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, rgba); 11352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 11362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 11375ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i, j, 0, rgba); 11382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 11392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 11402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 11412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 11422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/** 11432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Return the texture sample for coordinate (s,t) using GL_LINEAR filter. 11442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * New sampling code contributed by Lynn Quam <quam@ai.sri.com>. 11452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 11469520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 1147f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_linear(struct gl_context *ctx, 1148cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 11492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image *img, 11502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoord[4], 1151de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[]) 11522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 1153a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 11542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint width = img->Width2; 11552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint height = img->Height2; 11562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLint i0, j0, i1, j1; 11570f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul GLbitfield useBorderColor = 0x0; 11580f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul GLfloat a, b; 1159de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t00[4], t10[4], t01[4], t11[4]; /* sampled texel colors */ 11602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 1161cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen linear_texel_locations(samp->WrapS, img, width, texcoord[0], &i0, &i1, &a); 1162cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen linear_texel_locations(samp->WrapT, img, height, texcoord[1], &j0, &j1, &b); 11632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 11642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (img->Border) { 11652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul i0 += img->Border; 11662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul i1 += img->Border; 11672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul j0 += img->Border; 11682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul j1 += img->Border; 11692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 11702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 11712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT; 11722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT; 11732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (j0 < 0 || j0 >= height) useBorderColor |= J0BIT; 11742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (j1 < 0 || j1 >= height) useBorderColor |= J1BIT; 11752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 11762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 11770f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul /* fetch four texel colors */ 11780f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul if (useBorderColor & (I0BIT | J0BIT)) { 1179cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, t00); 11800f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 11810f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul else { 11825ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i0, j0, 0, t00); 11830f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 11840f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul if (useBorderColor & (I1BIT | J0BIT)) { 1185cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, t10); 11860f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 11870f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul else { 11885ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i1, j0, 0, t10); 11890f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 11900f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul if (useBorderColor & (I0BIT | J1BIT)) { 1191cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, t01); 11920f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 11930f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul else { 11945ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i0, j1, 0, t01); 11950f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 11960f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul if (useBorderColor & (I1BIT | J1BIT)) { 1197cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, t11); 11980f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 11990f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul else { 12005ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i1, j1, 0, t11); 12012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 12020f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul 12030f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul lerp_rgba_2d(rgba, a, b, t00, t10, t01, t11); 12042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 12052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 12062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 12076e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** 12082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * As above, but we know WRAP_S == REPEAT and WRAP_T == REPEAT. 12092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * We don't have to worry about the texture border. 12102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 12119520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 1212f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_linear_repeat(struct gl_context *ctx, 1213cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 12142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image *img, 12152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoord[4], 1216de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[]) 12172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 1218a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 12192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint width = img->Width2; 12202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint height = img->Height2; 12212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLint i0, j0, i1, j1; 1222249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian GLfloat wi, wj; 1223de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t00[4], t10[4], t01[4], t11[4]; /* sampled texel colors */ 12240f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul 12259ebe3b6d369c946e41b5f6a684a4ac4e3509b67cBrian Paul (void) ctx; 12269ebe3b6d369c946e41b5f6a684a4ac4e3509b67cBrian Paul 1227cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen ASSERT(samp->WrapS == GL_REPEAT); 1228cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen ASSERT(samp->WrapT == GL_REPEAT); 12292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(img->Border == 0); 1230eaf376ba354db11f7729452060570b48a029c9a0Brian Paul ASSERT(swImg->_IsPowerOfTwo); 12312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 1232249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian linear_repeat_texel_location(width, texcoord[0], &i0, &i1, &wi); 1233249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian linear_repeat_texel_location(height, texcoord[1], &j0, &j1, &wj); 12342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 12355ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i0, j0, 0, t00); 12365ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i1, j0, 0, t10); 12375ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i0, j1, 0, t01); 12385ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i1, j1, 0, t11); 12392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 1240249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian lerp_rgba_2d(rgba, wi, wj, t00, t10, t01, t11); 12412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 12422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 12432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 12442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 1245f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_nearest_mipmap_nearest(struct gl_context *ctx, 1246cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 12472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 12482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 1249de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 12502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 12512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 12522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 1253792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = nearest_mipmap_level(tObj, lambda[i]); 1254cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_nearest(ctx, samp, tObj->Image[0][level], texcoord[i], rgba[i]); 12552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 12562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 12572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 12582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 12592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 1260f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_linear_mipmap_nearest(struct gl_context *ctx, 1261cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 12622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 12632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 1264de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 12652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 12662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 12672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 12682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 1269792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = nearest_mipmap_level(tObj, lambda[i]); 1270cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_linear(ctx, samp, tObj->Image[0][level], texcoord[i], rgba[i]); 12712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 12722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 12732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 12742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 12752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 1276f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_nearest_mipmap_linear(struct gl_context *ctx, 1277cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 12782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 12792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 1280de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 12812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 12822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 12832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 12842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 1285792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = linear_mipmap_level(tObj, lambda[i]); 12862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (level >= tObj->_MaxLevel) { 1287cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_nearest(ctx, samp, tObj->Image[0][tObj->_MaxLevel], 12882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoord[i], rgba[i]); 12892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 12902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 1291de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; /* texels */ 12922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat f = FRAC(lambda[i]); 1293cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_nearest(ctx, samp, tObj->Image[0][level ], texcoord[i], t0); 1294cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_nearest(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1); 12952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lerp_rgba(rgba[i], f, t0, t1); 12962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 12972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 12982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 12992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 13002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 13012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 1302f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_linear_mipmap_linear( struct gl_context *ctx, 1303cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 13042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 13052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 1306de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4] ) 13072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 13082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 13092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 13102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 1311792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = linear_mipmap_level(tObj, lambda[i]); 13122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (level >= tObj->_MaxLevel) { 1313cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_linear(ctx, samp, tObj->Image[0][tObj->_MaxLevel], 13142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoord[i], rgba[i]); 13152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 13162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 1317de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; /* texels */ 13182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat f = FRAC(lambda[i]); 1319cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_linear(ctx, samp, tObj->Image[0][level ], texcoord[i], t0); 1320cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_linear(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1); 13212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lerp_rgba(rgba[i], f, t0, t1); 13222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 13232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 13242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 13252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 13262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 13272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 1328f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_linear_mipmap_linear_repeat(struct gl_context *ctx, 1329cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 13306e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const struct gl_texture_object *tObj, 13316e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian GLuint n, const GLfloat texcoord[][4], 1332de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 13332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 13342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 13352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 1336cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen ASSERT(samp->WrapS == GL_REPEAT); 1337cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen ASSERT(samp->WrapT == GL_REPEAT); 13382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 1339792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = linear_mipmap_level(tObj, lambda[i]); 13402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (level >= tObj->_MaxLevel) { 1341cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_linear_repeat(ctx, samp, tObj->Image[0][tObj->_MaxLevel], 13422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoord[i], rgba[i]); 13432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 13442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 1345de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; /* texels */ 13462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat f = FRAC(lambda[i]); 1347cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_linear_repeat(ctx, samp, tObj->Image[0][level ], 13486e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian texcoord[i], t0); 1349cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_linear_repeat(ctx, samp, tObj->Image[0][level+1], 13506e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian texcoord[i], t1); 13512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lerp_rgba(rgba[i], f, t0, t1); 13522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 13532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 13542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 13552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 13562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 13576e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 2D texture, nearest filtering for both min/magnification */ 13582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 1359f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_nearest_2d(struct gl_context *ctx, 1360cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 13616e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const struct gl_texture_object *tObj, GLuint n, 13626e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const GLfloat texcoords[][4], 1363de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 13642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 13652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 13662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; 13672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) lambda; 13686e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian for (i = 0; i < n; i++) { 1369cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_nearest(ctx, samp, image, texcoords[i], rgba[i]); 13702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 13712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 13722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 13732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 13746e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 2D texture, linear filtering for both min/magnification */ 13752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 1376f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_linear_2d(struct gl_context *ctx, 1377cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 13786e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const struct gl_texture_object *tObj, GLuint n, 13796e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const GLfloat texcoords[][4], 1380de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 13812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 13822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 13832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; 1384eaf376ba354db11f7729452060570b48a029c9a0Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(image); 13852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) lambda; 1386cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen if (samp->WrapS == GL_REPEAT && 1387cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen samp->WrapT == GL_REPEAT && 1388eaf376ba354db11f7729452060570b48a029c9a0Brian Paul swImg->_IsPowerOfTwo && 1389c14d969a69d7b9a060c6701d3f18c51eabc56635Brian image->Border == 0) { 13906e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian for (i = 0; i < n; i++) { 1391cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_linear_repeat(ctx, samp, image, texcoords[i], rgba[i]); 13922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 13932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 13942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 13956e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian for (i = 0; i < n; i++) { 1396cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_linear(ctx, samp, image, texcoords[i], rgba[i]); 13972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 13982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 13992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 14002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 14012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 14026e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** 14032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Optimized 2-D texture sampling: 14042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * S and T wrap mode == GL_REPEAT 14052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * GL_NEAREST min/mag filter 14062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * No border, 14072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * RowStride == Width, 14082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Format = GL_RGB 14092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 14102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 1411f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergopt_sample_rgb_2d(struct gl_context *ctx, 1412cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 14136e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const struct gl_texture_object *tObj, 14146e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian GLuint n, const GLfloat texcoords[][4], 14156d63dec41f5399dbe5561175c1652d2ac5ffd4bbBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 14162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 14172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image *img = tObj->Image[0][tObj->BaseLevel]; 1418eaf376ba354db11f7729452060570b48a029c9a0Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 14192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat width = (GLfloat) img->Width; 14202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat height = (GLfloat) img->Height; 14212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint colMask = img->Width - 1; 14222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint rowMask = img->Height - 1; 14232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint shift = img->WidthLog2; 14242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint k; 14252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) ctx; 14262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) lambda; 1427cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen ASSERT(samp->WrapS==GL_REPEAT); 1428cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen ASSERT(samp->WrapT==GL_REPEAT); 14292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(img->Border==0); 14303fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul ASSERT(img->TexFormat == MESA_FORMAT_RGB888); 1431eaf376ba354db11f7729452060570b48a029c9a0Brian Paul ASSERT(swImg->_IsPowerOfTwo); 143226b8dfc8cadf0f1a8604fc77b226cc7de005f9caBrian Paul (void) swImg; 14332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 14342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (k=0; k<n; k++) { 14352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLint i = IFLOOR(texcoords[k][0] * width) & colMask; 14362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLint j = IFLOOR(texcoords[k][1] * height) & rowMask; 14372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLint pos = (j << shift) | i; 1438bd3c10c0f0c60ab3421c2da2eab814edc2296cb0Brian Paul GLubyte *texel = swImg->Map + 3 * pos; 14398c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul rgba[k][RCOMP] = UBYTE_TO_FLOAT(texel[2]); 14403fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul rgba[k][GCOMP] = UBYTE_TO_FLOAT(texel[1]); 14418c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul rgba[k][BCOMP] = UBYTE_TO_FLOAT(texel[0]); 14426a0255122a7d7c0aa09bceacda90a5cea67d5ee2Brian Paul rgba[k][ACOMP] = 1.0F; 14432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 14442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 14452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 14462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 14476e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** 14482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Optimized 2-D texture sampling: 14492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * S and T wrap mode == GL_REPEAT 14502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * GL_NEAREST min/mag filter 14512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * No border 14522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * RowStride == Width, 14532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Format = GL_RGBA 14542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 14552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 1456f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergopt_sample_rgba_2d(struct gl_context *ctx, 1457cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 14586e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const struct gl_texture_object *tObj, 14596e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian GLuint n, const GLfloat texcoords[][4], 14606d63dec41f5399dbe5561175c1652d2ac5ffd4bbBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 14612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 14622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image *img = tObj->Image[0][tObj->BaseLevel]; 1463eaf376ba354db11f7729452060570b48a029c9a0Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 14642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat width = (GLfloat) img->Width; 14652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat height = (GLfloat) img->Height; 14662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint colMask = img->Width - 1; 14672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint rowMask = img->Height - 1; 14682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint shift = img->WidthLog2; 14692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 14702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) ctx; 14712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) lambda; 1472cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen ASSERT(samp->WrapS==GL_REPEAT); 1473cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen ASSERT(samp->WrapT==GL_REPEAT); 14742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(img->Border==0); 14753fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul ASSERT(img->TexFormat == MESA_FORMAT_RGBA8888); 1476eaf376ba354db11f7729452060570b48a029c9a0Brian Paul ASSERT(swImg->_IsPowerOfTwo); 147726b8dfc8cadf0f1a8604fc77b226cc7de005f9caBrian Paul (void) swImg; 14782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 14792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 14802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint col = IFLOOR(texcoords[i][0] * width) & colMask; 14812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint row = IFLOOR(texcoords[i][1] * height) & rowMask; 14822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint pos = (row << shift) | col; 1483bd3c10c0f0c60ab3421c2da2eab814edc2296cb0Brian Paul const GLuint texel = *((GLuint *) swImg->Map + pos); 14841e7517f059b1f3601502a199b05453eabfe56cdbBrian Paul rgba[i][RCOMP] = UBYTE_TO_FLOAT( (texel >> 24) ); 14851e7517f059b1f3601502a199b05453eabfe56cdbBrian Paul rgba[i][GCOMP] = UBYTE_TO_FLOAT( (texel >> 16) & 0xff ); 14861e7517f059b1f3601502a199b05453eabfe56cdbBrian Paul rgba[i][BCOMP] = UBYTE_TO_FLOAT( (texel >> 8) & 0xff ); 14871e7517f059b1f3601502a199b05453eabfe56cdbBrian Paul rgba[i][ACOMP] = UBYTE_TO_FLOAT( (texel ) & 0xff ); 14882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 14892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 14902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 14912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 14926e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 2D texture, using lambda to choose between min/magnification */ 14932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 1494f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_lambda_2d(struct gl_context *ctx, 1495cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 14966e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const struct gl_texture_object *tObj, 14976e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian GLuint n, const GLfloat texcoords[][4], 1498de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 14992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 15002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image *tImg = tObj->Image[0][tObj->BaseLevel]; 1501eaf376ba354db11f7729452060570b48a029c9a0Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(tImg); 15022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint minStart, minEnd; /* texels with minification */ 15032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint magStart, magEnd; /* texels with magnification */ 15042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 1505cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const GLboolean repeatNoBorderPOT = (samp->WrapS == GL_REPEAT) 1506cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen && (samp->WrapT == GL_REPEAT) 15076e0f9001fe3fb191c2928bd09aa9e9d05ddf4ea9Brian Paul && (tImg->Border == 0 && (tImg->Width == swImg->RowStride)) 1508eaf376ba354db11f7729452060570b48a029c9a0Brian Paul && swImg->_IsPowerOfTwo; 15092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 15102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 1511cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen compute_min_mag_ranges(samp, n, lambda, 1512aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul &minStart, &minEnd, &magStart, &magEnd); 15132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 15142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (minStart < minEnd) { 15152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* do the minified texels */ 15162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLuint m = minEnd - minStart; 1517cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen switch (samp->MinFilter) { 15182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST: 15192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (repeatNoBorderPOT) { 15201f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul switch (tImg->TexFormat) { 15213fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul case MESA_FORMAT_RGB888: 1522cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen opt_sample_rgb_2d(ctx, samp, tObj, m, texcoords + minStart, 15232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul NULL, rgba + minStart); 15242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 15253fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul case MESA_FORMAT_RGBA8888: 1526cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen opt_sample_rgba_2d(ctx, samp, tObj, m, texcoords + minStart, 15272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul NULL, rgba + minStart); 15282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 15292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul default: 1530cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_nearest_2d(ctx, samp, tObj, m, texcoords + minStart, 15312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul NULL, rgba + minStart ); 15322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 15332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 15342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 1535cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_nearest_2d(ctx, samp, tObj, m, texcoords + minStart, 15362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul NULL, rgba + minStart); 15372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 15382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 15392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR: 1540cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_linear_2d(ctx, samp, tObj, m, texcoords + minStart, 15412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul NULL, rgba + minStart); 15422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 15432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST_MIPMAP_NEAREST: 1544cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_nearest_mipmap_nearest(ctx, samp, tObj, m, 15452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoords + minStart, 15462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 15472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 15482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR_MIPMAP_NEAREST: 1549cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_linear_mipmap_nearest(ctx, samp, tObj, m, texcoords + minStart, 15502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 15512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 15522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST_MIPMAP_LINEAR: 1553cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_nearest_mipmap_linear(ctx, samp, tObj, m, texcoords + minStart, 15542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 15552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 15562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR_MIPMAP_LINEAR: 15572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (repeatNoBorderPOT) 1558cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_linear_mipmap_linear_repeat(ctx, samp, tObj, m, 15592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoords + minStart, lambda + minStart, rgba + minStart); 15602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else 1561cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_linear_mipmap_linear(ctx, samp, tObj, m, texcoords + minStart, 15622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 15632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 15642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul default: 15652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul _mesa_problem(ctx, "Bad min filter in sample_2d_texture"); 15662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return; 15672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 15682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 15692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 15702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (magStart < magEnd) { 15712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* do the magnified texels */ 15722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLuint m = magEnd - magStart; 15732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 1574cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen switch (samp->MagFilter) { 15752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST: 15762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (repeatNoBorderPOT) { 15771f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul switch (tImg->TexFormat) { 15783fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul case MESA_FORMAT_RGB888: 1579cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen opt_sample_rgb_2d(ctx, samp, tObj, m, texcoords + magStart, 15802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul NULL, rgba + magStart); 15812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 15823fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul case MESA_FORMAT_RGBA8888: 1583cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen opt_sample_rgba_2d(ctx, samp, tObj, m, texcoords + magStart, 15842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul NULL, rgba + magStart); 15852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 15862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul default: 1587cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_nearest_2d(ctx, samp, tObj, m, texcoords + magStart, 15882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul NULL, rgba + magStart ); 15892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 15902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 15912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 1592cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_nearest_2d(ctx, samp, tObj, m, texcoords + magStart, 15932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul NULL, rgba + magStart); 15942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 15952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 15962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR: 1597cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_linear_2d(ctx, samp, tObj, m, texcoords + magStart, 15982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul NULL, rgba + magStart); 15992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 16002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul default: 16012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul _mesa_problem(ctx, "Bad mag filter in sample_lambda_2d"); 160203bbcd447cbaa28b52465ae1045013f1aff420c2Chad Versace break; 16032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 16042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 16052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 16062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 16072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 16088a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger/* For anisotropic filtering */ 16098a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger#define WEIGHT_LUT_SIZE 1024 16108a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 16118a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengerstatic GLfloat *weightLut = NULL; 16128a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 16138a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger/** 16148a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * Creates the look-up table used to speed-up EWA sampling 16158a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 16168a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengerstatic void 16178a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengercreate_filter_table(void) 16188a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger{ 16198a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLuint i; 16208a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger if (!weightLut) { 16218a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger weightLut = (GLfloat *) malloc(WEIGHT_LUT_SIZE * sizeof(GLfloat)); 16228a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 16238a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger for (i = 0; i < WEIGHT_LUT_SIZE; ++i) { 16248a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat alpha = 2; 16258a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat r2 = (GLfloat) i / (GLfloat) (WEIGHT_LUT_SIZE - 1); 16268a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat weight = (GLfloat) exp(-alpha * r2); 16278a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger weightLut[i] = weight; 16288a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 16298a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 16308a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger} 16318a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 16328a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 16338a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger/** 16348a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * Elliptical weighted average (EWA) filter for producing high quality 16358a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * anisotropic filtered results. 16368a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * Based on the Higher Quality Elliptical Weighted Avarage Filter 16378a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * published by Paul S. Heckbert in his Master's Thesis 16388a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * "Fundamentals of Texture Mapping and Image Warping" (1989) 16398a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 16408a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengerstatic void 16418a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengersample_2d_ewa(struct gl_context *ctx, 1642cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 16438a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const struct gl_texture_object *tObj, 16448a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat texcoord[4], 16458a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat dudx, const GLfloat dvdx, 16468a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat dudy, const GLfloat dvdy, const GLint lod, 16478a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat rgba[]) 16488a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger{ 16498a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLint level = lod > 0 ? lod : 0; 16508a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat scaling = 1.0 / (1 << level); 16518a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const struct gl_texture_image *img = tObj->Image[0][level]; 16528a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const struct gl_texture_image *mostDetailedImage = 16538a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger tObj->Image[0][tObj->BaseLevel]; 1654980f6f1b37ca88529b3e000235156eab93254facBrian Paul const struct swrast_texture_image *swImg = 1655980f6f1b37ca88529b3e000235156eab93254facBrian Paul swrast_texture_image_const(mostDetailedImage); 1656980f6f1b37ca88529b3e000235156eab93254facBrian Paul GLfloat tex_u=-0.5 + texcoord[0] * swImg->WidthScale * scaling; 1657980f6f1b37ca88529b3e000235156eab93254facBrian Paul GLfloat tex_v=-0.5 + texcoord[1] * swImg->HeightScale * scaling; 16588a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 16598a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat ux = dudx * scaling; 16608a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat vx = dvdx * scaling; 16618a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat uy = dudy * scaling; 16628a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat vy = dvdy * scaling; 16638a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 16648a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* compute ellipse coefficients to bound the region: 16658a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * A*x*x + B*x*y + C*y*y = F. 16668a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 16678a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat A = vx*vx+vy*vy+1; 16688a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat B = -2*(ux*vx+uy*vy); 16698a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat C = ux*ux+uy*uy+1; 16708a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat F = A*C-B*B/4.0; 16718a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 16728a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* check if it is an ellipse */ 16738a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* ASSERT(F > 0.0); */ 16748a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 16758a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* Compute the ellipse's (u,v) bounding box in texture space */ 16768a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat d = -B*B+4.0*C*A; 16778a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat box_u = 2.0 / d * sqrt(d*C*F); /* box_u -> half of bbox with */ 16788a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat box_v = 2.0 / d * sqrt(A*d*F); /* box_v -> half of bbox height */ 16798a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 16808a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLint u0 = floor(tex_u - box_u); 16818a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLint u1 = ceil (tex_u + box_u); 16828a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLint v0 = floor(tex_v - box_v); 16838a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLint v1 = ceil (tex_v + box_v); 16848a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 16858a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat num[4] = {0.0F, 0.0F, 0.0F, 0.0F}; 16868a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat newCoord[2]; 16878a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat den = 0.0F; 16888a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat ddq; 16898a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat U = u0 - tex_u; 16908a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLint v; 16918a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 16928a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* Scale ellipse formula to directly index the Filter Lookup Table. 16938a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * i.e. scale so that F = WEIGHT_LUT_SIZE-1 16948a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 16958a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger double formScale = (double) (WEIGHT_LUT_SIZE - 1) / F; 16968a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger A *= formScale; 16978a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger B *= formScale; 16988a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger C *= formScale; 16998a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* F *= formScale; */ /* no need to scale F as we don't use it below here */ 17008a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 17018a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* Heckbert MS thesis, p. 59; scan over the bounding box of the ellipse 17028a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * and incrementally update the value of Ax^2+Bxy*Cy^2; when this 17038a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * value, q, is less than F, we're inside the ellipse 17048a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 17058a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger ddq = 2 * A; 17068a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger for (v = v0; v <= v1; ++v) { 17078a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat V = v - tex_v; 17088a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat dq = A * (2 * U + 1) + B * V; 17098a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat q = (C * V + B * U) * V + A * U * U; 17108a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 17118a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLint u; 17128a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger for (u = u0; u <= u1; ++u) { 17138a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* Note that the ellipse has been pre-scaled so F = WEIGHT_LUT_SIZE - 1 */ 17148a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger if (q < WEIGHT_LUT_SIZE) { 17158a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* as a LUT is used, q must never be negative; 17168a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * should not happen, though 17178a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 17188a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLint qClamped = q >= 0.0F ? q : 0; 17198a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat weight = weightLut[qClamped]; 17208a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 17218a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger newCoord[0] = u / ((GLfloat) img->Width2); 17228a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger newCoord[1] = v / ((GLfloat) img->Height2); 17238a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 1724cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_nearest(ctx, samp, img, newCoord, rgba); 17258a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger num[0] += weight * rgba[0]; 17268a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger num[1] += weight * rgba[1]; 17278a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger num[2] += weight * rgba[2]; 17288a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger num[3] += weight * rgba[3]; 17298a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 17308a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger den += weight; 17318a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 17328a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger q += dq; 17338a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger dq += ddq; 17348a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 17358a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 17368a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 17378a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger if (den <= 0.0F) { 17388a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* Reaching this place would mean 17398a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * that no pixels intersected the ellipse. 17408a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * This should never happen because 17418a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * the filter we use always 17428a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * intersects at least one pixel. 17438a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 17448a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 17458a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /*rgba[0]=0; 17468a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger rgba[1]=0; 17478a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger rgba[2]=0; 17488a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger rgba[3]=0;*/ 17498a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* not enough pixels in resampling, resort to direct interpolation */ 1750cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_linear(ctx, samp, img, texcoord, rgba); 17518a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger return; 17528a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 17538a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 17548a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger rgba[0] = num[0] / den; 17558a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger rgba[1] = num[1] / den; 17568a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger rgba[2] = num[2] / den; 17578a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger rgba[3] = num[3] / den; 17588a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger} 17598a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 17608a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 17618a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger/** 17628a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * Anisotropic filtering using footprint assembly as outlined in the 17638a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * EXT_texture_filter_anisotropic spec: 17648a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * http://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt 17658a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * Faster than EWA but has less quality (more aliasing effects) 17668a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 17678a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengerstatic void 17688a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengersample_2d_footprint(struct gl_context *ctx, 1769cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 17708a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const struct gl_texture_object *tObj, 17718a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat texcoord[4], 17728a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat dudx, const GLfloat dvdx, 17738a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat dudy, const GLfloat dvdy, const GLint lod, 17748a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat rgba[]) 17758a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger{ 17768a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLint level = lod > 0 ? lod : 0; 17778a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat scaling = 1.0F / (1 << level); 17788a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const struct gl_texture_image *img = tObj->Image[0][level]; 17798a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 17808a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat ux = dudx * scaling; 17818a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat vx = dvdx * scaling; 17828a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat uy = dudy * scaling; 17838a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat vy = dvdy * scaling; 17848a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 17858a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat Px2 = ux * ux + vx * vx; /* squared length of dx */ 17868a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat Py2 = uy * uy + vy * vy; /* squared length of dy */ 17878a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 17888a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLint numSamples; 17898a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat ds; 17908a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat dt; 17918a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 17928a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat num[4] = {0.0F, 0.0F, 0.0F, 0.0F}; 17938a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat newCoord[2]; 17948a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLint s; 17958a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 17968a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* Calculate the per anisotropic sample offsets in s,t space. */ 17978a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger if (Px2 > Py2) { 17988a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger numSamples = ceil(SQRTF(Px2)); 17998a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger ds = ux / ((GLfloat) img->Width2); 18008a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger dt = vx / ((GLfloat) img->Height2); 18018a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 18028a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger else { 18038a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger numSamples = ceil(SQRTF(Py2)); 18048a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger ds = uy / ((GLfloat) img->Width2); 18058a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger dt = vy / ((GLfloat) img->Height2); 18068a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 18078a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 18088a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger for (s = 0; s<numSamples; s++) { 18098a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger newCoord[0] = texcoord[0] + ds * ((GLfloat)(s+1) / (numSamples+1) -0.5); 18108a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger newCoord[1] = texcoord[1] + dt * ((GLfloat)(s+1) / (numSamples+1) -0.5); 18118a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 1812cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_linear(ctx, samp, img, newCoord, rgba); 18138a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger num[0] += rgba[0]; 18148a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger num[1] += rgba[1]; 18158a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger num[2] += rgba[2]; 18168a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger num[3] += rgba[3]; 18178a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 18188a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 18198a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger rgba[0] = num[0] / numSamples; 18208a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger rgba[1] = num[1] / numSamples; 18218a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger rgba[2] = num[2] / numSamples; 18228a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger rgba[3] = num[3] / numSamples; 18238a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger} 18248a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 18258a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 18268a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger/** 18278a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * Returns the index of the specified texture object in the 18288a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * gl_context texture unit array. 18298a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 18309520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLuint 18318a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengertexture_unit_index(const struct gl_context *ctx, 18328a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const struct gl_texture_object *tObj) 18338a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger{ 18348a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLuint maxUnit 18358a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger = (ctx->Texture._EnabledCoordUnits > 1) ? ctx->Const.MaxTextureUnits : 1; 18368a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLuint u; 18378a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 18388a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* XXX CoordUnits vs. ImageUnits */ 18398a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger for (u = 0; u < maxUnit; u++) { 18408a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger if (ctx->Texture.Unit[u]._Current == tObj) 18418a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger break; /* found */ 18428a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 18438a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger if (u >= maxUnit) 18448a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger u = 0; /* not found, use 1st one; should never happen */ 18458a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 18468a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger return u; 18478a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger} 18488a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 18498a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 18508a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger/** 18518a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * Sample 2D texture using an anisotropic filter. 18528a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * NOTE: the const GLfloat lambda_iso[] parameter does *NOT* contain 18538a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * the lambda float array but a "hidden" SWspan struct which is required 18548a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * by this function but is not available in the texture_sample_func signature. 18558a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * See _swrast_texture_span( struct gl_context *ctx, SWspan *span ) on how 18568a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * this function is called. 18578a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 18588a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengerstatic void 18598a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faengersample_lambda_2d_aniso(struct gl_context *ctx, 1860cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 18618a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const struct gl_texture_object *tObj, 18628a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLuint n, const GLfloat texcoords[][4], 18638a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat lambda_iso[], GLfloat rgba[][4]) 18648a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger{ 18658a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const struct gl_texture_image *tImg = tObj->Image[0][tObj->BaseLevel]; 1866980f6f1b37ca88529b3e000235156eab93254facBrian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(tImg); 18678a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat maxEccentricity = 1868cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen samp->MaxAnisotropy * samp->MaxAnisotropy; 18698a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 18708a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* re-calculate the lambda values so that they are usable with anisotropic 18718a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * filtering 18728a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 18738a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger SWspan *span = (SWspan *)lambda_iso; /* access the "hidden" SWspan struct */ 18748a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 18758a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* based on interpolate_texcoords(struct gl_context *ctx, SWspan *span) 18768a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * in swrast/s_span.c 18778a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 18788a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 18798a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* find the texture unit index by looking up the current texture object 18808a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * from the context list of available texture objects. 18818a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 18828a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLuint u = texture_unit_index(ctx, tObj); 18838a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLuint attr = FRAG_ATTRIB_TEX0 + u; 18848a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat texW, texH; 18858a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 18868a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat dsdx = span->attrStepX[attr][0]; 18878a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat dsdy = span->attrStepY[attr][0]; 18888a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat dtdx = span->attrStepX[attr][1]; 18898a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat dtdy = span->attrStepY[attr][1]; 18908a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat dqdx = span->attrStepX[attr][3]; 18918a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat dqdy = span->attrStepY[attr][3]; 18928a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat s = span->attrStart[attr][0] + span->leftClip * dsdx; 18938a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat t = span->attrStart[attr][1] + span->leftClip * dtdx; 18948a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat q = span->attrStart[attr][3] + span->leftClip * dqdx; 18958a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 18968a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* from swrast/s_texcombine.c _swrast_texture_span */ 18978a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u]; 18988a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLboolean adjustLOD = 1899cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen (texUnit->LodBias + samp->LodBias != 0.0F) 1900cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen || (samp->MinLod != -1000.0 || samp->MaxLod != 1000.0); 19018a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 19028a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLuint i; 19038a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 19048a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* on first access create the lookup table containing the filter weights. */ 19058a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger if (!weightLut) { 19068a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger create_filter_table(); 19078a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 19088a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 1909980f6f1b37ca88529b3e000235156eab93254facBrian Paul texW = swImg->WidthScale; 1910980f6f1b37ca88529b3e000235156eab93254facBrian Paul texH = swImg->HeightScale; 19118a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 19128a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger for (i = 0; i < n; i++) { 19138a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); 19148a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 19158a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat dudx = texW * ((s + dsdx) / (q + dqdx) - s * invQ); 19168a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat dvdx = texH * ((t + dtdx) / (q + dqdx) - t * invQ); 19178a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat dudy = texW * ((s + dsdy) / (q + dqdy) - s * invQ); 19188a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat dvdy = texH * ((t + dtdy) / (q + dqdy) - t * invQ); 19198a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 19208a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* note: instead of working with Px and Py, we will use the 19218a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * squared length instead, to avoid sqrt. 19228a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 19238a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat Px2 = dudx * dudx + dvdx * dvdx; 19248a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat Py2 = dudy * dudy + dvdy * dvdy; 19258a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 19268a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat Pmax2; 19278a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat Pmin2; 19288a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat e; 19298a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger GLfloat lod; 19308a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 19318a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger s += dsdx; 19328a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger t += dtdx; 19338a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger q += dqdx; 19348a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 19358a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger if (Px2 < Py2) { 19368a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger Pmax2 = Py2; 19378a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger Pmin2 = Px2; 19388a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 19398a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger else { 19408a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger Pmax2 = Px2; 19418a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger Pmin2 = Py2; 19428a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 19438a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 19448a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* if the eccentricity of the ellipse is too big, scale up the shorter 19458a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * of the two vectors to limit the maximum amount of work per pixel 19468a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 19478a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger e = Pmax2 / Pmin2; 19488a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger if (e > maxEccentricity) { 19498a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* GLfloat s=e / maxEccentricity; 19508a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger minor[0] *= s; 19518a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger minor[1] *= s; 19528a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger Pmin2 *= s; */ 19538a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger Pmin2 = Pmax2 / maxEccentricity; 19548a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 19558a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 19568a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* note: we need to have Pmin=sqrt(Pmin2) here, but we can avoid 19578a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * this since 0.5*log(x) = log(sqrt(x)) 19588a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 19598a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger lod = 0.5 * LOG2(Pmin2); 19608a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 19618a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger if (adjustLOD) { 19628a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* from swrast/s_texcombine.c _swrast_texture_span */ 1963cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen if (texUnit->LodBias + samp->LodBias != 0.0F) { 19648a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* apply LOD bias, but don't clamp yet */ 19658a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger const GLfloat bias = 1966cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen CLAMP(texUnit->LodBias + samp->LodBias, 19678a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger -ctx->Const.MaxTextureLodBias, 19688a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger ctx->Const.MaxTextureLodBias); 19698a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger lod += bias; 19708a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 1971cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen if (samp->MinLod != -1000.0 || 1972cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen samp->MaxLod != 1000.0) { 19738a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* apply LOD clamping to lambda */ 1974cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen lod = CLAMP(lod, samp->MinLod, samp->MaxLod); 19758a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 19768a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 19778a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 19788a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 19798a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* If the ellipse covers the whole image, we can 19808a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * simply return the average of the whole image. 19818a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 19828a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger if (lod >= tObj->_MaxLevel) { 1983cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_linear(ctx, samp, tObj->Image[0][tObj->_MaxLevel], 19848a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger texcoords[i], rgba[i]); 19858a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 19868a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger else { 19878a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* don't bother interpolating between multiple LODs; it doesn't 19888a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * seem to be worth the extra running time. 19898a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 1990cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_ewa(ctx, samp, tObj, texcoords[i], 19918a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger dudx, dvdx, dudy, dvdy, floor(lod), rgba[i]); 19928a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 19938a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* unused: */ 19948a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger (void) sample_2d_footprint; 19958a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* 19968a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger sample_2d_footprint(ctx, tObj, texcoords[i], 19978a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger dudx, dvdx, dudy, dvdy, floor(lod), rgba[i]); 19988a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 19998a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 20008a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 20018a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger} 20028a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 20038a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger 20042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 20052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/ 20062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/* 3-D Texture Sampling Functions */ 20072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/ 20082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 20096e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** 20102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter. 20112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 20129520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline void 2013f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_3d_nearest(struct gl_context *ctx, 2014cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 20152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image *img, 20162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoord[4], 2017de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[4]) 20182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 2019a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 20202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint width = img->Width2; /* without border, power of two */ 20212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint height = img->Height2; /* without border, power of two */ 20222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint depth = img->Depth2; /* without border, power of two */ 20232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLint i, j, k; 20242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) ctx; 20252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 2026cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen i = nearest_texel_location(samp->WrapS, img, width, texcoord[0]); 2027cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen j = nearest_texel_location(samp->WrapT, img, height, texcoord[1]); 2028cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen k = nearest_texel_location(samp->WrapR, img, depth, texcoord[2]); 20292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 20302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (i < 0 || i >= (GLint) img->Width || 20312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul j < 0 || j >= (GLint) img->Height || 20322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul k < 0 || k >= (GLint) img->Depth) { 20332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* Need this test for GL_CLAMP_TO_BORDER mode */ 2034cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, rgba); 20352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 20362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 20375ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i, j, k, rgba); 20382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 20392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 20402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 20412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 20426e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** 20432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter. 20442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 20452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2046f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_3d_linear(struct gl_context *ctx, 2047cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 20482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image *img, 20492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoord[4], 2050de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[4]) 20512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 2052a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 20532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint width = img->Width2; 20542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint height = img->Height2; 20552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLint depth = img->Depth2; 20562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLint i0, j0, k0, i1, j1, k1; 20570f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul GLbitfield useBorderColor = 0x0; 20580f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul GLfloat a, b, c; 2059de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t000[4], t010[4], t001[4], t011[4]; 2060de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t100[4], t110[4], t101[4], t111[4]; 20612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 2062cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen linear_texel_locations(samp->WrapS, img, width, texcoord[0], &i0, &i1, &a); 2063cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen linear_texel_locations(samp->WrapT, img, height, texcoord[1], &j0, &j1, &b); 2064cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen linear_texel_locations(samp->WrapR, img, depth, texcoord[2], &k0, &k1, &c); 20652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 20662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (img->Border) { 20672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul i0 += img->Border; 20682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul i1 += img->Border; 20692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul j0 += img->Border; 20702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul j1 += img->Border; 20712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul k0 += img->Border; 20722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul k1 += img->Border; 20732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 20742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 20752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* check if sampling texture border color */ 20762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT; 20772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT; 20782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (j0 < 0 || j0 >= height) useBorderColor |= J0BIT; 20792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (j1 < 0 || j1 >= height) useBorderColor |= J1BIT; 20802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (k0 < 0 || k0 >= depth) useBorderColor |= K0BIT; 20812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (k1 < 0 || k1 >= depth) useBorderColor |= K1BIT; 20822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 20832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 20840f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul /* Fetch texels */ 20850f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul if (useBorderColor & (I0BIT | J0BIT | K0BIT)) { 2086cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, t000); 20870f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 20880f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul else { 20895ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i0, j0, k0, t000); 20900f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 20910f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul if (useBorderColor & (I1BIT | J0BIT | K0BIT)) { 2092cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, t100); 20930f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 20940f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul else { 20955ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i1, j0, k0, t100); 20960f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 20970f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul if (useBorderColor & (I0BIT | J1BIT | K0BIT)) { 2098cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, t010); 20990f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 21000f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul else { 21015ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i0, j1, k0, t010); 21020f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 21030f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul if (useBorderColor & (I1BIT | J1BIT | K0BIT)) { 2104cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, t110); 21050f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 21060f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul else { 21075ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i1, j1, k0, t110); 21080f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 21092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 21100f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul if (useBorderColor & (I0BIT | J0BIT | K1BIT)) { 2111cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, t001); 21120f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 21130f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul else { 21145ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i0, j0, k1, t001); 21150f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 21160f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul if (useBorderColor & (I1BIT | J0BIT | K1BIT)) { 2117cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, t101); 21180f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 21190f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul else { 21205ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i1, j0, k1, t101); 21210f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 21220f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul if (useBorderColor & (I0BIT | J1BIT | K1BIT)) { 2123cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, t011); 21240f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 21250f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul else { 21265ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i0, j1, k1, t011); 21272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 21280f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul if (useBorderColor & (I1BIT | J1BIT | K1BIT)) { 2129cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, t111); 21300f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 21310f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul else { 21325ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i1, j1, k1, t111); 21330f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul } 21340f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul 21350f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul /* trilinear interpolation of samples */ 21360f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul lerp_rgba_3d(rgba, a, b, c, t000, t100, t010, t110, t001, t101, t011, t111); 21372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 21382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 21392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 21402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2141f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_3d_nearest_mipmap_nearest(struct gl_context *ctx, 2142cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 21432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 21442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 2145de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4] ) 21462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 21472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 21482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 2149792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = nearest_mipmap_level(tObj, lambda[i]); 2150cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_3d_nearest(ctx, samp, tObj->Image[0][level], texcoord[i], rgba[i]); 21512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 21522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 21532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 21542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 21552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2156f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_3d_linear_mipmap_nearest(struct gl_context *ctx, 2157cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 21582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 21592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 2160de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 21612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 21622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 21632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 21642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 2165792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = nearest_mipmap_level(tObj, lambda[i]); 2166cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_3d_linear(ctx, samp, tObj->Image[0][level], texcoord[i], rgba[i]); 21672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 21682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 21692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 21702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 21712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2172f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_3d_nearest_mipmap_linear(struct gl_context *ctx, 2173cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 21742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 21752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 2176de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 21772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 21782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 21792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 21802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 2181792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = linear_mipmap_level(tObj, lambda[i]); 21822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (level >= tObj->_MaxLevel) { 2183cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_3d_nearest(ctx, samp, tObj->Image[0][tObj->_MaxLevel], 21842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoord[i], rgba[i]); 21852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 21862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 2187de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; /* texels */ 21882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat f = FRAC(lambda[i]); 2189cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_3d_nearest(ctx, samp, tObj->Image[0][level ], texcoord[i], t0); 2190cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_3d_nearest(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1); 21912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lerp_rgba(rgba[i], f, t0, t1); 21922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 21932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 21942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 21952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 21962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 21972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2198f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_3d_linear_mipmap_linear(struct gl_context *ctx, 2199cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 22002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 22012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 2202de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 22032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 22042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 22052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 22062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 2207792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = linear_mipmap_level(tObj, lambda[i]); 22082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (level >= tObj->_MaxLevel) { 2209cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_3d_linear(ctx, samp, tObj->Image[0][tObj->_MaxLevel], 22102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoord[i], rgba[i]); 22112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 22122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 2213de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; /* texels */ 22142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat f = FRAC(lambda[i]); 2215cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_3d_linear(ctx, samp, tObj->Image[0][level ], texcoord[i], t0); 2216cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_3d_linear(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1); 22172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lerp_rgba(rgba[i], f, t0, t1); 22182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 22192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 22202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 22212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 22222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 22236e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 3D texture, nearest filtering for both min/magnification */ 22242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2225f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_nearest_3d(struct gl_context *ctx, 2226cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 22272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, GLuint n, 22282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoords[][4], const GLfloat lambda[], 2229de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[][4]) 22302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 22312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 22322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; 22332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) lambda; 22346e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian for (i = 0; i < n; i++) { 2235cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_3d_nearest(ctx, samp, image, texcoords[i], rgba[i]); 22362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 22372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 22382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 22392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 22406e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 3D texture, linear filtering for both min/magnification */ 22412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2242f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_linear_3d(struct gl_context *ctx, 2243cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 22446e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const struct gl_texture_object *tObj, GLuint n, 22456e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const GLfloat texcoords[][4], 2246de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 22472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 22482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 22492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; 22502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) lambda; 22516e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian for (i = 0; i < n; i++) { 2252cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_3d_linear(ctx, samp, image, texcoords[i], rgba[i]); 22532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 22542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 22552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 22562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 22576e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 3D texture, using lambda to choose between min/magnification */ 22582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2259f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_lambda_3d(struct gl_context *ctx, 2260cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 22616e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const struct gl_texture_object *tObj, GLuint n, 22626e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const GLfloat texcoords[][4], const GLfloat lambda[], 2263de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[][4]) 22642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 22652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint minStart, minEnd; /* texels with minification */ 22662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint magStart, magEnd; /* texels with magnification */ 22672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 22682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 22692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 2270cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen compute_min_mag_ranges(samp, n, lambda, 2271aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul &minStart, &minEnd, &magStart, &magEnd); 22722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 22732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (minStart < minEnd) { 22742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* do the minified texels */ 22752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint m = minEnd - minStart; 2276cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen switch (samp->MinFilter) { 22772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST: 22782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = minStart; i < minEnd; i++) 2279cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_3d_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel], 22802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoords[i], rgba[i]); 22812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 22822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR: 22832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = minStart; i < minEnd; i++) 2284cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_3d_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel], 22852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoords[i], rgba[i]); 22862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 22872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST_MIPMAP_NEAREST: 2288cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_3d_nearest_mipmap_nearest(ctx, samp, tObj, m, texcoords + minStart, 22892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 22902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 22912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR_MIPMAP_NEAREST: 2292cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_3d_linear_mipmap_nearest(ctx, samp, tObj, m, texcoords + minStart, 22932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 22942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 22952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST_MIPMAP_LINEAR: 2296cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_3d_nearest_mipmap_linear(ctx, samp, tObj, m, texcoords + minStart, 22972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 22982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 22992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR_MIPMAP_LINEAR: 2300cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_3d_linear_mipmap_linear(ctx, samp, tObj, m, texcoords + minStart, 23012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 23022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 23032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul default: 23042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul _mesa_problem(ctx, "Bad min filter in sample_3d_texture"); 23052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return; 23062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 23072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 23082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 23092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (magStart < magEnd) { 23102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* do the magnified texels */ 2311cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen switch (samp->MagFilter) { 23122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST: 23132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = magStart; i < magEnd; i++) 2314cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_3d_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel], 23152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoords[i], rgba[i]); 23162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 23172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR: 23182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = magStart; i < magEnd; i++) 2319cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_3d_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel], 23202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoords[i], rgba[i]); 23212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 23222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul default: 23232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul _mesa_problem(ctx, "Bad mag filter in sample_3d_texture"); 23242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return; 23252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 23262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 23272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 23282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 23292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 23302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/ 23312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/* Texture Cube Map Sampling Functions */ 23322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/ 23332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 23342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/** 23352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Choose one of six sides of a texture cube map given the texture 23362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * coord (rx,ry,rz). Return pointer to corresponding array of texture 23372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * images. 23382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 23392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic const struct gl_texture_image ** 23402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulchoose_cube_face(const struct gl_texture_object *texObj, 23412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoord[4], GLfloat newCoord[4]) 23422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 23432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* 23442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul major axis 23452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul direction target sc tc ma 23462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ---------- ------------------------------- --- --- --- 23472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul +rx TEXTURE_CUBE_MAP_POSITIVE_X_EXT -rz -ry rx 23482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul -rx TEXTURE_CUBE_MAP_NEGATIVE_X_EXT +rz -ry rx 23492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul +ry TEXTURE_CUBE_MAP_POSITIVE_Y_EXT +rx +rz ry 23502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul -ry TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT +rx -rz ry 23512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul +rz TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz 23522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul -rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz 23532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 23542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat rx = texcoord[0]; 23552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat ry = texcoord[1]; 23562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat rz = texcoord[2]; 23572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat arx = FABSF(rx), ary = FABSF(ry), arz = FABSF(rz); 23582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint face; 23592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLfloat sc, tc, ma; 23602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 2361d504a7669d7b71229c2d15503a095d71ee1584e6Brian Paul if (arx >= ary && arx >= arz) { 23622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (rx >= 0.0F) { 23632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul face = FACE_POS_X; 23642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sc = -rz; 23652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul tc = -ry; 23662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ma = arx; 23672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 23682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 23692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul face = FACE_NEG_X; 23702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sc = rz; 23712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul tc = -ry; 23722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ma = arx; 23732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 23742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 2375d504a7669d7b71229c2d15503a095d71ee1584e6Brian Paul else if (ary >= arx && ary >= arz) { 23762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (ry >= 0.0F) { 23772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul face = FACE_POS_Y; 23782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sc = rx; 23792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul tc = rz; 23802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ma = ary; 23812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 23822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 23832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul face = FACE_NEG_Y; 23842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sc = rx; 23852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul tc = -rz; 23862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ma = ary; 23872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 23882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 23892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 23902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (rz > 0.0F) { 23912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul face = FACE_POS_Z; 23922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sc = rx; 23932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul tc = -ry; 23942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ma = arz; 23952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 23962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 23972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul face = FACE_NEG_Z; 23982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul sc = -rx; 23992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul tc = -ry; 24002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ma = arz; 24012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 24022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 24032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 240467d4a5b15cfd8583c19a5776b0ec1564b60239ebKeith Whitwell { 240567d4a5b15cfd8583c19a5776b0ec1564b60239ebKeith Whitwell const float ima = 1.0F / ma; 240667d4a5b15cfd8583c19a5776b0ec1564b60239ebKeith Whitwell newCoord[0] = ( sc * ima + 1.0F ) * 0.5F; 240767d4a5b15cfd8583c19a5776b0ec1564b60239ebKeith Whitwell newCoord[1] = ( tc * ima + 1.0F ) * 0.5F; 240867d4a5b15cfd8583c19a5776b0ec1564b60239ebKeith Whitwell } 240967d4a5b15cfd8583c19a5776b0ec1564b60239ebKeith Whitwell 24102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return (const struct gl_texture_image **) texObj->Image[face]; 24112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 24122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 24132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 24142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2415f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_nearest_cube(struct gl_context *ctx, 2416cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 24172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, GLuint n, 24182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoords[][4], const GLfloat lambda[], 2419de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[][4]) 24202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 24212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 24222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) lambda; 24232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 24242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image **images; 24252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLfloat newCoord[4]; 24262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul images = choose_cube_face(tObj, texcoords[i], newCoord); 2427cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_nearest(ctx, samp, images[tObj->BaseLevel], 24282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul newCoord, rgba[i]); 24292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 24309282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul if (is_depth_texture(tObj)) { 24319282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul for (i = 0; i < n; i++) { 24329282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul apply_depth_mode(tObj->DepthMode, rgba[i][0], rgba[i]); 24339282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul } 24349282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul } 24352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 24362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 24372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 24382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2439f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_linear_cube(struct gl_context *ctx, 2440cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 24412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, GLuint n, 24422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoords[][4], 2443de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 24442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 24452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 24462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) lambda; 24472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 24482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image **images; 24492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLfloat newCoord[4]; 24502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul images = choose_cube_face(tObj, texcoords[i], newCoord); 2451cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_linear(ctx, samp, images[tObj->BaseLevel], 24522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul newCoord, rgba[i]); 24532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 24549282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul if (is_depth_texture(tObj)) { 24559282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul for (i = 0; i < n; i++) { 24569282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul apply_depth_mode(tObj->DepthMode, rgba[i][0], rgba[i]); 24579282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul } 24589282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul } 24592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 24602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 24612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 24622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2463f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_cube_nearest_mipmap_nearest(struct gl_context *ctx, 2464cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 24652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 24662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 2467de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 24682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 24692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 24702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 24712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 24722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image **images; 24732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLfloat newCoord[4]; 247421177c8764638e1d4b3b29fed64adec62a14e936Brian Paul GLint level; 24752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul images = choose_cube_face(tObj, texcoord[i], newCoord); 247621177c8764638e1d4b3b29fed64adec62a14e936Brian Paul 247721177c8764638e1d4b3b29fed64adec62a14e936Brian Paul /* XXX we actually need to recompute lambda here based on the newCoords. 247821177c8764638e1d4b3b29fed64adec62a14e936Brian Paul * But we would need the texcoords of adjacent fragments to compute that 247921177c8764638e1d4b3b29fed64adec62a14e936Brian Paul * properly, and we don't have those here. 248021177c8764638e1d4b3b29fed64adec62a14e936Brian Paul * For now, do an approximation: subtracting 1 from the chosen mipmap 248121177c8764638e1d4b3b29fed64adec62a14e936Brian Paul * level seems to work in some test cases. 248221177c8764638e1d4b3b29fed64adec62a14e936Brian Paul * The same adjustment is done in the next few functions. 248321177c8764638e1d4b3b29fed64adec62a14e936Brian Paul */ 248421177c8764638e1d4b3b29fed64adec62a14e936Brian Paul level = nearest_mipmap_level(tObj, lambda[i]); 248521177c8764638e1d4b3b29fed64adec62a14e936Brian Paul level = MAX2(level - 1, 0); 248621177c8764638e1d4b3b29fed64adec62a14e936Brian Paul 2487cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_nearest(ctx, samp, images[level], newCoord, rgba[i]); 24882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 24899282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul if (is_depth_texture(tObj)) { 24909282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul for (i = 0; i < n; i++) { 24919282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul apply_depth_mode(tObj->DepthMode, rgba[i][0], rgba[i]); 24929282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul } 24939282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul } 24942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 24952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 24962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 24972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2498f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_cube_linear_mipmap_nearest(struct gl_context *ctx, 2499cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 25002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 25012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 2502de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 25032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 25042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 25052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 25062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 25072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image **images; 25082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLfloat newCoord[4]; 2509792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = nearest_mipmap_level(tObj, lambda[i]); 251021177c8764638e1d4b3b29fed64adec62a14e936Brian Paul level = MAX2(level - 1, 0); /* see comment above */ 25112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul images = choose_cube_face(tObj, texcoord[i], newCoord); 2512cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_linear(ctx, samp, images[level], newCoord, rgba[i]); 25132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 25149282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul if (is_depth_texture(tObj)) { 25159282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul for (i = 0; i < n; i++) { 25169282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul apply_depth_mode(tObj->DepthMode, rgba[i][0], rgba[i]); 25179282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul } 25189282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul } 25192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 25202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 25212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 25222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2523f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_cube_nearest_mipmap_linear(struct gl_context *ctx, 2524cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 25252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 25262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 2527de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 25282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 25292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 25302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 25312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 25322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image **images; 25332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLfloat newCoord[4]; 2534792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = linear_mipmap_level(tObj, lambda[i]); 253521177c8764638e1d4b3b29fed64adec62a14e936Brian Paul level = MAX2(level - 1, 0); /* see comment above */ 25362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul images = choose_cube_face(tObj, texcoord[i], newCoord); 25372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (level >= tObj->_MaxLevel) { 2538cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_nearest(ctx, samp, images[tObj->_MaxLevel], 25392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul newCoord, rgba[i]); 25402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 25412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 2542de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; /* texels */ 25432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat f = FRAC(lambda[i]); 2544cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_nearest(ctx, samp, images[level ], newCoord, t0); 2545cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_nearest(ctx, samp, images[level+1], newCoord, t1); 25462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lerp_rgba(rgba[i], f, t0, t1); 25472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 25482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 25499282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul if (is_depth_texture(tObj)) { 25509282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul for (i = 0; i < n; i++) { 25519282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul apply_depth_mode(tObj->DepthMode, rgba[i][0], rgba[i]); 25529282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul } 25539282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul } 25542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 25552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 25562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 25572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2558f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_cube_linear_mipmap_linear(struct gl_context *ctx, 2559cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 25602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, 25612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint n, const GLfloat texcoord[][4], 2562de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 25632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 25642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 25652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 25662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 25672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image **images; 25682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLfloat newCoord[4]; 2569792a1bcbe4c4b4f5f96d6ac017fcb5376900ea75Brian Paul GLint level = linear_mipmap_level(tObj, lambda[i]); 257021177c8764638e1d4b3b29fed64adec62a14e936Brian Paul level = MAX2(level - 1, 0); /* see comment above */ 25712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul images = choose_cube_face(tObj, texcoord[i], newCoord); 25722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (level >= tObj->_MaxLevel) { 2573cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_linear(ctx, samp, images[tObj->_MaxLevel], 25742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul newCoord, rgba[i]); 25752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 25762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 2577de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; 25782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat f = FRAC(lambda[i]); 2579cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_linear(ctx, samp, images[level ], newCoord, t0); 2580cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_linear(ctx, samp, images[level+1], newCoord, t1); 25812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lerp_rgba(rgba[i], f, t0, t1); 25822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 25832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 25849282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul if (is_depth_texture(tObj)) { 25859282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul for (i = 0; i < n; i++) { 25869282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul apply_depth_mode(tObj->DepthMode, rgba[i][0], rgba[i]); 25879282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul } 25889282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul } 25892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 25902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 25912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 25926e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample cube texture, using lambda to choose between min/magnification */ 25932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2594f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_lambda_cube(struct gl_context *ctx, 2595cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 25966e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const struct gl_texture_object *tObj, GLuint n, 25976e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const GLfloat texcoords[][4], const GLfloat lambda[], 2598de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[][4]) 25992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 26002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint minStart, minEnd; /* texels with minification */ 26012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint magStart, magEnd; /* texels with magnification */ 26022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 26032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(lambda != NULL); 2604cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen compute_min_mag_ranges(samp, n, lambda, 2605aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul &minStart, &minEnd, &magStart, &magEnd); 26062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 26072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (minStart < minEnd) { 26082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* do the minified texels */ 26092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLuint m = minEnd - minStart; 2610cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen switch (samp->MinFilter) { 26112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST: 2612cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_nearest_cube(ctx, samp, tObj, m, texcoords + minStart, 26132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 26142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 26152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR: 2616cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_linear_cube(ctx, samp, tObj, m, texcoords + minStart, 26172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 26182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 26192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST_MIPMAP_NEAREST: 2620cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_cube_nearest_mipmap_nearest(ctx, samp, tObj, m, 26212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoords + minStart, 26222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 26232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 26242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR_MIPMAP_NEAREST: 2625cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_cube_linear_mipmap_nearest(ctx, samp, tObj, m, 26262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoords + minStart, 26272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 26282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 26292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST_MIPMAP_LINEAR: 2630cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_cube_nearest_mipmap_linear(ctx, samp, tObj, m, 26312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoords + minStart, 26322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 26332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 26342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR_MIPMAP_LINEAR: 2635cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_cube_linear_mipmap_linear(ctx, samp, tObj, m, 26362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul texcoords + minStart, 26372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + minStart, rgba + minStart); 26382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 26392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul default: 26402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul _mesa_problem(ctx, "Bad min filter in sample_lambda_cube"); 264103bbcd447cbaa28b52465ae1045013f1aff420c2Chad Versace break; 26422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 26432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 26442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 26452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (magStart < magEnd) { 26462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* do the magnified texels */ 26472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLuint m = magEnd - magStart; 2648cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen switch (samp->MagFilter) { 26492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_NEAREST: 2650cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_nearest_cube(ctx, samp, tObj, m, texcoords + magStart, 26512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + magStart, rgba + magStart); 26522cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 26532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_LINEAR: 2654cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_linear_cube(ctx, samp, tObj, m, texcoords + magStart, 26552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda + magStart, rgba + magStart); 26562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 26572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul default: 26582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul _mesa_problem(ctx, "Bad mag filter in sample_lambda_cube"); 265903bbcd447cbaa28b52465ae1045013f1aff420c2Chad Versace break; 26602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 26612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 26622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 26632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 26642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 26652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/ 26662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/* Texture Rectangle Sampling Functions */ 26672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/**********************************************************************/ 26682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 2669fde15a2bae2f2ca552763705f12d53e4606feabfBrian 26702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2671f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_nearest_rect(struct gl_context *ctx, 2672cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 26732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, GLuint n, 26742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoords[][4], const GLfloat lambda[], 2675de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[][4]) 26762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 26772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image *img = tObj->Image[0][0]; 2678a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 26796e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const GLint width = img->Width; 26806e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const GLint height = img->Height; 26812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 26822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 26832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) ctx; 26842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) lambda; 26852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 2686cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen ASSERT(samp->WrapS == GL_CLAMP || 2687cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen samp->WrapS == GL_CLAMP_TO_EDGE || 2688cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen samp->WrapS == GL_CLAMP_TO_BORDER); 2689cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen ASSERT(samp->WrapT == GL_CLAMP || 2690cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen samp->WrapT == GL_CLAMP_TO_EDGE || 2691cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen samp->WrapT == GL_CLAMP_TO_BORDER); 26922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 26932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 26942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLint row, col; 2695cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen col = clamp_rect_coord_nearest(samp->WrapS, texcoords[i][0], width); 2696cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen row = clamp_rect_coord_nearest(samp->WrapT, texcoords[i][1], height); 26976e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian if (col < 0 || col >= width || row < 0 || row >= height) 2698cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, rgba[i]); 26992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else 27005ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, col, row, 0, rgba[i]); 27012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 27022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 27032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 27042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 27052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2706f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_linear_rect(struct gl_context *ctx, 2707cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 27082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, GLuint n, 27092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoords[][4], 2710de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 27112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 27122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_image *img = tObj->Image[0][0]; 2713a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 27146e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const GLint width = img->Width; 27156e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const GLint height = img->Height; 27162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 27172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 27182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) ctx; 27192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) lambda; 27202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 2721cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen ASSERT(samp->WrapS == GL_CLAMP || 2722cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen samp->WrapS == GL_CLAMP_TO_EDGE || 2723cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen samp->WrapS == GL_CLAMP_TO_BORDER); 2724cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen ASSERT(samp->WrapT == GL_CLAMP || 2725cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen samp->WrapT == GL_CLAMP_TO_EDGE || 2726cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen samp->WrapT == GL_CLAMP_TO_BORDER); 27272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 27282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 27292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLint i0, j0, i1, j1; 2730de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t00[4], t01[4], t10[4], t11[4]; 27312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLfloat a, b; 27320f540f4b0468f581f63fb0b6347fe66251fa545aBrian Paul GLbitfield useBorderColor = 0x0; 27332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 2734cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen clamp_rect_coord_linear(samp->WrapS, texcoords[i][0], width, 2735249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian &i0, &i1, &a); 2736cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen clamp_rect_coord_linear(samp->WrapT, texcoords[i][1], height, 2737249e1e4d30759cd3c55cef0dba75f531cc7c6269Brian &j0, &j1, &b); 27382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 27392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* compute integer rows/columns */ 27406e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT; 27416e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT; 27426e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian if (j0 < 0 || j0 >= height) useBorderColor |= J0BIT; 27436e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian if (j1 < 0 || j1 >= height) useBorderColor |= J1BIT; 27442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 27452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* get four texel samples */ 27462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (useBorderColor & (I0BIT | J0BIT)) 2747cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, t00); 27482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else 27495ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i0, j0, 0, t00); 27502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 27512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (useBorderColor & (I1BIT | J0BIT)) 2752cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, t10); 27532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else 27545ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i1, j0, 0, t10); 27552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 27562cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (useBorderColor & (I0BIT | J1BIT)) 2757cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, t01); 27582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else 27595ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i0, j1, 0, t01); 27602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 27612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (useBorderColor & (I1BIT | J1BIT)) 2762cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, t11); 27632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else 27645ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i1, j1, 0, t11); 27652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 27662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lerp_rgba_2d(rgba[i], a, b, t00, t10, t01, t11); 27672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 27682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 27692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 27702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 27716e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample Rect texture, using lambda to choose between min/magnification */ 27722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 2773f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_lambda_rect(struct gl_context *ctx, 2774cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 27756e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const struct gl_texture_object *tObj, GLuint n, 27766e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const GLfloat texcoords[][4], const GLfloat lambda[], 2777de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[][4]) 27782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 27792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint minStart, minEnd, magStart, magEnd; 27802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 27812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* We only need lambda to decide between minification and magnification. 27822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * There is no mipmapping with rectangular textures. 27832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 2784cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen compute_min_mag_ranges(samp, n, lambda, 2785aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul &minStart, &minEnd, &magStart, &magEnd); 27862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 27872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (minStart < minEnd) { 2788cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen if (samp->MinFilter == GL_NEAREST) { 2789cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_nearest_rect(ctx, samp, tObj, minEnd - minStart, 27906e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian texcoords + minStart, NULL, rgba + minStart); 27912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 27922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 2793cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_linear_rect(ctx, samp, tObj, minEnd - minStart, 27946e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian texcoords + minStart, NULL, rgba + minStart); 27952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 27962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 27972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (magStart < magEnd) { 2798cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen if (samp->MagFilter == GL_NEAREST) { 2799cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_nearest_rect(ctx, samp, tObj, magEnd - magStart, 28006e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian texcoords + magStart, NULL, rgba + magStart); 28012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 28022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 2803cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_linear_rect(ctx, samp, tObj, magEnd - magStart, 28046e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian texcoords + magStart, NULL, rgba + magStart); 28052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 28062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 28072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 28082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 28092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 2810bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick/**********************************************************************/ 2811bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick/* 2D Texture Array Sampling Functions */ 2812bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick/**********************************************************************/ 2813bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 28146e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** 2815bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter. 2816bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick */ 2817bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 2818f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_array_nearest(struct gl_context *ctx, 2819cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 2820bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_image *img, 2821bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLfloat texcoord[4], 2822de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[4]) 2823bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 2824a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 2825bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLint width = img->Width2; /* without border, power of two */ 2826bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLint height = img->Height2; /* without border, power of two */ 2827bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLint depth = img->Depth; 2828bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint i, j; 2829bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint array; 2830bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick (void) ctx; 2831bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2832cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen i = nearest_texel_location(samp->WrapS, img, width, texcoord[0]); 2833cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen j = nearest_texel_location(samp->WrapT, img, height, texcoord[1]); 283458ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul array = tex_array_slice(texcoord[2], depth); 2835bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2836bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (i < 0 || i >= (GLint) img->Width || 2837bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick j < 0 || j >= (GLint) img->Height || 2838bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick array < 0 || array >= (GLint) img->Depth) { 2839bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick /* Need this test for GL_CLAMP_TO_BORDER mode */ 2840cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, rgba); 2841bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2842bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 28435ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i, j, array, rgba); 2844bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2845bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 2846bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2847bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 28486e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** 2849bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter. 2850bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick */ 2851bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 2852f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_array_linear(struct gl_context *ctx, 2853cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 2854bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_image *img, 2855bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLfloat texcoord[4], 2856de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[4]) 2857bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 2858a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 2859bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLint width = img->Width2; 2860bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLint height = img->Height2; 2861bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLint depth = img->Depth; 2862bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint i0, j0, i1, j1; 2863bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint array; 2864bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLbitfield useBorderColor = 0x0; 2865bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLfloat a, b; 2866de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t00[4], t01[4], t10[4], t11[4]; 2867bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2868cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen linear_texel_locations(samp->WrapS, img, width, texcoord[0], &i0, &i1, &a); 2869cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen linear_texel_locations(samp->WrapT, img, height, texcoord[1], &j0, &j1, &b); 287058ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul array = tex_array_slice(texcoord[2], depth); 2871bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2872bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (array < 0 || array >= depth) { 2873cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen COPY_4V(rgba, samp->BorderColor.f); 2874bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2875bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 2876bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (img->Border) { 2877bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick i0 += img->Border; 2878bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick i1 += img->Border; 2879bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick j0 += img->Border; 2880bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick j1 += img->Border; 2881bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2882bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 2883bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick /* check if sampling texture border color */ 2884bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT; 2885bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT; 2886bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (j0 < 0 || j0 >= height) useBorderColor |= J0BIT; 2887bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (j1 < 0 || j1 >= height) useBorderColor |= J1BIT; 2888bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2889bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2890bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick /* Fetch texels */ 2891bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (useBorderColor & (I0BIT | J0BIT)) { 2892cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, t00); 2893bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2894bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 28955ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i0, j0, array, t00); 2896bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2897bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (useBorderColor & (I1BIT | J0BIT)) { 2898cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, t10); 2899bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2900bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 29015ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i1, j0, array, t10); 2902bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2903bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (useBorderColor & (I0BIT | J1BIT)) { 2904cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, t01); 2905bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2906bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 29075ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i0, j1, array, t01); 2908bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2909bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (useBorderColor & (I1BIT | J1BIT)) { 2910cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, t11); 2911bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2912bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 29135ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i1, j1, array, t11); 2914bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2915bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2916bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick /* trilinear interpolation of samples */ 2917bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick lerp_rgba_2d(rgba, a, b, t00, t10, t01, t11); 2918bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2919bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 2920bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2921bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2922bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 2923f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_array_nearest_mipmap_nearest(struct gl_context *ctx, 2924cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 2925bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_object *tObj, 2926bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint n, const GLfloat texcoord[][4], 2927de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 2928bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 2929bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint i; 2930bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = 0; i < n; i++) { 2931bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint level = nearest_mipmap_level(tObj, lambda[i]); 2932cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_array_nearest(ctx, samp, tObj->Image[0][level], texcoord[i], 2933bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick rgba[i]); 2934bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2935bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 2936bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2937bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2938bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 2939f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_array_linear_mipmap_nearest(struct gl_context *ctx, 2940cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 2941bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_object *tObj, 2942bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint n, const GLfloat texcoord[][4], 2943de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 2944bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 2945bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint i; 2946bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick ASSERT(lambda != NULL); 2947bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = 0; i < n; i++) { 2948bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint level = nearest_mipmap_level(tObj, lambda[i]); 2949cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_array_linear(ctx, samp, tObj->Image[0][level], 2950bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoord[i], rgba[i]); 2951bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2952bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 2953bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2954bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2955bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 2956f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_array_nearest_mipmap_linear(struct gl_context *ctx, 2957cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 2958bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_object *tObj, 2959bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint n, const GLfloat texcoord[][4], 2960de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 2961bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 2962bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint i; 2963bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick ASSERT(lambda != NULL); 2964bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = 0; i < n; i++) { 2965bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint level = linear_mipmap_level(tObj, lambda[i]); 2966bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (level >= tObj->_MaxLevel) { 2967cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_array_nearest(ctx, samp, tObj->Image[0][tObj->_MaxLevel], 2968bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoord[i], rgba[i]); 2969bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2970bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 2971de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; /* texels */ 2972bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLfloat f = FRAC(lambda[i]); 2973cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_array_nearest(ctx, samp, tObj->Image[0][level ], 29746e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian texcoord[i], t0); 2975cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_array_nearest(ctx, samp, tObj->Image[0][level+1], 29766e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian texcoord[i], t1); 2977bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick lerp_rgba(rgba[i], f, t0, t1); 2978bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2979bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2980bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 2981bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2982bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 2983bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 2984f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_2d_array_linear_mipmap_linear(struct gl_context *ctx, 2985cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 29866e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const struct gl_texture_object *tObj, 29876e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian GLuint n, const GLfloat texcoord[][4], 2988de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 2989bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 2990bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint i; 2991bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick ASSERT(lambda != NULL); 2992bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = 0; i < n; i++) { 2993bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint level = linear_mipmap_level(tObj, lambda[i]); 2994bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (level >= tObj->_MaxLevel) { 2995cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_array_linear(ctx, samp, tObj->Image[0][tObj->_MaxLevel], 2996bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoord[i], rgba[i]); 2997bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 2998bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 2999de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; /* texels */ 3000bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLfloat f = FRAC(lambda[i]); 3001cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_array_linear(ctx, samp, tObj->Image[0][level ], 30026e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian texcoord[i], t0); 3003cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_array_linear(ctx, samp, tObj->Image[0][level+1], 30046e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian texcoord[i], t1); 3005bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick lerp_rgba(rgba[i], f, t0, t1); 3006bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3007bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3008bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 3009bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3010bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 30116e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 2D Array texture, nearest filtering for both min/magnification */ 3012bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 3013f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_nearest_2d_array(struct gl_context *ctx, 3014cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 30156e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const struct gl_texture_object *tObj, GLuint n, 30166e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const GLfloat texcoords[][4], const GLfloat lambda[], 3017de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[][4]) 3018bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 3019bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint i; 3020bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; 3021bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick (void) lambda; 30226e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian for (i = 0; i < n; i++) { 3023cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_array_nearest(ctx, samp, image, texcoords[i], rgba[i]); 3024bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3025bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 3026bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3027bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3028bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 30296e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 2D Array texture, linear filtering for both min/magnification */ 3030bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 3031f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_linear_2d_array(struct gl_context *ctx, 3032cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 3033bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_object *tObj, GLuint n, 3034bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLfloat texcoords[][4], 3035de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 3036bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 3037bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint i; 3038bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; 3039bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick (void) lambda; 30406e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian for (i = 0; i < n; i++) { 3041cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_array_linear(ctx, samp, image, texcoords[i], rgba[i]); 3042bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3043bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 3044bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3045bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 30466e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 2D Array texture, using lambda to choose between min/magnification */ 3047bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 3048f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_lambda_2d_array(struct gl_context *ctx, 3049cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 3050bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_object *tObj, GLuint n, 3051bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLfloat texcoords[][4], const GLfloat lambda[], 3052de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[][4]) 3053bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 3054bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint minStart, minEnd; /* texels with minification */ 3055bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint magStart, magEnd; /* texels with magnification */ 3056bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint i; 3057bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3058bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick ASSERT(lambda != NULL); 3059cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen compute_min_mag_ranges(samp, n, lambda, 3060bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick &minStart, &minEnd, &magStart, &magEnd); 3061bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3062bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (minStart < minEnd) { 3063bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick /* do the minified texels */ 3064bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint m = minEnd - minStart; 3065cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen switch (samp->MinFilter) { 3066bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_NEAREST: 3067bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = minStart; i < minEnd; i++) 3068cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_array_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel], 3069bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoords[i], rgba[i]); 3070bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 3071bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_LINEAR: 3072bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = minStart; i < minEnd; i++) 3073cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_array_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel], 3074bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoords[i], rgba[i]); 3075bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 3076bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_NEAREST_MIPMAP_NEAREST: 3077cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_array_nearest_mipmap_nearest(ctx, samp, tObj, m, 30786e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian texcoords + minStart, 30796e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian lambda + minStart, 30806e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian rgba + minStart); 3081bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 3082bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_LINEAR_MIPMAP_NEAREST: 3083cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_array_linear_mipmap_nearest(ctx, samp, tObj, m, 3084bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoords + minStart, 3085bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick lambda + minStart, 3086bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick rgba + minStart); 3087bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 3088bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_NEAREST_MIPMAP_LINEAR: 3089cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_array_nearest_mipmap_linear(ctx, samp, tObj, m, 30906e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian texcoords + minStart, 30916e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian lambda + minStart, 30926e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian rgba + minStart); 3093bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 3094bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_LINEAR_MIPMAP_LINEAR: 3095cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_array_linear_mipmap_linear(ctx, samp, tObj, m, 3096bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoords + minStart, 3097bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick lambda + minStart, 3098bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick rgba + minStart); 3099bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 3100bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick default: 3101bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick _mesa_problem(ctx, "Bad min filter in sample_2d_array_texture"); 3102bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick return; 3103bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3104bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3105bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3106bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (magStart < magEnd) { 3107bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick /* do the magnified texels */ 3108cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen switch (samp->MagFilter) { 3109bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_NEAREST: 3110bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = magStart; i < magEnd; i++) 3111cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_array_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel], 3112bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoords[i], rgba[i]); 3113bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 3114bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_LINEAR: 3115bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = magStart; i < magEnd; i++) 3116cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_2d_array_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel], 3117bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoords[i], rgba[i]); 3118bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 3119bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick default: 3120bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick _mesa_problem(ctx, "Bad mag filter in sample_2d_array_texture"); 3121bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick return; 3122bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3123bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3124bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 3125bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3126bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3127bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3128bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3129bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick/**********************************************************************/ 3130bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick/* 1D Texture Array Sampling Functions */ 3131bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick/**********************************************************************/ 3132bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 31336e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** 3134bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter. 3135bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick */ 3136bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 3137f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_array_nearest(struct gl_context *ctx, 3138cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 3139bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_image *img, 3140bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLfloat texcoord[4], 3141de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[4]) 3142bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 3143a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 3144bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLint width = img->Width2; /* without border, power of two */ 3145bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLint height = img->Height; 3146bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint i; 3147bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint array; 3148bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick (void) ctx; 3149bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3150cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen i = nearest_texel_location(samp->WrapS, img, width, texcoord[0]); 315158ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul array = tex_array_slice(texcoord[1], height); 3152bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3153bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (i < 0 || i >= (GLint) img->Width || 3154bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick array < 0 || array >= (GLint) img->Height) { 3155bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick /* Need this test for GL_CLAMP_TO_BORDER mode */ 3156cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, rgba); 3157bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3158bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 31595ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i, array, 0, rgba); 3160bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3161bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 3162bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3163bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 31646e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** 3165bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter. 3166bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick */ 3167bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 3168f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_array_linear(struct gl_context *ctx, 3169cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 3170bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_image *img, 3171bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLfloat texcoord[4], 3172de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[4]) 3173bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 3174a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 3175bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLint width = img->Width2; 3176bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLint height = img->Height; 3177bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint i0, i1; 3178bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint array; 3179bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLbitfield useBorderColor = 0x0; 3180bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLfloat a; 3181de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; 3182bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3183cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen linear_texel_locations(samp->WrapS, img, width, texcoord[0], &i0, &i1, &a); 318458ab56d32308e36f331294047e11c3e0b4b73cdeBrian Paul array = tex_array_slice(texcoord[1], height); 3185bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3186bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (img->Border) { 3187bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick i0 += img->Border; 3188bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick i1 += img->Border; 3189bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3190bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 3191bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick /* check if sampling texture border color */ 3192bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT; 3193bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT; 3194bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3195bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3196bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (array < 0 || array >= height) useBorderColor |= K0BIT; 3197bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3198bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick /* Fetch texels */ 3199bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (useBorderColor & (I0BIT | K0BIT)) { 3200cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, t0); 3201bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3202bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 32035ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i0, array, 0, t0); 3204bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3205bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (useBorderColor & (I1BIT | K0BIT)) { 3206cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen get_border_color(samp, img, t1); 3207bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3208bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 32095ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i1, array, 0, t1); 3210bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3211bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3212bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick /* bilinear interpolation of samples */ 3213bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick lerp_rgba(rgba, a, t0, t1); 3214bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 3215bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3216bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3217bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 3218f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_array_nearest_mipmap_nearest(struct gl_context *ctx, 3219cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 3220bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_object *tObj, 3221bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint n, const GLfloat texcoord[][4], 3222de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 3223bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 3224bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint i; 3225bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = 0; i < n; i++) { 3226bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint level = nearest_mipmap_level(tObj, lambda[i]); 3227cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_array_nearest(ctx, samp, tObj->Image[0][level], texcoord[i], 3228bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick rgba[i]); 3229bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3230bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 3231bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3232bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3233bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 3234f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_array_linear_mipmap_nearest(struct gl_context *ctx, 3235cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 3236bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_object *tObj, 3237bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint n, const GLfloat texcoord[][4], 3238de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 3239bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 3240bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint i; 3241bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick ASSERT(lambda != NULL); 3242bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = 0; i < n; i++) { 3243bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint level = nearest_mipmap_level(tObj, lambda[i]); 3244cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_array_linear(ctx, samp, tObj->Image[0][level], 3245bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoord[i], rgba[i]); 3246bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3247bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 3248bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3249bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3250bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 3251f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_array_nearest_mipmap_linear(struct gl_context *ctx, 3252cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 3253bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_object *tObj, 3254bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint n, const GLfloat texcoord[][4], 3255de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 3256bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 3257bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint i; 3258bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick ASSERT(lambda != NULL); 3259bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = 0; i < n; i++) { 3260bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint level = linear_mipmap_level(tObj, lambda[i]); 3261bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (level >= tObj->_MaxLevel) { 3262cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_array_nearest(ctx, samp, tObj->Image[0][tObj->_MaxLevel], 3263bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoord[i], rgba[i]); 3264bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3265bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 3266de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; /* texels */ 3267bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLfloat f = FRAC(lambda[i]); 3268cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_array_nearest(ctx, samp, tObj->Image[0][level ], texcoord[i], t0); 3269cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_array_nearest(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1); 3270bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick lerp_rgba(rgba[i], f, t0, t1); 3271bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3272bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3273bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 3274bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3275bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3276bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 3277f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_1d_array_linear_mipmap_linear(struct gl_context *ctx, 3278cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 32796e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const struct gl_texture_object *tObj, 32806e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian GLuint n, const GLfloat texcoord[][4], 3281de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 3282bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 3283bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint i; 3284bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick ASSERT(lambda != NULL); 3285bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = 0; i < n; i++) { 3286bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint level = linear_mipmap_level(tObj, lambda[i]); 3287bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (level >= tObj->_MaxLevel) { 3288cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_array_linear(ctx, samp, tObj->Image[0][tObj->_MaxLevel], 3289bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoord[i], rgba[i]); 3290bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3291bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 3292de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat t0[4], t1[4]; /* texels */ 3293bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLfloat f = FRAC(lambda[i]); 3294cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_array_linear(ctx, samp, tObj->Image[0][level ], texcoord[i], t0); 3295cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_array_linear(ctx, samp, tObj->Image[0][level+1], texcoord[i], t1); 3296bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick lerp_rgba(rgba[i], f, t0, t1); 3297bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3298bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3299bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 3300bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3301bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 33026e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 1D Array texture, nearest filtering for both min/magnification */ 3303bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 3304f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_nearest_1d_array(struct gl_context *ctx, 3305cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 33066e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const struct gl_texture_object *tObj, GLuint n, 33076e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian const GLfloat texcoords[][4], const GLfloat lambda[], 3308de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[][4]) 3309bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 3310bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint i; 3311bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; 3312bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick (void) lambda; 33136e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian for (i = 0; i < n; i++) { 3314cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_array_nearest(ctx, samp, image, texcoords[i], rgba[i]); 3315bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3316bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 3317bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3318bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 33196e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 1D Array texture, linear filtering for both min/magnification */ 3320bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 3321f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_linear_1d_array(struct gl_context *ctx, 3322cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 3323bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_object *tObj, GLuint n, 3324bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLfloat texcoords[][4], 3325de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul const GLfloat lambda[], GLfloat rgba[][4]) 3326bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 3327bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint i; 3328bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; 3329bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick (void) lambda; 33306e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian for (i = 0; i < n; i++) { 3331cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_array_linear(ctx, samp, image, texcoords[i], rgba[i]); 3332bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3333bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 3334bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3335bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 33366e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** Sample 1D Array texture, using lambda to choose between min/magnification */ 3337bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanickstatic void 3338f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_lambda_1d_array(struct gl_context *ctx, 3339cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 3340bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const struct gl_texture_object *tObj, GLuint n, 3341bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLfloat texcoords[][4], const GLfloat lambda[], 3342de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[][4]) 3343bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{ 3344bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint minStart, minEnd; /* texels with minification */ 3345bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint magStart, magEnd; /* texels with magnification */ 3346bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint i; 3347bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3348bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick ASSERT(lambda != NULL); 3349cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen compute_min_mag_ranges(samp, n, lambda, 3350bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick &minStart, &minEnd, &magStart, &magEnd); 3351bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3352bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (minStart < minEnd) { 3353bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick /* do the minified texels */ 3354bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLuint m = minEnd - minStart; 3355cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen switch (samp->MinFilter) { 3356bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_NEAREST: 3357bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = minStart; i < minEnd; i++) 3358cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_array_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel], 3359bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoords[i], rgba[i]); 3360bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 3361bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_LINEAR: 3362bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = minStart; i < minEnd; i++) 3363cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_array_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel], 3364bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoords[i], rgba[i]); 3365bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 3366bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_NEAREST_MIPMAP_NEAREST: 3367cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_array_nearest_mipmap_nearest(ctx, samp, tObj, m, texcoords + minStart, 3368bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick lambda + minStart, rgba + minStart); 3369bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 3370bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_LINEAR_MIPMAP_NEAREST: 3371cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_array_linear_mipmap_nearest(ctx, samp, tObj, m, 3372bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoords + minStart, 3373bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick lambda + minStart, 3374bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick rgba + minStart); 3375bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 3376bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_NEAREST_MIPMAP_LINEAR: 3377cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_array_nearest_mipmap_linear(ctx, samp, tObj, m, texcoords + minStart, 3378bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick lambda + minStart, rgba + minStart); 3379bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 3380bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_LINEAR_MIPMAP_LINEAR: 3381cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_array_linear_mipmap_linear(ctx, samp, tObj, m, 3382bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoords + minStart, 3383bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick lambda + minStart, 3384bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick rgba + minStart); 3385bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 3386bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick default: 3387bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick _mesa_problem(ctx, "Bad min filter in sample_1d_array_texture"); 3388bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick return; 3389bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3390bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3391bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3392bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (magStart < magEnd) { 3393bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick /* do the magnified texels */ 3394cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen switch (samp->MagFilter) { 3395bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_NEAREST: 3396bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = magStart; i < magEnd; i++) 3397cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_array_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel], 3398bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoords[i], rgba[i]); 3399bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 3400bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_LINEAR: 3401bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick for (i = magStart; i < magEnd; i++) 3402cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sample_1d_array_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel], 3403bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick texcoords[i], rgba[i]); 3404bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick break; 3405bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick default: 3406bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick _mesa_problem(ctx, "Bad mag filter in sample_1d_array_texture"); 3407bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick return; 3408bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3409bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3410bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick} 3411bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3412bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 34136e0f8b174dddeb743b4bdc0d831eb1121f62ff50Brian/** 3414707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick * Compare texcoord against depth sample. Return 1.0 or 0.0 value. 3415a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul */ 34169520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLfloat 3417707f0679157f83ac45127e41647b96ed924d45c9Ian Romanickshadow_compare(GLenum function, GLfloat coord, GLfloat depthSample) 3418a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul{ 3419a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul switch (function) { 3420a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_LEQUAL: 3421707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick return (coord <= depthSample) ? 1.0F : 0.0F; 3422a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_GEQUAL: 3423707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick return (coord >= depthSample) ? 1.0F : 0.0F; 3424a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_LESS: 3425707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick return (coord < depthSample) ? 1.0F : 0.0F; 3426a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_GREATER: 3427707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick return (coord > depthSample) ? 1.0F : 0.0F; 3428a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_EQUAL: 3429707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick return (coord == depthSample) ? 1.0F : 0.0F; 3430a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_NOTEQUAL: 3431707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick return (coord != depthSample) ? 1.0F : 0.0F; 3432a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_ALWAYS: 3433a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return 1.0F; 3434a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_NEVER: 3435707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick return 0.0F; 3436a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_NONE: 3437a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return depthSample; 3438a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul default: 3439a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul _mesa_problem(NULL, "Bad compare func in shadow_compare"); 3440707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick return 0.0F; 3441a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul } 3442a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul} 3443a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 3444a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 3445a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul/** 3446a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul * Compare texcoord against four depth samples. 3447a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul */ 34489520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLfloat 3449a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paulshadow_compare4(GLenum function, GLfloat coord, 3450a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul GLfloat depth00, GLfloat depth01, 3451a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul GLfloat depth10, GLfloat depth11, 3452707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick GLfloat wi, GLfloat wj) 3453a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul{ 3454707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick const GLfloat d = 0.25F; 3455a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul GLfloat luminance = 1.0F; 3456a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 3457a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul switch (function) { 3458a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_LEQUAL: 34594a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord > depth00) luminance -= d; 34604a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord > depth01) luminance -= d; 34614a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord > depth10) luminance -= d; 34624a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord > depth11) luminance -= d; 3463a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return luminance; 3464d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor case GL_GEQUAL: 34654a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord < depth00) luminance -= d; 34664a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord < depth01) luminance -= d; 34674a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord < depth10) luminance -= d; 34684a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord < depth11) luminance -= d; 3469a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return luminance; 3470d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor case GL_LESS: 34714a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord >= depth00) luminance -= d; 34724a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord >= depth01) luminance -= d; 34734a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord >= depth10) luminance -= d; 34744a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord >= depth11) luminance -= d; 3475a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return luminance; 3476d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor case GL_GREATER: 34774a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord <= depth00) luminance -= d; 34784a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord <= depth01) luminance -= d; 34794a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord <= depth10) luminance -= d; 34804a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord <= depth11) luminance -= d; 3481d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor return luminance; 3482d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor case GL_EQUAL: 34834a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord != depth00) luminance -= d; 34844a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord != depth01) luminance -= d; 34854a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord != depth10) luminance -= d; 34864a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord != depth11) luminance -= d; 3487a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return luminance; 3488d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor case GL_NOTEQUAL: 34894a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord == depth00) luminance -= d; 34904a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord == depth01) luminance -= d; 34914a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord == depth10) luminance -= d; 34924a802738b08b1dbddef6c59d0a1324f864b987b0Brian Paul if (coord == depth11) luminance -= d; 3493d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor return luminance; 3494a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_ALWAYS: 3495d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor return 1.0F; 3496a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_NEVER: 3497707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick return 0.0F; 3498a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul case GL_NONE: 3499a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul /* ordinary bilinear filtering */ 3500a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul return lerp_2d(wi, wj, depth00, depth10, depth01, depth11); 3501a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul default: 3502d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor _mesa_problem(NULL, "Bad compare func in sample_compare4"); 3503707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick return 0.0F; 3504a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul } 3505a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul} 3506a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 3507a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul 3508a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul/** 35092b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul * Choose the mipmap level to use when sampling from a depth texture. 35102b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul */ 35112b5de09b3ea8754fb004d4f216bca29303f99490Brian Paulstatic int 3512cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminenchoose_depth_texture_level(const struct gl_sampler_object *samp, 3513cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_texture_object *tObj, GLfloat lambda) 35142b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul{ 35152b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul GLint level; 35162b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul 3517cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen if (samp->MinFilter == GL_NEAREST || samp->MinFilter == GL_LINEAR) { 3518fb5e6f88fc426e53af26e98d1c336222a8952cc5Brian Paul /* no mipmapping - use base level */ 3519fb5e6f88fc426e53af26e98d1c336222a8952cc5Brian Paul level = tObj->BaseLevel; 3520fb5e6f88fc426e53af26e98d1c336222a8952cc5Brian Paul } 3521fb5e6f88fc426e53af26e98d1c336222a8952cc5Brian Paul else { 3522fb5e6f88fc426e53af26e98d1c336222a8952cc5Brian Paul /* choose mipmap level */ 3523cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen lambda = CLAMP(lambda, samp->MinLod, samp->MaxLod); 3524fb5e6f88fc426e53af26e98d1c336222a8952cc5Brian Paul level = (GLint) lambda; 3525fb5e6f88fc426e53af26e98d1c336222a8952cc5Brian Paul level = CLAMP(level, tObj->BaseLevel, tObj->_MaxLevel); 3526fb5e6f88fc426e53af26e98d1c336222a8952cc5Brian Paul } 35272b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul 35282b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul return level; 35292b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul} 35302b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul 35312b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul 35322b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul/** 35332b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul * Sample a shadow/depth texture. This function is incomplete. It doesn't 35342b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul * check for minification vs. magnification, etc. 35352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 35362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 3537f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergsample_depth_texture( struct gl_context *ctx, 3538cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 35392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, GLuint n, 35402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoords[][4], const GLfloat lambda[], 3541de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat texel[][4] ) 35422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 3543cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const GLint level = choose_depth_texture_level(samp, tObj, lambda[0]); 35442b5de09b3ea8754fb004d4f216bca29303f99490Brian Paul const struct gl_texture_image *img = tObj->Image[0][level]; 3545a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul const struct swrast_texture_image *swImg = swrast_texture_image_const(img); 35469ebe3b6d369c946e41b5f6a684a4ac4e3509b67cBrian Paul const GLint width = img->Width; 35479ebe3b6d369c946e41b5f6a684a4ac4e3509b67cBrian Paul const GLint height = img->Height; 3548bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLint depth = img->Depth; 3549bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick const GLuint compare_coord = (tObj->Target == GL_TEXTURE_2D_ARRAY_EXT) 3550bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick ? 3 : 2; 35512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLenum function; 3552de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat result; 35532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 35541f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul ASSERT(img->_BaseFormat == GL_DEPTH_COMPONENT || 35551f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul img->_BaseFormat == GL_DEPTH_STENCIL_EXT); 3556b0a0ca8bd9edc13e495a39709cc28953dd3fbd9cBrian Paul 35572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(tObj->Target == GL_TEXTURE_1D || 35582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul tObj->Target == GL_TEXTURE_2D || 3559bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick tObj->Target == GL_TEXTURE_RECTANGLE_NV || 3560bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick tObj->Target == GL_TEXTURE_1D_ARRAY_EXT || 3561c3aae7745a648d5d8f8386e09cd6d965f919c7d9Anuj Phogat tObj->Target == GL_TEXTURE_2D_ARRAY_EXT || 3562c3aae7745a648d5d8f8386e09cd6d965f919c7d9Anuj Phogat tObj->Target == GL_TEXTURE_CUBE_MAP); 35632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 3564cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen /* XXXX if samp->MinFilter != samp->MagFilter, we're ignoring lambda */ 35652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 3566cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen function = (samp->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) ? 3567cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen samp->CompareFunc : GL_NONE; 3568590f6fe05030cb274067a9e58af9d8306d97d0b9Brian Paul 3569cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen if (samp->MagFilter == GL_NEAREST) { 35702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 35712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 3572d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor GLfloat depthSample, depthRef; 3573bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint col, row, slice; 3574fde15a2bae2f2ca552763705f12d53e4606feabfBrian 3575cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen nearest_texcoord(samp, tObj, level, texcoords[i], &col, &row, &slice); 3576bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3577bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (col >= 0 && row >= 0 && col < width && row < height && 3578bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick slice >= 0 && slice < depth) { 35795ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, col, row, slice, &depthSample); 35809ebe3b6d369c946e41b5f6a684a4ac4e3509b67cBrian Paul } 35819ebe3b6d369c946e41b5f6a684a4ac4e3509b67cBrian Paul else { 3582cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen depthSample = samp->BorderColor.f[0]; 35839ebe3b6d369c946e41b5f6a684a4ac4e3509b67cBrian Paul } 35842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 3585d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor depthRef = CLAMP(texcoords[i][compare_coord], 0.0F, 1.0F); 3586d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor 3587707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick result = shadow_compare(function, depthRef, depthSample); 35882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 35899282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul apply_depth_mode(tObj->DepthMode, result, texel[i]); 35902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 35912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 35922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 35932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 3594cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen ASSERT(samp->MagFilter == GL_LINEAR); 35952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 3596d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor GLfloat depth00, depth01, depth10, depth11, depthRef; 35972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLint i0, i1, j0, j1; 3598bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick GLint slice; 3599a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul GLfloat wi, wj; 36002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint useBorderTexel; 36012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 3602cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen linear_texcoord(samp, tObj, level, texcoords[i], &i0, &i1, &j0, &j1, &slice, 3603a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul &wi, &wj); 36042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 36052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul useBorderTexel = 0; 360606f606ce5761e673fca3f6b1f7dd40dace8a9906Brian Paul if (img->Border) { 360706f606ce5761e673fca3f6b1f7dd40dace8a9906Brian Paul i0 += img->Border; 360806f606ce5761e673fca3f6b1f7dd40dace8a9906Brian Paul i1 += img->Border; 3609bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (tObj->Target != GL_TEXTURE_1D_ARRAY_EXT) { 3610bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick j0 += img->Border; 3611bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick j1 += img->Border; 3612bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 36132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 36142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 36152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (i0 < 0 || i0 >= (GLint) width) useBorderTexel |= I0BIT; 36162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (i1 < 0 || i1 >= (GLint) width) useBorderTexel |= I1BIT; 36172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (j0 < 0 || j0 >= (GLint) height) useBorderTexel |= J0BIT; 36182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (j1 < 0 || j1 >= (GLint) height) useBorderTexel |= J1BIT; 36192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 36202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 3621bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (slice < 0 || slice >= (GLint) depth) { 3622cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen depth00 = samp->BorderColor.f[0]; 3623cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen depth01 = samp->BorderColor.f[0]; 3624cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen depth10 = samp->BorderColor.f[0]; 3625cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen depth11 = samp->BorderColor.f[0]; 36262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 36272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 3628bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick /* get four depth samples from the texture */ 3629bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (useBorderTexel & (I0BIT | J0BIT)) { 3630cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen depth00 = samp->BorderColor.f[0]; 3631bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3632bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 36335ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i0, j0, slice, &depth00); 3634bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3635bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (useBorderTexel & (I1BIT | J0BIT)) { 3636cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen depth10 = samp->BorderColor.f[0]; 3637bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3638bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 36395ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i1, j0, slice, &depth10); 3640bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3641bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick 3642bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (tObj->Target != GL_TEXTURE_1D_ARRAY_EXT) { 3643bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (useBorderTexel & (I0BIT | J1BIT)) { 3644cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen depth01 = samp->BorderColor.f[0]; 3645bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3646bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 36475ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i0, j1, slice, &depth01); 3648bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3649bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick if (useBorderTexel & (I1BIT | J1BIT)) { 3650cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen depth11 = samp->BorderColor.f[0]; 3651bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3652bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 36535ac96033c52eb2185b9b30bcbb40846d2216d0d3Brian Paul swImg->FetchTexel(swImg, i1, j1, slice, &depth11); 3654bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3655bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3656bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 3657bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick depth01 = depth00; 3658bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick depth11 = depth10; 3659bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 36602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 36612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 3662d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor depthRef = CLAMP(texcoords[i][compare_coord], 0.0F, 1.0F); 3663d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor 3664d9f584e663c7447e638acca2c164b16626a5271aPhilip Taylor result = shadow_compare4(function, depthRef, 3665a35ad020f9449849f7616788aa6bd9e439d6c518Brian Paul depth00, depth01, depth10, depth11, 3666707f0679157f83ac45127e41647b96ed924d45c9Ian Romanick wi, wj); 36672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 36689282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul apply_depth_mode(tObj->DepthMode, result, texel[i]); 36692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } /* for */ 36702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } /* if filter */ 36712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 36722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 36732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 36742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/** 36752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * We use this function when a texture object is in an "incomplete" state. 36762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * When a fragment program attempts to sample an incomplete texture we 36772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * return black (see issue 23 in GL_ARB_fragment_program spec). 36785bfb9356d6df4c8b1e177ebda01631d99355ba25Brian Paul * Note: fragment programs don't observe the texture enable/disable flags. 36792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 36802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 3681f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnull_sample_func( struct gl_context *ctx, 3682cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp, 36832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *tObj, GLuint n, 36842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLfloat texcoords[][4], const GLfloat lambda[], 3685de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat rgba[][4]) 36862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 36872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 36882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) ctx; 36892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) tObj; 36902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) texcoords; 36912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul (void) lambda; 3692cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen (void) samp; 36932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 36942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul rgba[i][RCOMP] = 0; 36952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul rgba[i][GCOMP] = 0; 36962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul rgba[i][BCOMP] = 0; 36973fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul rgba[i][ACOMP] = 1.0; 36982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 36992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 37002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 37012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 37022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/** 37032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Choose the texture sampling function for the given texture object. 37042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 37052cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paultexture_sample_func 3706f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_choose_texture_sample_func( struct gl_context *ctx, 3707f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul const struct gl_texture_object *t, 3708f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul const struct gl_sampler_object *sampler) 37092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 3710f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul if (!t || !_mesa_is_texture_complete(t, sampler)) { 37112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &null_sample_func; 37122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 37132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 3714ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul const GLboolean needLambda = 3715cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen (GLboolean) (sampler->MinFilter != sampler->MagFilter); 37162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 37172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul switch (t->Target) { 37182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_TEXTURE_1D: 37199282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul if (is_depth_texture(t)) { 37202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_depth_texture; 37212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 37222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else if (needLambda) { 37232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_lambda_1d; 37242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 3725cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen else if (sampler->MinFilter == GL_LINEAR) { 37262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_linear_1d; 37272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 37282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 3729cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen ASSERT(sampler->MinFilter == GL_NEAREST); 37302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_nearest_1d; 37312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 37322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_TEXTURE_2D: 37339282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul if (is_depth_texture(t)) { 37342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_depth_texture; 37352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 37362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else if (needLambda) { 37378a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* Anisotropic filtering extension. Activated only if mipmaps are used */ 3738cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen if (sampler->MaxAnisotropy > 1.0 && 3739cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sampler->MinFilter == GL_LINEAR_MIPMAP_LINEAR) { 37408a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger return &sample_lambda_2d_aniso; 37418a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 37422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_lambda_2d; 37432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 3744cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen else if (sampler->MinFilter == GL_LINEAR) { 37452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_linear_2d; 37462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 37472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 374806f606ce5761e673fca3f6b1f7dd40dace8a9906Brian Paul /* check for a few optimized cases */ 374906f606ce5761e673fca3f6b1f7dd40dace8a9906Brian Paul const struct gl_texture_image *img = t->Image[0][t->BaseLevel]; 3750eaf376ba354db11f7729452060570b48a029c9a0Brian Paul const struct swrast_texture_image *swImg = 3751eaf376ba354db11f7729452060570b48a029c9a0Brian Paul swrast_texture_image_const(img); 37529f7b6a39f6ebc070ff5020578cea2d299b21d476Yuanhan Liu texture_sample_func func; 3753eaf376ba354db11f7729452060570b48a029c9a0Brian Paul 3754cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen ASSERT(sampler->MinFilter == GL_NEAREST); 37559f7b6a39f6ebc070ff5020578cea2d299b21d476Yuanhan Liu func = &sample_nearest_2d; 3756cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen if (sampler->WrapS == GL_REPEAT && 3757cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen sampler->WrapT == GL_REPEAT && 3758eaf376ba354db11f7729452060570b48a029c9a0Brian Paul swImg->_IsPowerOfTwo && 37599f7b6a39f6ebc070ff5020578cea2d299b21d476Yuanhan Liu img->Border == 0) { 37609f7b6a39f6ebc070ff5020578cea2d299b21d476Yuanhan Liu if (img->TexFormat == MESA_FORMAT_RGB888) 37619f7b6a39f6ebc070ff5020578cea2d299b21d476Yuanhan Liu func = &opt_sample_rgb_2d; 37629f7b6a39f6ebc070ff5020578cea2d299b21d476Yuanhan Liu else if (img->TexFormat == MESA_FORMAT_RGBA8888) 37639f7b6a39f6ebc070ff5020578cea2d299b21d476Yuanhan Liu func = &opt_sample_rgba_2d; 37642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 37659f7b6a39f6ebc070ff5020578cea2d299b21d476Yuanhan Liu 37669f7b6a39f6ebc070ff5020578cea2d299b21d476Yuanhan Liu return func; 37672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 37682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_TEXTURE_3D: 37692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (needLambda) { 37702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_lambda_3d; 37712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 3772cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen else if (sampler->MinFilter == GL_LINEAR) { 37732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_linear_3d; 37742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 37752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 3776cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen ASSERT(sampler->MinFilter == GL_NEAREST); 37772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_nearest_3d; 37782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 37792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_TEXTURE_CUBE_MAP: 37809282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul if (needLambda) { 37812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_lambda_cube; 37822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 3783cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen else if (sampler->MinFilter == GL_LINEAR) { 37842cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_linear_cube; 37852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 37862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 3787cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen ASSERT(sampler->MinFilter == GL_NEAREST); 37882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_nearest_cube; 37892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 37902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_TEXTURE_RECTANGLE_NV: 37919282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul if (is_depth_texture(t)) { 3792fde15a2bae2f2ca552763705f12d53e4606feabfBrian return &sample_depth_texture; 3793fde15a2bae2f2ca552763705f12d53e4606feabfBrian } 3794fde15a2bae2f2ca552763705f12d53e4606feabfBrian else if (needLambda) { 37952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_lambda_rect; 37962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 3797cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen else if (sampler->MinFilter == GL_LINEAR) { 37982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_linear_rect; 37992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 38002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul else { 3801cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen ASSERT(sampler->MinFilter == GL_NEAREST); 38022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &sample_nearest_rect; 38032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 3804bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_TEXTURE_1D_ARRAY_EXT: 38059282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul if (is_depth_texture(t)) { 3806c3aae7745a648d5d8f8386e09cd6d965f919c7d9Anuj Phogat return &sample_depth_texture; 3807c3aae7745a648d5d8f8386e09cd6d965f919c7d9Anuj Phogat } 3808c3aae7745a648d5d8f8386e09cd6d965f919c7d9Anuj Phogat else if (needLambda) { 3809bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick return &sample_lambda_1d_array; 3810bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3811cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen else if (sampler->MinFilter == GL_LINEAR) { 3812bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick return &sample_linear_1d_array; 3813bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3814bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 3815cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen ASSERT(sampler->MinFilter == GL_NEAREST); 3816bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick return &sample_nearest_1d_array; 3817bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3818bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick case GL_TEXTURE_2D_ARRAY_EXT: 38199282ebbaa5fdb4bc1d6234d746acac525660185dBrian Paul if (is_depth_texture(t)) { 3820c3aae7745a648d5d8f8386e09cd6d965f919c7d9Anuj Phogat return &sample_depth_texture; 3821c3aae7745a648d5d8f8386e09cd6d965f919c7d9Anuj Phogat } 3822c3aae7745a648d5d8f8386e09cd6d965f919c7d9Anuj Phogat else if (needLambda) { 3823bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick return &sample_lambda_2d_array; 3824bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3825cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen else if (sampler->MinFilter == GL_LINEAR) { 3826bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick return &sample_linear_2d_array; 3827bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 3828bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick else { 3829cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen ASSERT(sampler->MinFilter == GL_NEAREST); 3830bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick return &sample_nearest_2d_array; 3831bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick } 38322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul default: 38332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul _mesa_problem(ctx, 38342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul "invalid target in _swrast_choose_texture_sample_func"); 38352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul return &null_sample_func; 38362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 38372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 38382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 3839