sp_tex_sample.c File Reference

Include dependency graph for sp_tex_sample.c:

Go to the source code of this file.

Defines

#define FRAC(f)   ((f) - util_ifloor(f))
 Texture sampling.
#define LERP(T, A, B)   ( (A) + (T) * ((B) - (A)) )
 Linear interpolation macro.
#define REMAINDER(A, B)   ((unsigned) (A) % (unsigned) (B))
 If A is a signed integer, A % B doesn't give the right value for A < 0 (in terms of texture repeat).

Functions

static float lerp_2d (float a, float b, float v00, float v10, float v01, float v11)
 Do 2D/biliner interpolation of float values.
static int nearest_texcoord (unsigned wrapMode, float s, unsigned size)
 Apply texture coord wrapping mode and return integer texture index.
static void linear_texcoord (unsigned wrapMode, float s, unsigned size, int *i0, int *i1, float *a)
 Used to compute texel locations for linear sampling.
static int nearest_texcoord_unnorm (unsigned wrapMode, float s, unsigned size)
 For RECT textures / unnormalized texcoords Only a subset of wrap modes supported.
static void linear_texcoord_unnorm (unsigned wrapMode, float s, unsigned size, int *i0, int *i1, float *a)
 For RECT textures / unnormalized texcoords.
static unsigned choose_cube_face (float rx, float ry, float rz, float *newS, float *newT)
static float compute_lambda (struct tgsi_sampler *sampler, const float s[QUAD_SIZE], const float t[QUAD_SIZE], const float p[QUAD_SIZE], float lodbias)
 Examine the quad's texture coordinates to compute the partial derivatives w.r.t X and Y, then compute lambda (level of detail).
static void choose_mipmap_levels (struct tgsi_sampler *sampler, const float s[QUAD_SIZE], const float t[QUAD_SIZE], const float p[QUAD_SIZE], float lodbias, unsigned *level0, unsigned *level1, float *levelBlend, unsigned *imgFilter)
 Do several things here: 1.
static void get_texel (struct tgsi_sampler *sampler, unsigned face, unsigned level, int x, int y, int z, float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j)
 Get a texel from a texture, using the texture tile cache.
static void shadow_compare (uint compare_func, float rgba[NUM_CHANNELS][QUAD_SIZE], const float p[QUAD_SIZE], uint j)
 Compare texcoord 'p' (aka R) against texture value 'rgba[0]' When we sampled the depth texture, the depth value was put into all RGBA channels.
static void sp_get_samples_2d_common (struct tgsi_sampler *sampler, const float s[QUAD_SIZE], const float t[QUAD_SIZE], const float p[QUAD_SIZE], float lodbias, float rgba[NUM_CHANNELS][QUAD_SIZE], const unsigned faces[4])
 Common code for sampling 1D/2D/cube textures.
static void sp_get_samples_1d (struct tgsi_sampler *sampler, const float s[QUAD_SIZE], const float t[QUAD_SIZE], const float p[QUAD_SIZE], float lodbias, float rgba[NUM_CHANNELS][QUAD_SIZE])
static void sp_get_samples_2d (struct tgsi_sampler *sampler, const float s[QUAD_SIZE], const float t[QUAD_SIZE], const float p[QUAD_SIZE], float lodbias, float rgba[NUM_CHANNELS][QUAD_SIZE])
static void sp_get_samples_3d (struct tgsi_sampler *sampler, const float s[QUAD_SIZE], const float t[QUAD_SIZE], const float p[QUAD_SIZE], float lodbias, float rgba[NUM_CHANNELS][QUAD_SIZE])
static void sp_get_samples_cube (struct tgsi_sampler *sampler, const float s[QUAD_SIZE], const float t[QUAD_SIZE], const float p[QUAD_SIZE], float lodbias, float rgba[NUM_CHANNELS][QUAD_SIZE])
static void sp_get_samples_rect (struct tgsi_sampler *sampler, const float s[QUAD_SIZE], const float t[QUAD_SIZE], const float p[QUAD_SIZE], float lodbias, float rgba[NUM_CHANNELS][QUAD_SIZE])
void sp_get_samples (struct tgsi_sampler *sampler, const float s[QUAD_SIZE], const float t[QUAD_SIZE], const float p[QUAD_SIZE], float lodbias, float rgba[NUM_CHANNELS][QUAD_SIZE])
 Called via tgsi_sampler::get_samples() Use the sampler's state setting to get a filtered RGBA value from the sampler's texture.


Define Documentation

#define FRAC (  )     ((f) - util_ifloor(f))

Texture sampling.

Authors: Brian Paul

Definition at line 54 of file sp_tex_sample.c.

#define LERP ( T,
A,
 )     ( (A) + (T) * ((B) - (A)) )

Linear interpolation macro.

Definition at line 60 of file sp_tex_sample.c.

#define REMAINDER ( A,
 )     ((unsigned) (A) % (unsigned) (B))

If A is a signed integer, A % B doesn't give the right value for A < 0 (in terms of texture repeat).

Just casting to unsigned fixes that.

Definition at line 85 of file sp_tex_sample.c.


Function Documentation

static unsigned choose_cube_face ( float  rx,
float  ry,
float  rz,
float *  newS,
float *  newT 
) [static]

Definition at line 392 of file sp_tex_sample.c.

References PIPE_TEX_FACE_NEG_X, PIPE_TEX_FACE_NEG_Y, PIPE_TEX_FACE_NEG_Z, PIPE_TEX_FACE_POS_X, PIPE_TEX_FACE_POS_Y, and PIPE_TEX_FACE_POS_Z.

00393 {
00394    /*
00395       major axis
00396       direction     target                             sc     tc    ma
00397       ----------    -------------------------------    ---    ---   ---
00398        +rx          TEXTURE_CUBE_MAP_POSITIVE_X_EXT    -rz    -ry   rx
00399        -rx          TEXTURE_CUBE_MAP_NEGATIVE_X_EXT    +rz    -ry   rx
00400        +ry          TEXTURE_CUBE_MAP_POSITIVE_Y_EXT    +rx    +rz   ry
00401        -ry          TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT    +rx    -rz   ry
00402        +rz          TEXTURE_CUBE_MAP_POSITIVE_Z_EXT    +rx    -ry   rz
00403        -rz          TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT    -rx    -ry   rz
00404    */
00405    const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz);
00406    unsigned face;
00407    float sc, tc, ma;
00408 
00409    if (arx > ary && arx > arz) {
00410       if (rx >= 0.0F) {
00411          face = PIPE_TEX_FACE_POS_X;
00412          sc = -rz;
00413          tc = -ry;
00414          ma = arx;
00415       }
00416       else {
00417          face = PIPE_TEX_FACE_NEG_X;
00418          sc = rz;
00419          tc = -ry;
00420          ma = arx;
00421       }
00422    }
00423    else if (ary > arx && ary > arz) {
00424       if (ry >= 0.0F) {
00425          face = PIPE_TEX_FACE_POS_Y;
00426          sc = rx;
00427          tc = rz;
00428          ma = ary;
00429       }
00430       else {
00431          face = PIPE_TEX_FACE_NEG_Y;
00432          sc = rx;
00433          tc = -rz;
00434          ma = ary;
00435       }
00436    }
00437    else {
00438       if (rz > 0.0F) {
00439          face = PIPE_TEX_FACE_POS_Z;
00440          sc = rx;
00441          tc = -ry;
00442          ma = arz;
00443       }
00444       else {
00445          face = PIPE_TEX_FACE_NEG_Z;
00446          sc = -rx;
00447          tc = -ry;
00448          ma = arz;
00449       }
00450    }
00451 
00452    *newS = ( sc / ma + 1.0F ) * 0.5F;
00453    *newT = ( tc / ma + 1.0F ) * 0.5F;
00454 
00455    return face;
00456 }

static void choose_mipmap_levels ( struct tgsi_sampler sampler,
const float  s[QUAD_SIZE],
const float  t[QUAD_SIZE],
const float  p[QUAD_SIZE],
float  lodbias,
unsigned *  level0,
unsigned *  level1,
float *  levelBlend,
unsigned *  imgFilter 
) [static]

Do several things here: 1.

Compute lambda from the texcoords, if needed 2. Determine if we're minifying or magnifying 3. If minifying, choose mipmap levels 4. Return image filter to use within mipmap images

Definition at line 519 of file sp_tex_sample.c.

References CLAMP, compute_lambda(), FRAC, pipe_texture::last_level, pipe_sampler_state::mag_img_filter, pipe_sampler_state::min_img_filter, pipe_sampler_state::min_lod, pipe_sampler_state::min_mip_filter, PIPE_TEX_MIPFILTER_NEAREST, PIPE_TEX_MIPFILTER_NONE, tgsi_sampler::state, and tgsi_sampler::texture.

00526 {
00527    if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) {
00528       /* no mipmap selection needed */
00529       *level0 = *level1 = CLAMP((int) sampler->state->min_lod,
00530                                 0, (int) sampler->texture->last_level);
00531 
00532       if (sampler->state->min_img_filter != sampler->state->mag_img_filter) {
00533          /* non-mipmapped texture, but still need to determine if doing
00534           * minification or magnification.
00535           */
00536          float lambda = compute_lambda(sampler, s, t, p, lodbias);
00537          if (lambda <= 0.0) {
00538             *imgFilter = sampler->state->mag_img_filter;
00539          }
00540          else {
00541             *imgFilter = sampler->state->min_img_filter;
00542          }
00543       }
00544       else {
00545          *imgFilter = sampler->state->mag_img_filter;
00546       }
00547    }
00548    else {
00549       float lambda;
00550 
00551       if (1)
00552          /* fragment shader */
00553          lambda = compute_lambda(sampler, s, t, p, lodbias);
00554       else
00555          /* vertex shader */
00556          lambda = lodbias; /* not really a bias, but absolute LOD */
00557 
00558       if (lambda <= 0.0) { /* XXX threshold depends on the filter */
00559          /* magnifying */
00560          *imgFilter = sampler->state->mag_img_filter;
00561          *level0 = *level1 = 0;
00562       }
00563       else {
00564          /* minifying */
00565          *imgFilter = sampler->state->min_img_filter;
00566 
00567          /* choose mipmap level(s) and compute the blend factor between them */
00568          if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NEAREST) {
00569             /* Nearest mipmap level */
00570             const int lvl = (int) (lambda + 0.5);
00571             *level0 =
00572             *level1 = CLAMP(lvl, 0, (int) sampler->texture->last_level);
00573          }
00574          else {
00575             /* Linear interpolation between mipmap levels */
00576             const int lvl = (int) lambda;
00577             *level0 = CLAMP(lvl,     0, (int) sampler->texture->last_level);
00578             *level1 = CLAMP(lvl + 1, 0, (int) sampler->texture->last_level);
00579             *levelBlend = FRAC(lambda);  /* blending weight between levels */
00580          }
00581       }
00582    }
00583 }

static float compute_lambda ( struct tgsi_sampler sampler,
const float  s[QUAD_SIZE],
const float  t[QUAD_SIZE],
const float  p[QUAD_SIZE],
float  lodbias 
) [static]

Examine the quad's texture coordinates to compute the partial derivatives w.r.t X and Y, then compute lambda (level of detail).

This is only done for fragment shaders, not vertex shaders.

Definition at line 466 of file sp_tex_sample.c.

References assert, CLAMP, pipe_texture::depth, pipe_texture::height, pipe_sampler_state::lod_bias, max(), MAX2, pipe_sampler_state::max_lod, pipe_sampler_state::min_lod, pipe_sampler_state::normalized_coords, QUAD_BOTTOM_LEFT, QUAD_BOTTOM_RIGHT, QUAD_TOP_LEFT, tgsi_sampler::state, tgsi_sampler::texture, util_fast_log2(), and pipe_texture::width.

00471 {
00472    float rho, lambda;
00473 
00474    assert(sampler->state->normalized_coords);
00475 
00476    assert(s);
00477    {
00478       float dsdx = s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT];
00479       float dsdy = s[QUAD_TOP_LEFT]     - s[QUAD_BOTTOM_LEFT];
00480       dsdx = fabsf(dsdx);
00481       dsdy = fabsf(dsdy);
00482       rho = MAX2(dsdx, dsdy) * sampler->texture->width[0];
00483    }
00484    if (t) {
00485       float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT];
00486       float dtdy = t[QUAD_TOP_LEFT]     - t[QUAD_BOTTOM_LEFT];
00487       float max;
00488       dtdx = fabsf(dtdx);
00489       dtdy = fabsf(dtdy);
00490       max = MAX2(dtdx, dtdy) * sampler->texture->height[0];
00491       rho = MAX2(rho, max);
00492    }
00493    if (p) {
00494       float dpdx = p[QUAD_BOTTOM_RIGHT] - p[QUAD_BOTTOM_LEFT];
00495       float dpdy = p[QUAD_TOP_LEFT]     - p[QUAD_BOTTOM_LEFT];
00496       float max;
00497       dpdx = fabsf(dpdx);
00498       dpdy = fabsf(dpdy);
00499       max = MAX2(dpdx, dpdy) * sampler->texture->depth[0];
00500       rho = MAX2(rho, max);
00501    }
00502 
00503    lambda = util_fast_log2(rho);
00504    lambda += lodbias + sampler->state->lod_bias;
00505    lambda = CLAMP(lambda, sampler->state->min_lod, sampler->state->max_lod);
00506 
00507    return lambda;
00508 }

static void get_texel ( struct tgsi_sampler sampler,
unsigned  face,
unsigned  level,
int  x,
int  y,
int  z,
float  rgba[NUM_CHANNELS][QUAD_SIZE],
unsigned  j 
) [static]

Get a texel from a texture, using the texture tile cache.

Parameters:
face the cube face in 0..5
level the mipmap level
x the x coord of texel within 2D image
y the y coord of texel within 2D image
z which slice of a 3D texture
rgba the quad to put the texel/color into
j which element of the rgba quad to write to
XXX maybe move this into sp_tile_cache.c and merge with the sp_get_cached_tile_tex() function. Also, get 4 texels instead of 1...

Definition at line 601 of file sp_tex_sample.c.

References pipe_sampler_state::border_color, tgsi_sampler::cache, softpipe_cached_tile::color, softpipe_cached_tile::data, debug_printf(), pipe_texture::depth, pipe_texture::format, pipe_texture::height, pf_name(), tgsi_sampler::pipe, sp_get_cached_tile_tex(), tgsi_sampler::state, tgsi_sampler::texture, TILE_SIZE, and pipe_texture::width.

00604 {
00605    if (x < 0 || x >= (int) sampler->texture->width[level] ||
00606        y < 0 || y >= (int) sampler->texture->height[level] ||
00607        z < 0 || z >= (int) sampler->texture->depth[level]) {
00608       rgba[0][j] = sampler->state->border_color[0];
00609       rgba[1][j] = sampler->state->border_color[1];
00610       rgba[2][j] = sampler->state->border_color[2];
00611       rgba[3][j] = sampler->state->border_color[3];
00612    }
00613    else {
00614       const int tx = x % TILE_SIZE;
00615       const int ty = y % TILE_SIZE;
00616       const struct softpipe_cached_tile *tile
00617          = sp_get_cached_tile_tex(sampler->pipe, sampler->cache,
00618                                   x, y, z, face, level);
00619       rgba[0][j] = tile->data.color[ty][tx][0];
00620       rgba[1][j] = tile->data.color[ty][tx][1];
00621       rgba[2][j] = tile->data.color[ty][tx][2];
00622       rgba[3][j] = tile->data.color[ty][tx][3];
00623       if (0)
00624       {
00625          debug_printf("Get texel %f %f %f %f from %s\n",
00626                       rgba[0][j], rgba[1][j], rgba[2][j], rgba[3][j],
00627                       pf_name(sampler->texture->format));
00628       }
00629    }
00630 }

static float lerp_2d ( float  a,
float  b,
float  v00,
float  v10,
float  v01,
float  v11 
) [static]

Do 2D/biliner interpolation of float values.

v00, v10, v01 and v11 are typically four texture samples in a square/box. a and b are the horizontal and vertical interpolants. It's important that this function is inlined when compiled with optimization! If we find that's not true on some systems, convert to a macro.

Definition at line 72 of file sp_tex_sample.c.

References LERP.

00074 {
00075    const float temp0 = LERP(a, v00, v10);
00076    const float temp1 = LERP(a, v01, v11);
00077    return LERP(b, temp0, temp1);
00078 }

static void linear_texcoord ( unsigned  wrapMode,
float  s,
unsigned  size,
int *  i0,
int *  i1,
float *  a 
) [static]

Used to compute texel locations for linear sampling.

Parameters:
wrapMode PIPE_TEX_WRAP_x
s the texcoord
size the texture image size
i0 returns first texture index
i1 returns second texture index (usually *i0 + 1)
a returns blend factor/weight between texture indexes

Definition at line 222 of file sp_tex_sample.c.

References assert, FRAC, max(), min(), PIPE_TEX_WRAP_CLAMP, PIPE_TEX_WRAP_CLAMP_TO_BORDER, PIPE_TEX_WRAP_CLAMP_TO_EDGE, PIPE_TEX_WRAP_MIRROR_CLAMP, PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER, PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE, PIPE_TEX_WRAP_MIRROR_REPEAT, PIPE_TEX_WRAP_REPEAT, REMAINDER, and util_ifloor().

00224 {
00225    float u;
00226    switch (wrapMode) {
00227    case PIPE_TEX_WRAP_REPEAT:
00228       u = s * size - 0.5F;
00229       *i0 = REMAINDER(util_ifloor(u), size);
00230       *i1 = REMAINDER(*i0 + 1, size);
00231       break;
00232    case PIPE_TEX_WRAP_CLAMP:
00233       if (s <= 0.0F)
00234          u = 0.0F;
00235       else if (s >= 1.0F)
00236          u = (float) size;
00237       else
00238          u = s * size;
00239       u -= 0.5F;
00240       *i0 = util_ifloor(u);
00241       *i1 = *i0 + 1;
00242       break;
00243    case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
00244       if (s <= 0.0F)
00245          u = 0.0F;
00246       else if (s >= 1.0F)
00247          u = (float) size;
00248       else
00249          u = s * size;
00250       u -= 0.5F;
00251       *i0 = util_ifloor(u);
00252       *i1 = *i0 + 1;
00253       if (*i0 < 0)
00254          *i0 = 0;
00255       if (*i1 >= (int) size)
00256          *i1 = size - 1;
00257       break;
00258    case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
00259       {
00260          const float min = -1.0F / (2.0F * size);
00261          const float max = 1.0F - min;
00262          if (s <= min)
00263             u = min * size;
00264          else if (s >= max)
00265             u = max * size;
00266          else
00267             u = s * size;
00268          u -= 0.5F;
00269          *i0 = util_ifloor(u);
00270          *i1 = *i0 + 1;
00271       }
00272       break;
00273    case PIPE_TEX_WRAP_MIRROR_REPEAT:
00274       {
00275          const int flr = util_ifloor(s);
00276          if (flr & 1)
00277             u = 1.0F - (s - (float) flr);
00278          else
00279             u = s - (float) flr;
00280          u = (u * size) - 0.5F;
00281          *i0 = util_ifloor(u);
00282          *i1 = *i0 + 1;
00283          if (*i0 < 0)
00284             *i0 = 0;
00285          if (*i1 >= (int) size)
00286             *i1 = size - 1;
00287       }
00288       break;
00289    case PIPE_TEX_WRAP_MIRROR_CLAMP:
00290       u = fabsf(s);
00291       if (u >= 1.0F)
00292          u = (float) size;
00293       else
00294          u *= size;
00295       u -= 0.5F;
00296       *i0 = util_ifloor(u);
00297       *i1 = *i0 + 1;
00298       break;
00299    case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
00300       u = fabsf(s);
00301       if (u >= 1.0F)
00302          u = (float) size;
00303       else
00304          u *= size;
00305       u -= 0.5F;
00306       *i0 = util_ifloor(u);
00307       *i1 = *i0 + 1;
00308       if (*i0 < 0)
00309          *i0 = 0;
00310       if (*i1 >= (int) size)
00311          *i1 = size - 1;
00312       break;
00313    case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
00314       {
00315          const float min = -1.0F / (2.0F * size);
00316          const float max = 1.0F - min;
00317          u = fabsf(s);
00318          if (u <= min)
00319             u = min * size;
00320          else if (u >= max)
00321             u = max * size;
00322          else
00323             u *= size;
00324          u -= 0.5F;
00325          *i0 = util_ifloor(u);
00326          *i1 = *i0 + 1;
00327       }
00328       break;
00329    default:
00330       assert(0);
00331    }
00332    *a = FRAC(u);
00333 }

static void linear_texcoord_unnorm ( unsigned  wrapMode,
float  s,
unsigned  size,
int *  i0,
int *  i1,
float *  a 
) [static]

For RECT textures / unnormalized texcoords.

Only a subset of wrap modes supported.

Definition at line 364 of file sp_tex_sample.c.

References assert, CLAMP, FRAC, PIPE_TEX_WRAP_CLAMP, PIPE_TEX_WRAP_CLAMP_TO_BORDER, PIPE_TEX_WRAP_CLAMP_TO_EDGE, and util_ifloor().

00366 {
00367    switch (wrapMode) {
00368    case PIPE_TEX_WRAP_CLAMP:
00369       /* Not exactly what the spec says, but it matches NVIDIA output */
00370       s = CLAMP(s - 0.5F, 0.0f, (float) size - 1.0f);
00371       *i0 = util_ifloor(s);
00372       *i1 = *i0 + 1;
00373       break;
00374    case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
00375       /* fall-through */
00376    case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
00377       s = CLAMP(s, 0.5F, (float) size - 0.5F);
00378       s -= 0.5F;
00379       *i0 = util_ifloor(s);
00380       *i1 = *i0 + 1;
00381       if (*i1 > (int) size - 1)
00382          *i1 = size - 1;
00383       break;
00384    default:
00385       assert(0);
00386    }
00387    *a = FRAC(s);
00388 }

static int nearest_texcoord ( unsigned  wrapMode,
float  s,
unsigned  size 
) [static]

Apply texture coord wrapping mode and return integer texture index.

Parameters:
wrapMode PIPE_TEX_WRAP_x
s the texcoord
size the texture image size
Returns:
integer texture index

Definition at line 96 of file sp_tex_sample.c.

References assert, max(), min(), PIPE_TEX_WRAP_CLAMP, PIPE_TEX_WRAP_CLAMP_TO_BORDER, PIPE_TEX_WRAP_CLAMP_TO_EDGE, PIPE_TEX_WRAP_MIRROR_CLAMP, PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER, PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE, PIPE_TEX_WRAP_MIRROR_REPEAT, PIPE_TEX_WRAP_REPEAT, REMAINDER, and util_ifloor().

00097 {
00098    int i;
00099    switch (wrapMode) {
00100    case PIPE_TEX_WRAP_REPEAT:
00101       /* s limited to [0,1) */
00102       /* i limited to [0,size-1] */
00103       i = util_ifloor(s * size);
00104       i = REMAINDER(i, size);
00105       return i;
00106    case PIPE_TEX_WRAP_CLAMP:
00107       /* s limited to [0,1] */
00108       /* i limited to [0,size-1] */
00109       if (s <= 0.0F)
00110          i = 0;
00111       else if (s >= 1.0F)
00112          i = size - 1;
00113       else
00114          i = util_ifloor(s * size);
00115       return i;
00116    case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
00117       {
00118          /* s limited to [min,max] */
00119          /* i limited to [0, size-1] */
00120          const float min = 1.0F / (2.0F * size);
00121          const float max = 1.0F - min;
00122          if (s < min)
00123             i = 0;
00124          else if (s > max)
00125             i = size - 1;
00126          else
00127             i = util_ifloor(s * size);
00128       }
00129       return i;
00130    case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
00131       {
00132          /* s limited to [min,max] */
00133          /* i limited to [-1, size] */
00134          const float min = -1.0F / (2.0F * size);
00135          const float max = 1.0F - min;
00136          if (s <= min)
00137             i = -1;
00138          else if (s >= max)
00139             i = size;
00140          else
00141             i = util_ifloor(s * size);
00142       }
00143       return i;
00144    case PIPE_TEX_WRAP_MIRROR_REPEAT:
00145       {
00146          const float min = 1.0F / (2.0F * size);
00147          const float max = 1.0F - min;
00148          const int flr = util_ifloor(s);
00149          float u;
00150          if (flr & 1)
00151             u = 1.0F - (s - (float) flr);
00152          else
00153             u = s - (float) flr;
00154          if (u < min)
00155             i = 0;
00156          else if (u > max)
00157             i = size - 1;
00158          else
00159             i = util_ifloor(u * size);
00160       }
00161       return i;
00162    case PIPE_TEX_WRAP_MIRROR_CLAMP:
00163       {
00164          /* s limited to [0,1] */
00165          /* i limited to [0,size-1] */
00166          const float u = fabsf(s);
00167          if (u <= 0.0F)
00168             i = 0;
00169          else if (u >= 1.0F)
00170             i = size - 1;
00171          else
00172             i = util_ifloor(u * size);
00173       }
00174       return i;
00175    case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
00176       {
00177          /* s limited to [min,max] */
00178          /* i limited to [0, size-1] */
00179          const float min = 1.0F / (2.0F * size);
00180          const float max = 1.0F - min;
00181          const float u = fabsf(s);
00182          if (u < min)
00183             i = 0;
00184          else if (u > max)
00185             i = size - 1;
00186          else
00187             i = util_ifloor(u * size);
00188       }
00189       return i;
00190    case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
00191       {
00192          /* s limited to [min,max] */
00193          /* i limited to [0, size-1] */
00194          const float min = -1.0F / (2.0F * size);
00195          const float max = 1.0F - min;
00196          const float u = fabsf(s);
00197          if (u < min)
00198             i = -1;
00199          else if (u > max)
00200             i = size;
00201          else
00202             i = util_ifloor(u * size);
00203       }
00204       return i;
00205    default:
00206       assert(0);
00207       return 0;
00208    }
00209 }

static int nearest_texcoord_unnorm ( unsigned  wrapMode,
float  s,
unsigned  size 
) [static]

For RECT textures / unnormalized texcoords Only a subset of wrap modes supported.

Definition at line 341 of file sp_tex_sample.c.

References assert, CLAMP, PIPE_TEX_WRAP_CLAMP, PIPE_TEX_WRAP_CLAMP_TO_BORDER, PIPE_TEX_WRAP_CLAMP_TO_EDGE, and util_ifloor().

00342 {
00343    int i;
00344    switch (wrapMode) {
00345    case PIPE_TEX_WRAP_CLAMP:
00346       i = util_ifloor(s);
00347       return CLAMP(i, 0, (int) size-1);
00348    case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
00349       /* fall-through */
00350    case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
00351       return util_ifloor( CLAMP(s, 0.5F, (float) size - 0.5F) );
00352    default:
00353       assert(0);
00354       return 0;
00355    }
00356 }

static void shadow_compare ( uint  compare_func,
float  rgba[NUM_CHANNELS][QUAD_SIZE],
const float  p[QUAD_SIZE],
uint  j 
) [static]

Compare texcoord 'p' (aka R) against texture value 'rgba[0]' When we sampled the depth texture, the depth value was put into all RGBA channels.

We look at the red channel here.

Definition at line 639 of file sp_tex_sample.c.

References assert, PIPE_FUNC_ALWAYS, PIPE_FUNC_EQUAL, PIPE_FUNC_GEQUAL, PIPE_FUNC_GREATER, PIPE_FUNC_LEQUAL, PIPE_FUNC_LESS, PIPE_FUNC_NEVER, and PIPE_FUNC_NOTEQUAL.

00643 {
00644    int k;
00645    switch (compare_func) {
00646    case PIPE_FUNC_LESS:
00647       k = p[j] < rgba[0][j];
00648       break;
00649    case PIPE_FUNC_LEQUAL:
00650       k = p[j] <= rgba[0][j];
00651       break;
00652    case PIPE_FUNC_GREATER:
00653       k = p[j] > rgba[0][j];
00654       break;
00655    case PIPE_FUNC_GEQUAL:
00656       k = p[j] >= rgba[0][j];
00657       break;
00658    case PIPE_FUNC_EQUAL:
00659       k = p[j] == rgba[0][j];
00660       break;
00661    case PIPE_FUNC_NOTEQUAL:
00662       k = p[j] != rgba[0][j];
00663       break;
00664    case PIPE_FUNC_ALWAYS:
00665       k = 1;
00666       break;
00667    case PIPE_FUNC_NEVER:
00668       k = 0;
00669       break;
00670    default:
00671       k = 0;
00672       assert(0);
00673       break;
00674    }
00675 
00676    rgba[0][j] = rgba[1][j] = rgba[2][j] = (float) k;
00677 }

void sp_get_samples ( struct tgsi_sampler sampler,
const float  s[QUAD_SIZE],
const float  t[QUAD_SIZE],
const float  p[QUAD_SIZE],
float  lodbias,
float  rgba[NUM_CHANNELS][QUAD_SIZE] 
)

Called via tgsi_sampler::get_samples() Use the sampler's state setting to get a filtered RGBA value from the sampler's texture.

XXX we can implement many versions of this function, each tightly coded for a specific combination of sampler state (nearest + repeat), (bilinear mipmap + clamp), etc.

The update_samplers() function in st_atom_sampler.c could create a new tgsi_sampler object for each state combo it finds....

Definition at line 1039 of file sp_tex_sample.c.

References assert, pipe_sampler_state::normalized_coords, PIPE_TEXTURE_1D, PIPE_TEXTURE_2D, PIPE_TEXTURE_3D, PIPE_TEXTURE_CUBE, sp_get_samples_1d(), sp_get_samples_2d(), sp_get_samples_3d(), sp_get_samples_cube(), sp_get_samples_rect(), tgsi_sampler::state, pipe_texture::target, and tgsi_sampler::texture.

01045 {
01046    if (!sampler->texture)
01047       return;
01048 
01049    switch (sampler->texture->target) {
01050    case PIPE_TEXTURE_1D:
01051       assert(sampler->state->normalized_coords);
01052       sp_get_samples_1d(sampler, s, t, p, lodbias, rgba);
01053       break;
01054    case PIPE_TEXTURE_2D:
01055       if (sampler->state->normalized_coords)
01056          sp_get_samples_2d(sampler, s, t, p, lodbias, rgba);
01057       else
01058          sp_get_samples_rect(sampler, s, t, p, lodbias, rgba);
01059       break;
01060    case PIPE_TEXTURE_3D:
01061       assert(sampler->state->normalized_coords);
01062       sp_get_samples_3d(sampler, s, t, p, lodbias, rgba);
01063       break;
01064    case PIPE_TEXTURE_CUBE:
01065       assert(sampler->state->normalized_coords);
01066       sp_get_samples_cube(sampler, s, t, p, lodbias, rgba);
01067       break;
01068    default:
01069       assert(0);
01070    }
01071 
01072 #if 0 /* DEBUG */
01073    {
01074       int i;
01075       printf("Sampled at %f, %f, %f:\n", s[0], t[0], p[0]);
01076       for (i = 0; i < 4; i++) {
01077          printf("Frag %d: %f %f %f %f\n", i,
01078                 rgba[0][i],
01079                 rgba[1][i],
01080                 rgba[2][i],
01081                 rgba[3][i]);
01082       }
01083    }
01084 #endif
01085 }

static void sp_get_samples_1d ( struct tgsi_sampler sampler,
const float  s[QUAD_SIZE],
const float  t[QUAD_SIZE],
const float  p[QUAD_SIZE],
float  lodbias,
float  rgba[NUM_CHANNELS][QUAD_SIZE] 
) [static]

Definition at line 793 of file sp_tex_sample.c.

References sp_get_samples_2d_common().

00799 {
00800    static const unsigned faces[4] = {0, 0, 0, 0};
00801    static const float tzero[4] = {0, 0, 0, 0};
00802    sp_get_samples_2d_common(sampler, s, tzero, NULL, lodbias, rgba, faces);
00803 }

static void sp_get_samples_2d ( struct tgsi_sampler sampler,
const float  s[QUAD_SIZE],
const float  t[QUAD_SIZE],
const float  p[QUAD_SIZE],
float  lodbias,
float  rgba[NUM_CHANNELS][QUAD_SIZE] 
) [static]

Definition at line 807 of file sp_tex_sample.c.

References sp_get_samples_2d_common().

00813 {
00814    static const unsigned faces[4] = {0, 0, 0, 0};
00815    sp_get_samples_2d_common(sampler, s, t, p, lodbias, rgba, faces);
00816 }

static void sp_get_samples_2d_common ( struct tgsi_sampler sampler,
const float  s[QUAD_SIZE],
const float  t[QUAD_SIZE],
const float  p[QUAD_SIZE],
float  lodbias,
float  rgba[NUM_CHANNELS][QUAD_SIZE],
const unsigned  faces[4] 
) [static]

Common code for sampling 1D/2D/cube textures.

Could probably extend for 3D...

Definition at line 685 of file sp_tex_sample.c.

References assert, choose_mipmap_levels(), pipe_sampler_state::compare_func, pipe_sampler_state::compare_mode, get_texel(), pipe_texture::height, LERP, lerp_2d(), linear_texcoord(), nearest_texcoord(), pipe_sampler_state::normalized_coords, NUM_CHANNELS, PIPE_TEX_COMPARE_R_TO_TEXTURE, PIPE_TEX_FILTER_ANISO, PIPE_TEX_FILTER_LINEAR, PIPE_TEX_FILTER_NEAREST, shadow_compare(), tgsi_sampler::state, tgsi_sampler::texture, pipe_texture::width, pipe_sampler_state::wrap_s, pipe_sampler_state::wrap_t, softpipe_cached_tile::x, and softpipe_cached_tile::y.

00692 {
00693    const uint compare_func = sampler->state->compare_func;
00694    unsigned level0, level1, j, imgFilter;
00695    int width, height;
00696    float levelBlend;
00697 
00698    choose_mipmap_levels(sampler, s, t, p, lodbias,
00699                         &level0, &level1, &levelBlend, &imgFilter);
00700 
00701    assert(sampler->state->normalized_coords);
00702 
00703    width = sampler->texture->width[level0];
00704    height = sampler->texture->height[level0];
00705 
00706    assert(width > 0);
00707 
00708    switch (imgFilter) {
00709    case PIPE_TEX_FILTER_NEAREST:
00710       for (j = 0; j < QUAD_SIZE; j++) {
00711          int x = nearest_texcoord(sampler->state->wrap_s, s[j], width);
00712          int y = nearest_texcoord(sampler->state->wrap_t, t[j], height);
00713          get_texel(sampler, faces[j], level0, x, y, 0, rgba, j);
00714          if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
00715             shadow_compare(compare_func, rgba, p, j);
00716          }
00717 
00718          if (level0 != level1) {
00719             /* get texels from second mipmap level and blend */
00720             float rgba2[4][4];
00721             unsigned c;
00722             x = x / 2;
00723             y = y / 2;
00724             get_texel(sampler, faces[j], level1, x, y, 0, rgba2, j);
00725             if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
00726                shadow_compare(compare_func, rgba2, p, j);
00727             }
00728 
00729             for (c = 0; c < NUM_CHANNELS; c++) {
00730                rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]);
00731             }
00732          }
00733       }
00734       break;
00735    case PIPE_TEX_FILTER_LINEAR:
00736    case PIPE_TEX_FILTER_ANISO:
00737       for (j = 0; j < QUAD_SIZE; j++) {
00738          float tx[4][4], a, b;
00739          int x0, y0, x1, y1, c;
00740          linear_texcoord(sampler->state->wrap_s, s[j], width,  &x0, &x1, &a);
00741          linear_texcoord(sampler->state->wrap_t, t[j], height, &y0, &y1, &b);
00742          get_texel(sampler, faces[j], level0, x0, y0, 0, tx, 0);
00743          get_texel(sampler, faces[j], level0, x1, y0, 0, tx, 1);
00744          get_texel(sampler, faces[j], level0, x0, y1, 0, tx, 2);
00745          get_texel(sampler, faces[j], level0, x1, y1, 0, tx, 3);
00746          if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
00747             shadow_compare(compare_func, tx, p, 0);
00748             shadow_compare(compare_func, tx, p, 1);
00749             shadow_compare(compare_func, tx, p, 2);
00750             shadow_compare(compare_func, tx, p, 3);
00751          }
00752 
00753          for (c = 0; c < 4; c++) {
00754             rgba[c][j] = lerp_2d(a, b, tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
00755          }
00756 
00757          if (level0 != level1) {
00758             /* get texels from second mipmap level and blend */
00759             float rgba2[4][4];
00760             x0 = x0 / 2;
00761             y0 = y0 / 2;
00762             x1 = x1 / 2;
00763             y1 = y1 / 2;
00764             get_texel(sampler, faces[j], level1, x0, y0, 0, tx, 0);
00765             get_texel(sampler, faces[j], level1, x1, y0, 0, tx, 1);
00766             get_texel(sampler, faces[j], level1, x0, y1, 0, tx, 2);
00767             get_texel(sampler, faces[j], level1, x1, y1, 0, tx, 3);
00768             if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
00769                shadow_compare(compare_func, tx, p, 0);
00770                shadow_compare(compare_func, tx, p, 1);
00771                shadow_compare(compare_func, tx, p, 2);
00772                shadow_compare(compare_func, tx, p, 3);
00773             }
00774 
00775             for (c = 0; c < 4; c++) {
00776                rgba2[c][j] = lerp_2d(a, b,
00777                                      tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
00778             }
00779 
00780             for (c = 0; c < NUM_CHANNELS; c++) {
00781                rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]);
00782             }
00783          }
00784       }
00785       break;
00786    default:
00787       assert(0);
00788    }
00789 }

static void sp_get_samples_3d ( struct tgsi_sampler sampler,
const float  s[QUAD_SIZE],
const float  t[QUAD_SIZE],
const float  p[QUAD_SIZE],
float  lodbias,
float  rgba[NUM_CHANNELS][QUAD_SIZE] 
) [static]

Definition at line 820 of file sp_tex_sample.c.

References assert, choose_mipmap_levels(), pipe_texture::depth, softpipe_cached_tile::face, get_texel(), pipe_texture::height, LERP, lerp_2d(), linear_texcoord(), nearest_texcoord(), pipe_sampler_state::normalized_coords, NUM_CHANNELS, PIPE_TEX_FILTER_ANISO, PIPE_TEX_FILTER_LINEAR, PIPE_TEX_FILTER_NEAREST, tgsi_sampler::state, tgsi_sampler::texture, pipe_texture::width, pipe_sampler_state::wrap_r, pipe_sampler_state::wrap_s, pipe_sampler_state::wrap_t, softpipe_cached_tile::x, softpipe_cached_tile::y, and softpipe_cached_tile::z.

00826 {
00827    /* get/map pipe_surfaces corresponding to 3D tex slices */
00828    unsigned level0, level1, j, imgFilter;
00829    int width, height, depth;
00830    float levelBlend;
00831    const uint face = 0;
00832 
00833    choose_mipmap_levels(sampler, s, t, p, lodbias,
00834                         &level0, &level1, &levelBlend, &imgFilter);
00835 
00836    assert(sampler->state->normalized_coords);
00837 
00838    width = sampler->texture->width[level0];
00839    height = sampler->texture->height[level0];
00840    depth = sampler->texture->depth[level0];
00841 
00842    assert(width > 0);
00843    assert(height > 0);
00844    assert(depth > 0);
00845 
00846    switch (imgFilter) {
00847    case PIPE_TEX_FILTER_NEAREST:
00848       for (j = 0; j < QUAD_SIZE; j++) {
00849          int x = nearest_texcoord(sampler->state->wrap_s, s[j], width);
00850          int y = nearest_texcoord(sampler->state->wrap_t, t[j], height);
00851          int z = nearest_texcoord(sampler->state->wrap_r, p[j], depth);
00852          get_texel(sampler, face, level0, x, y, z, rgba, j);
00853 
00854          if (level0 != level1) {
00855             /* get texels from second mipmap level and blend */
00856             float rgba2[4][4];
00857             unsigned c;
00858             x /= 2;
00859             y /= 2;
00860             z /= 2;
00861             get_texel(sampler, face, level1, x, y, z, rgba2, j);
00862             for (c = 0; c < NUM_CHANNELS; c++) {
00863                rgba[c][j] = LERP(levelBlend, rgba2[c][j], rgba[c][j]);
00864             }
00865          }
00866       }
00867       break;
00868    case PIPE_TEX_FILTER_LINEAR:
00869    case PIPE_TEX_FILTER_ANISO:
00870       for (j = 0; j < QUAD_SIZE; j++) {
00871          float texel0[4][4], texel1[4][4];
00872          float xw, yw, zw; /* interpolation weights */
00873          int x0, x1, y0, y1, z0, z1, c;
00874          linear_texcoord(sampler->state->wrap_s, s[j], width,  &x0, &x1, &xw);
00875          linear_texcoord(sampler->state->wrap_t, t[j], height, &y0, &y1, &yw);
00876          linear_texcoord(sampler->state->wrap_r, p[j], depth,  &z0, &z1, &zw);
00877          get_texel(sampler, face, level0, x0, y0, z0, texel0, 0);
00878          get_texel(sampler, face, level0, x1, y0, z0, texel0, 1);
00879          get_texel(sampler, face, level0, x0, y1, z0, texel0, 2);
00880          get_texel(sampler, face, level0, x1, y1, z0, texel0, 3);
00881          get_texel(sampler, face, level0, x0, y0, z1, texel1, 0);
00882          get_texel(sampler, face, level0, x1, y0, z1, texel1, 1);
00883          get_texel(sampler, face, level0, x0, y1, z1, texel1, 2);
00884          get_texel(sampler, face, level0, x1, y1, z1, texel1, 3);
00885 
00886          /* 3D lerp */
00887          for (c = 0; c < 4; c++) {
00888             float ctemp0[4][4], ctemp1[4][4];
00889             ctemp0[c][j] = lerp_2d(xw, yw,
00890                                    texel0[c][0], texel0[c][1],
00891                                    texel0[c][2], texel0[c][3]);
00892             ctemp1[c][j] = lerp_2d(xw, yw,
00893                                    texel1[c][0], texel1[c][1],
00894                                    texel1[c][2], texel1[c][3]);
00895             rgba[c][j] = LERP(zw, ctemp0[c][j], ctemp1[c][j]);
00896          }
00897 
00898          if (level0 != level1) {
00899             /* get texels from second mipmap level and blend */
00900             float rgba2[4][4];
00901             x0 /= 2;
00902             y0 /= 2;
00903             z0 /= 2;
00904             x1 /= 2;
00905             y1 /= 2;
00906             z1 /= 2;
00907             get_texel(sampler, face, level1, x0, y0, z0, texel0, 0);
00908             get_texel(sampler, face, level1, x1, y0, z0, texel0, 1);
00909             get_texel(sampler, face, level1, x0, y1, z0, texel0, 2);
00910             get_texel(sampler, face, level1, x1, y1, z0, texel0, 3);
00911             get_texel(sampler, face, level1, x0, y0, z1, texel1, 0);
00912             get_texel(sampler, face, level1, x1, y0, z1, texel1, 1);
00913             get_texel(sampler, face, level1, x0, y1, z1, texel1, 2);
00914             get_texel(sampler, face, level1, x1, y1, z1, texel1, 3);
00915 
00916             /* 3D lerp */
00917             for (c = 0; c < 4; c++) {
00918                float ctemp0[4][4], ctemp1[4][4];
00919                ctemp0[c][j] = lerp_2d(xw, yw,
00920                                       texel0[c][0], texel0[c][1],
00921                                       texel0[c][2], texel0[c][3]);
00922                ctemp1[c][j] = lerp_2d(xw, yw,
00923                                       texel1[c][0], texel1[c][1],
00924                                       texel1[c][2], texel1[c][3]);
00925                rgba2[c][j] = LERP(zw, ctemp0[c][j], ctemp1[c][j]);
00926             }
00927 
00928             /* blend mipmap levels */
00929             for (c = 0; c < NUM_CHANNELS; c++) {
00930                rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]);
00931             }
00932          }
00933       }
00934       break;
00935    default:
00936       assert(0);
00937    }
00938 }

static void sp_get_samples_cube ( struct tgsi_sampler sampler,
const float  s[QUAD_SIZE],
const float  t[QUAD_SIZE],
const float  p[QUAD_SIZE],
float  lodbias,
float  rgba[NUM_CHANNELS][QUAD_SIZE] 
) [static]

Definition at line 942 of file sp_tex_sample.c.

References choose_cube_face(), and sp_get_samples_2d_common().

00948 {
00949    unsigned faces[QUAD_SIZE], j;
00950    float ssss[4], tttt[4];
00951    for (j = 0; j < QUAD_SIZE; j++) {
00952       faces[j] = choose_cube_face(s[j], t[j], p[j], ssss + j, tttt + j);
00953    }
00954    sp_get_samples_2d_common(sampler, ssss, tttt, NULL, lodbias, rgba, faces);
00955 }

static void sp_get_samples_rect ( struct tgsi_sampler sampler,
const float  s[QUAD_SIZE],
const float  t[QUAD_SIZE],
const float  p[QUAD_SIZE],
float  lodbias,
float  rgba[NUM_CHANNELS][QUAD_SIZE] 
) [static]

Definition at line 959 of file sp_tex_sample.c.

References assert, choose_mipmap_levels(), pipe_sampler_state::compare_func, pipe_sampler_state::compare_mode, softpipe_cached_tile::face, get_texel(), pipe_texture::height, lerp_2d(), linear_texcoord_unnorm(), nearest_texcoord_unnorm(), PIPE_TEX_COMPARE_R_TO_TEXTURE, PIPE_TEX_FILTER_ANISO, PIPE_TEX_FILTER_LINEAR, PIPE_TEX_FILTER_NEAREST, shadow_compare(), tgsi_sampler::state, tgsi_sampler::texture, pipe_texture::width, pipe_sampler_state::wrap_s, pipe_sampler_state::wrap_t, softpipe_cached_tile::x, and softpipe_cached_tile::y.

00965 {
00966    //sp_get_samples_2d_common(sampler, s, t, p, lodbias, rgba, faces);
00967    static const uint face = 0;
00968    const uint compare_func = sampler->state->compare_func;
00969    unsigned level0, level1, j, imgFilter;
00970    int width, height;
00971    float levelBlend;
00972 
00973    choose_mipmap_levels(sampler, s, t, p, lodbias,
00974                         &level0, &level1, &levelBlend, &imgFilter);
00975 
00976    /* texture RECTS cannot be mipmapped */
00977    assert(level0 == level1);
00978 
00979    width = sampler->texture->width[level0];
00980    height = sampler->texture->height[level0];
00981 
00982    assert(width > 0);
00983 
00984    switch (imgFilter) {
00985    case PIPE_TEX_FILTER_NEAREST:
00986       for (j = 0; j < QUAD_SIZE; j++) {
00987          int x = nearest_texcoord_unnorm(sampler->state->wrap_s, s[j], width);
00988          int y = nearest_texcoord_unnorm(sampler->state->wrap_t, t[j], height);
00989          get_texel(sampler, face, level0, x, y, 0, rgba, j);
00990          if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
00991             shadow_compare(compare_func, rgba, p, j);
00992          }
00993       }
00994       break;
00995    case PIPE_TEX_FILTER_LINEAR:
00996    case PIPE_TEX_FILTER_ANISO:
00997       for (j = 0; j < QUAD_SIZE; j++) {
00998          float tx[4][4], a, b;
00999          int x0, y0, x1, y1, c;
01000          linear_texcoord_unnorm(sampler->state->wrap_s, s[j], width,  &x0, &x1, &a);
01001          linear_texcoord_unnorm(sampler->state->wrap_t, t[j], height, &y0, &y1, &b);
01002          get_texel(sampler, face, level0, x0, y0, 0, tx, 0);
01003          get_texel(sampler, face, level0, x1, y0, 0, tx, 1);
01004          get_texel(sampler, face, level0, x0, y1, 0, tx, 2);
01005          get_texel(sampler, face, level0, x1, y1, 0, tx, 3);
01006          if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
01007             shadow_compare(compare_func, tx, p, 0);
01008             shadow_compare(compare_func, tx, p, 1);
01009             shadow_compare(compare_func, tx, p, 2);
01010             shadow_compare(compare_func, tx, p, 3);
01011          }
01012 
01013          for (c = 0; c < 4; c++) {
01014             rgba[c][j] = lerp_2d(a, b, tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
01015          }
01016       }
01017       break;
01018    default:
01019       assert(0);
01020    }
01021 }


Generated on Tue Sep 29 06:25:42 2009 for Gallium3D by  doxygen 1.5.4