*
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
- * Copyright 2008 VMware, Inc. All rights reserved.
+ * Copyright 2008-2010 VMware, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
/*
- * Note, the FRAC macro has to work perfectly. Otherwise you'll sometimes
- * see 1-pixel bands of improperly weighted linear-filtered textures.
+ * Return fractional part of 'f'. Used for computing interpolation weights.
+ * Need to be careful with negative values.
+ * Note, if this function isn't perfect you'll sometimes see 1-pixel bands
+ * of improperly weighted linear-filtered textures.
* The tests/texwrap.c demo is a good test.
- * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0.
- * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x).
*/
-#define FRAC(f) ((f) - util_ifloor(f))
+static INLINE float
+frac(float f)
+{
+ return f - util_ifloor(f);
+}
+
/**
/**
- * 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.
+ * Compute coord % size for repeat wrap modes.
+ * Note that if coord is a signed integer, coord % size doesn't give
+ * the right value for coord < 0 (in terms of texture repeat). Just
+ * casting to unsigned fixes that.
*/
-#define REMAINDER(A, B) ((unsigned) (A) % (unsigned) (B))
+static INLINE int
+repeat(int coord, unsigned size)
+{
+ return (int) ((unsigned) coord % size);
+}
/**
* \return integer texture index
*/
static void
-wrap_nearest_repeat(const float s[4], unsigned size,
- int icoord[4])
+wrap_nearest_repeat(const float s[4], unsigned size, int icoord[4])
{
uint ch;
-
/* s limited to [0,1) */
/* i limited to [0,size-1] */
for (ch = 0; ch < 4; ch++) {
int i = util_ifloor(s[ch] * size);
- icoord[ch] = REMAINDER(i, size);
+ icoord[ch] = repeat(i, size);
}
}
static void
-wrap_nearest_clamp(const float s[4], unsigned size,
- int icoord[4])
+wrap_nearest_clamp(const float s[4], unsigned size, int icoord[4])
{
uint ch;
/* s limited to [0,1] */
static void
-wrap_nearest_clamp_to_edge(const float s[4], unsigned size,
- int icoord[4])
+wrap_nearest_clamp_to_edge(const float s[4], unsigned size, int icoord[4])
{
uint ch;
/* s limited to [min,max] */
static void
-wrap_nearest_clamp_to_border(const float s[4], unsigned size,
- int icoord[4])
+wrap_nearest_clamp_to_border(const float s[4], unsigned size, int icoord[4])
{
uint ch;
/* s limited to [min,max] */
}
}
+
static void
-wrap_nearest_mirror_repeat(const float s[4], unsigned size,
- int icoord[4])
+wrap_nearest_mirror_repeat(const float s[4], unsigned size, int icoord[4])
{
uint ch;
const float min = 1.0F / (2.0F * size);
}
}
+
static void
-wrap_nearest_mirror_clamp(const float s[4], unsigned size,
- int icoord[4])
+wrap_nearest_mirror_clamp(const float s[4], unsigned size, int icoord[4])
{
uint ch;
for (ch = 0; ch < 4; ch++) {
}
}
+
static void
wrap_nearest_mirror_clamp_to_edge(const float s[4], unsigned size,
- int icoord[4])
+ int icoord[4])
{
uint ch;
/* s limited to [min,max] */
int icoord0[4], int icoord1[4], float w[4])
{
uint ch;
-
for (ch = 0; ch < 4; ch++) {
float u = s[ch] * size - 0.5F;
- icoord0[ch] = REMAINDER(util_ifloor(u), size);
- icoord1[ch] = REMAINDER(icoord0[ch] + 1, size);
- w[ch] = FRAC(u);
+ icoord0[ch] = repeat(util_ifloor(u), size);
+ icoord1[ch] = repeat(icoord0[ch] + 1, size);
+ w[ch] = frac(u);
}
}
+
static void
wrap_linear_clamp(const float s[4], unsigned size,
int icoord0[4], int icoord1[4], float w[4])
u = u * size - 0.5f;
icoord0[ch] = util_ifloor(u);
icoord1[ch] = icoord0[ch] + 1;
- w[ch] = FRAC(u);
+ w[ch] = frac(u);
}
}
+
static void
wrap_linear_clamp_to_edge(const float s[4], unsigned size,
int icoord0[4], int icoord1[4], float w[4])
icoord0[ch] = 0;
if (icoord1[ch] >= (int) size)
icoord1[ch] = size - 1;
- w[ch] = FRAC(u);
+ w[ch] = frac(u);
}
}
+
static void
wrap_linear_clamp_to_border(const float s[4], unsigned size,
int icoord0[4], int icoord1[4], float w[4])
u = u * size - 0.5f;
icoord0[ch] = util_ifloor(u);
icoord1[ch] = icoord0[ch] + 1;
- w[ch] = FRAC(u);
+ w[ch] = frac(u);
}
}
icoord0[ch] = 0;
if (icoord1[ch] >= (int) size)
icoord1[ch] = size - 1;
- w[ch] = FRAC(u);
+ w[ch] = frac(u);
}
}
+
static void
wrap_linear_mirror_clamp(const float s[4], unsigned size,
int icoord0[4], int icoord1[4], float w[4])
u -= 0.5F;
icoord0[ch] = util_ifloor(u);
icoord1[ch] = icoord0[ch] + 1;
- w[ch] = FRAC(u);
+ w[ch] = frac(u);
}
}
+
static void
wrap_linear_mirror_clamp_to_edge(const float s[4], unsigned size,
int icoord0[4], int icoord1[4], float w[4])
icoord0[ch] = 0;
if (icoord1[ch] >= (int) size)
icoord1[ch] = size - 1;
- w[ch] = FRAC(u);
+ w[ch] = frac(u);
}
}
+
static void
wrap_linear_mirror_clamp_to_border(const float s[4], unsigned size,
int icoord0[4], int icoord1[4], float w[4])
u -= 0.5F;
icoord0[ch] = util_ifloor(u);
icoord1[ch] = icoord0[ch] + 1;
- w[ch] = FRAC(u);
+ w[ch] = frac(u);
}
}
* Only a subset of wrap modes supported.
*/
static void
-wrap_nearest_unorm_clamp(const float s[4], unsigned size,
- int icoord[4])
+wrap_nearest_unorm_clamp(const float s[4], unsigned size, int icoord[4])
{
uint ch;
for (ch = 0; ch < 4; ch++) {
}
}
-/* Handles clamp_to_edge and clamp_to_border:
+
+/**
+ * Handles clamp_to_edge and clamp_to_border:
*/
static void
wrap_nearest_unorm_clamp_to_border(const float s[4], unsigned size,
- int icoord[4])
+ int icoord[4])
{
uint ch;
for (ch = 0; ch < 4; ch++) {
*/
static void
wrap_linear_unorm_clamp(const float s[4], unsigned size,
- int icoord0[4], int icoord1[4], float w[4])
+ int icoord0[4], int icoord1[4], float w[4])
{
uint ch;
for (ch = 0; ch < 4; ch++) {
float u = CLAMP(s[ch] - 0.5F, 0.0f, (float) size - 1.0f);
icoord0[ch] = util_ifloor(u);
icoord1[ch] = icoord0[ch] + 1;
- w[ch] = FRAC(u);
+ w[ch] = frac(u);
}
}
+
static void
-wrap_linear_unorm_clamp_to_border( const float s[4], unsigned size,
- int icoord0[4], int icoord1[4], float w[4])
+wrap_linear_unorm_clamp_to_border(const float s[4], unsigned size,
+ int icoord0[4], int icoord1[4], float w[4])
{
uint ch;
for (ch = 0; ch < 4; ch++) {
icoord1[ch] = icoord0[ch] + 1;
if (icoord1[ch] > (int) size - 1)
icoord1[ch] = size - 1;
- w[ch] = FRAC(u);
+ w[ch] = frac(u);
}
}
-
-
/**
* Examine the quad's texture coordinates to compute the partial
* derivatives w.r.t X and Y, then compute lambda (level of detail).
compute_lambda_1d(const struct sp_sampler_varient *samp,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
- const float p[QUAD_SIZE],
- float lodbias)
+ const float p[QUAD_SIZE])
{
const struct pipe_texture *texture = samp->texture;
const struct pipe_sampler_state *sampler = samp->sampler;
float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]);
float dsdy = fabsf(s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]);
- float rho = MAX2(dsdx, dsdy) * texture->width[0];
- float lambda;
-
- lambda = util_fast_log2(rho);
- lambda += lodbias + sampler->lod_bias;
- lambda = CLAMP(lambda, sampler->min_lod, sampler->max_lod);
+ float rho = MAX2(dsdx, dsdy) * texture->width0;
- return lambda;
+ return util_fast_log2(rho);
}
+
static float
compute_lambda_2d(const struct sp_sampler_varient *samp,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
- const float p[QUAD_SIZE],
- float lodbias)
+ const float p[QUAD_SIZE])
{
const struct pipe_texture *texture = samp->texture;
const struct pipe_sampler_state *sampler = samp->sampler;
float dsdy = fabsf(s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]);
float dtdx = fabsf(t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]);
float dtdy = fabsf(t[QUAD_TOP_LEFT] - t[QUAD_BOTTOM_LEFT]);
- float maxx = MAX2(dsdx, dsdy) * texture->width[0];
- float maxy = MAX2(dtdx, dtdy) * texture->height[0];
+ float maxx = MAX2(dsdx, dsdy) * texture->width0;
+ float maxy = MAX2(dtdx, dtdy) * texture->height0;
float rho = MAX2(maxx, maxy);
- float lambda;
-
- lambda = util_fast_log2(rho);
- lambda += lodbias + sampler->lod_bias;
- lambda = CLAMP(lambda, sampler->min_lod, sampler->max_lod);
- return lambda;
+ return util_fast_log2(rho);
}
compute_lambda_3d(const struct sp_sampler_varient *samp,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
- const float p[QUAD_SIZE],
- float lodbias)
+ const float p[QUAD_SIZE])
{
const struct pipe_texture *texture = samp->texture;
const struct pipe_sampler_state *sampler = samp->sampler;
float dtdy = fabsf(t[QUAD_TOP_LEFT] - t[QUAD_BOTTOM_LEFT]);
float dpdx = fabsf(p[QUAD_BOTTOM_RIGHT] - p[QUAD_BOTTOM_LEFT]);
float dpdy = fabsf(p[QUAD_TOP_LEFT] - p[QUAD_BOTTOM_LEFT]);
- float maxx = MAX2(dsdx, dsdy) * texture->width[0];
- float maxy = MAX2(dtdx, dtdy) * texture->height[0];
- float maxz = MAX2(dpdx, dpdy) * texture->depth[0];
- float rho, lambda;
+ float maxx = MAX2(dsdx, dsdy) * texture->width0;
+ float maxy = MAX2(dtdx, dtdy) * texture->height0;
+ float maxz = MAX2(dpdx, dpdy) * texture->depth0;
+ float rho;
rho = MAX2(maxx, maxy);
rho = MAX2(rho, maxz);
- lambda = util_fast_log2(rho);
- lambda += lodbias + sampler->lod_bias;
- lambda = CLAMP(lambda, sampler->min_lod, sampler->max_lod);
-
- return lambda;
+ return util_fast_log2(rho);
}
-
+/**
+ * Compute lambda for a vertex texture sampler.
+ * Since there aren't derivatives to use, just return 0.
+ */
static float
compute_lambda_vert(const struct sp_sampler_varient *samp,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
- const float p[QUAD_SIZE],
- float lodbias)
+ const float p[QUAD_SIZE])
{
- return lodbias;
+ return 0.0f;
}
/**
* Get a texel from a texture, using the texture tile cache.
*
- * \param face the cube face in 0..5
- * \param level the mipmap level
+ * \param addr the template tex address containing cube, z, face info.
* \param x the x coord of texel within 2D image
* \param y the y coord of texel within 2D image
- * \param z which slice of a 3D texture
* \param rgba the quad to put the texel/color into
- * \param j which element of the rgba quad to write to
*
* XXX maybe move this into sp_tex_tile_cache.c and merge with the
* sp_get_cached_tile_tex() function. Also, get 4 texels instead of 1...
*/
-static INLINE void
-get_texel_quad_2d(const struct tgsi_sampler *tgsi_sampler,
- unsigned face, unsigned level, int x, int y,
- const float *out[4])
-{
- const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
- const struct softpipe_tex_cached_tile *tile
- = sp_get_cached_tile_tex(samp->cache,
- tex_tile_address(x, y, 0, face, level));
+
+
+static INLINE const float *
+get_texel_2d_no_border(const struct sp_sampler_varient *samp,
+ union tex_tile_address addr, int x, int y)
+{
+ const struct softpipe_tex_cached_tile *tile;
+
+ addr.bits.x = x / TILE_SIZE;
+ addr.bits.y = y / TILE_SIZE;
y %= TILE_SIZE;
x %= TILE_SIZE;
-
- out[0] = &tile->data.color[y ][x ][0];
- out[1] = &tile->data.color[y ][x+1][0];
- out[2] = &tile->data.color[y+1][x ][0];
- out[3] = &tile->data.color[y+1][x+1][0];
+
+ tile = sp_get_cached_tile_tex(samp->cache, addr);
+
+ return &tile->data.color[y][x][0];
}
+
static INLINE const float *
-get_texel_2d_ptr(const struct tgsi_sampler *tgsi_sampler,
- unsigned face, unsigned level, int x, int y)
+get_texel_2d(const struct sp_sampler_varient *samp,
+ union tex_tile_address addr, int x, int y)
{
- const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ const struct pipe_texture *texture = samp->texture;
+ unsigned level = addr.bits.level;
+
+ if (x < 0 || x >= (int) u_minify(texture->width0, level) ||
+ y < 0 || y >= (int) u_minify(texture->height0, level)) {
+ return samp->sampler->border_color;
+ }
+ else {
+ return get_texel_2d_no_border( samp, addr, x, y );
+ }
+}
- const struct softpipe_tex_cached_tile *tile
- = sp_get_cached_tile_tex(samp->cache,
- tex_tile_address(x, y, 0, face, level));
+/* Gather a quad of adjacent texels within a tile:
+ */
+static INLINE void
+get_texel_quad_2d_no_border_single_tile(const struct sp_sampler_varient *samp,
+ union tex_tile_address addr,
+ unsigned x, unsigned y,
+ const float *out[4])
+{
+ const struct softpipe_tex_cached_tile *tile;
+
+ addr.bits.x = x / TILE_SIZE;
+ addr.bits.y = y / TILE_SIZE;
y %= TILE_SIZE;
x %= TILE_SIZE;
- return &tile->data.color[y][x][0];
+ tile = sp_get_cached_tile_tex(samp->cache, addr);
+
+ out[0] = &tile->data.color[y ][x ][0];
+ out[1] = &tile->data.color[y ][x+1][0];
+ out[2] = &tile->data.color[y+1][x ][0];
+ out[3] = &tile->data.color[y+1][x+1][0];
}
+/* Gather a quad of potentially non-adjacent texels:
+ */
static INLINE void
-get_texel_quad_2d_mt(const struct tgsi_sampler *tgsi_sampler,
- unsigned face, unsigned level,
- int x0, int y0,
- int x1, int y1,
- const float *out[4])
+get_texel_quad_2d_no_border(const struct sp_sampler_varient *samp,
+ union tex_tile_address addr,
+ int x0, int y0,
+ int x1, int y1,
+ const float *out[4])
{
- unsigned i;
+ out[0] = get_texel_2d_no_border( samp, addr, x0, y0 );
+ out[1] = get_texel_2d_no_border( samp, addr, x1, y0 );
+ out[2] = get_texel_2d_no_border( samp, addr, x0, y1 );
+ out[3] = get_texel_2d_no_border( samp, addr, x1, y1 );
+}
- for (i = 0; i < 4; i++) {
- unsigned tx = (i & 1) ? x1 : x0;
- unsigned ty = (i >> 1) ? y1 : y0;
+/* Can involve a lot of unnecessary checks for border color:
+ */
+static INLINE void
+get_texel_quad_2d(const struct sp_sampler_varient *samp,
+ union tex_tile_address addr,
+ int x0, int y0,
+ int x1, int y1,
+ const float *out[4])
+{
+ out[0] = get_texel_2d( samp, addr, x0, y0 );
+ out[1] = get_texel_2d( samp, addr, x1, y0 );
+ out[3] = get_texel_2d( samp, addr, x1, y1 );
+ out[2] = get_texel_2d( samp, addr, x0, y1 );
+}
- out[i] = get_texel_2d_ptr( tgsi_sampler, face, level, tx, ty );
- }
+
+
+/* 3d varients:
+ */
+static INLINE const float *
+get_texel_3d_no_border(const struct sp_sampler_varient *samp,
+ union tex_tile_address addr, int x, int y, int z)
+{
+ const struct softpipe_tex_cached_tile *tile;
+
+ addr.bits.x = x / TILE_SIZE;
+ addr.bits.y = y / TILE_SIZE;
+ addr.bits.z = z;
+ y %= TILE_SIZE;
+ x %= TILE_SIZE;
+
+ tile = sp_get_cached_tile_tex(samp->cache, addr);
+
+ return &tile->data.color[y][x][0];
}
-static INLINE void
-get_texel(const struct tgsi_sampler *tgsi_sampler,
- unsigned face, unsigned level, int x, int y, int z,
- float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j)
+
+static INLINE const float *
+get_texel_3d(const struct sp_sampler_varient *samp,
+ union tex_tile_address addr, int x, int y, int z)
{
- const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
const struct pipe_texture *texture = samp->texture;
- const struct pipe_sampler_state *sampler = samp->sampler;
+ unsigned level = addr.bits.level;
- if (x < 0 || x >= (int) texture->width[level] ||
- y < 0 || y >= (int) texture->height[level] ||
- z < 0 || z >= (int) texture->depth[level]) {
- rgba[0][j] = sampler->border_color[0];
- rgba[1][j] = sampler->border_color[1];
- rgba[2][j] = sampler->border_color[2];
- rgba[3][j] = sampler->border_color[3];
+ if (x < 0 || x >= (int) u_minify(texture->width0, level) ||
+ y < 0 || y >= (int) u_minify(texture->height0, level) ||
+ z < 0 || z >= (int) u_minify(texture->depth0, level)) {
+ return samp->sampler->border_color;
}
else {
- const unsigned tx = x % TILE_SIZE;
- const unsigned ty = y % TILE_SIZE;
- const struct softpipe_tex_cached_tile *tile;
-
- tile = sp_get_cached_tile_tex(samp->cache,
- tex_tile_address(x, y, z, face, level));
-
- rgba[0][j] = tile->data.color[ty][tx][0];
- rgba[1][j] = tile->data.color[ty][tx][1];
- rgba[2][j] = tile->data.color[ty][tx][2];
- rgba[3][j] = tile->data.color[ty][tx][3];
- if (0)
- {
- debug_printf("Get texel %f %f %f %f from %s\n",
- rgba[0][j], rgba[1][j], rgba[2][j], rgba[3][j],
- pf_name(texture->format));
- }
+ return get_texel_3d_no_border( samp, addr, x, y, z );
}
}
+/**
+ * Given the logbase2 of a mipmap's base level size and a mipmap level,
+ * return the size (in texels) of that mipmap level.
+ * For example, if level[0].width = 256 then base_pot will be 8.
+ * If level = 2, then we'll return 64 (the width at level=2).
+ * Return 1 if level > base_pot.
+ */
+static INLINE unsigned
+pot_level_size(unsigned base_pot, unsigned level)
+{
+ return (base_pot >= level) ? (1 << (base_pot - level)) : 1;
+}
-
+/* Some image-filter fastpaths:
+ */
static INLINE void
img_filter_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_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 float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ const float c0[QUAD_SIZE],
+ enum tgsi_sampler_control control,
+ float rgba[NUM_CHANNELS][QUAD_SIZE])
{
const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
unsigned j;
unsigned level = samp->level;
- unsigned xpot = 1 << (samp->xpot - level);
- unsigned ypot = 1 << (samp->ypot - level);
+ unsigned xpot = pot_level_size(samp->xpot, level);
+ unsigned ypot = pot_level_size(samp->ypot, level);
unsigned xmax = (xpot - 1) & (TILE_SIZE - 1); /* MIN2(TILE_SIZE, xpot) - 1; */
unsigned ymax = (ypot - 1) & (TILE_SIZE - 1); /* MIN2(TILE_SIZE, ypot) - 1; */
-
+ union tex_tile_address addr;
+
+ addr.value = 0;
+ addr.bits.level = samp->level;
+
for (j = 0; j < QUAD_SIZE; j++) {
int c;
int x0 = uflr & (xpot - 1);
int y0 = vflr & (ypot - 1);
- const float *tx[4];
+ const float *tx[4];
-
/* Can we fetch all four at once:
*/
- if (x0 < xmax && y0 < ymax)
- {
- get_texel_quad_2d(tgsi_sampler, 0, level, x0, y0, tx);
+ if (x0 < xmax && y0 < ymax) {
+ get_texel_quad_2d_no_border_single_tile(samp, addr, x0, y0, tx);
}
- else
- {
+ else {
unsigned x1 = (x0 + 1) & (xpot - 1);
unsigned y1 = (y0 + 1) & (ypot - 1);
- get_texel_quad_2d_mt(tgsi_sampler, 0, level,
- x0, y0, x1, y1, tx);
+ get_texel_quad_2d_no_border(samp, addr, x0, y0, x1, y1, tx);
}
-
/* interpolate R, G, B, A */
for (c = 0; c < 4; c++) {
rgba[c][j] = lerp_2d(xw, yw,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float c0[QUAD_SIZE],
+ enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
unsigned j;
unsigned level = samp->level;
- unsigned xpot = 1 << (samp->xpot - level);
- unsigned ypot = 1 << (samp->ypot - level);
+ unsigned xpot = pot_level_size(samp->xpot, level);
+ unsigned ypot = pot_level_size(samp->ypot, level);
+ union tex_tile_address addr;
+
+ addr.value = 0;
+ addr.bits.level = samp->level;
for (j = 0; j < QUAD_SIZE; j++) {
int c;
int x0 = uflr & (xpot - 1);
int y0 = vflr & (ypot - 1);
- const float *out = get_texel_2d_ptr(tgsi_sampler, 0, level, x0, y0);
+ const float *out = get_texel_2d_no_border(samp, addr, x0, y0);
for (c = 0; c < 4; c++) {
rgba[c][j] = out[c];
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float c0[QUAD_SIZE],
+ enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
unsigned j;
unsigned level = samp->level;
- unsigned xpot = 1 << (samp->xpot - level);
- unsigned ypot = 1 << (samp->ypot - level);
+ unsigned xpot = pot_level_size(samp->xpot, level);
+ unsigned ypot = pot_level_size(samp->ypot, level);
+ union tex_tile_address addr;
+
+ addr.value = 0;
+ addr.bits.level = samp->level;
for (j = 0; j < QUAD_SIZE; j++) {
int c;
else if (y0 > ypot - 1)
y0 = ypot - 1;
- out = get_texel_2d_ptr(tgsi_sampler, 0, level, x0, y0);
+ out = get_texel_2d_no_border(samp, addr, x0, y0);
for (c = 0; c < 4; c++) {
rgba[c][j] = out[c];
}
}
+
static void
img_filter_1d_nearest(struct tgsi_sampler *tgsi_sampler,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float c0[QUAD_SIZE],
+ enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
unsigned level0, j;
int width;
int x[4];
+ union tex_tile_address addr;
level0 = samp->level;
- width = texture->width[level0];
+ width = u_minify(texture->width0, level0);
assert(width > 0);
+ addr.value = 0;
+ addr.bits.level = samp->level;
+
samp->nearest_texcoord_s(s, width, x);
for (j = 0; j < QUAD_SIZE; j++) {
- get_texel(tgsi_sampler, 0, level0, x[j], 0, 0, rgba, j);
+ const float *out = get_texel_2d(samp, addr, x[j], 0);
+ int c;
+ for (c = 0; c < 4; c++) {
+ rgba[c][j] = out[c];
+ }
}
}
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float c0[QUAD_SIZE],
+ enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
+{
+ const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ const struct pipe_texture *texture = samp->texture;
+ unsigned level0, j;
+ int width, height;
+ int x[4], y[4];
+ union tex_tile_address addr;
+
+
+ level0 = samp->level;
+ width = u_minify(texture->width0, level0);
+ height = u_minify(texture->height0, level0);
+
+ assert(width > 0);
+ assert(height > 0);
+
+ addr.value = 0;
+ addr.bits.level = samp->level;
+
+ samp->nearest_texcoord_s(s, width, x);
+ samp->nearest_texcoord_t(t, height, y);
+
+ for (j = 0; j < QUAD_SIZE; j++) {
+ const float *out = get_texel_2d(samp, addr, x[j], y[j]);
+ int c;
+ for (c = 0; c < 4; c++) {
+ rgba[c][j] = out[c];
+ }
+ }
+}
+
+
+static INLINE union tex_tile_address
+face(union tex_tile_address addr, unsigned face )
+{
+ addr.bits.face = face;
+ return addr;
+}
+
+
+static void
+img_filter_cube_nearest(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ const float c0[QUAD_SIZE],
+ enum tgsi_sampler_control control,
+ float rgba[NUM_CHANNELS][QUAD_SIZE])
{
const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
const struct pipe_texture *texture = samp->texture;
unsigned level0, j;
int width, height;
int x[4], y[4];
+ union tex_tile_address addr;
level0 = samp->level;
- width = texture->width[level0];
- height = texture->height[level0];
+ width = u_minify(texture->width0, level0);
+ height = u_minify(texture->height0, level0);
assert(width > 0);
+ assert(height > 0);
+
+ addr.value = 0;
+ addr.bits.level = samp->level;
samp->nearest_texcoord_s(s, width, x);
samp->nearest_texcoord_t(t, height, y);
for (j = 0; j < QUAD_SIZE; j++) {
- get_texel(tgsi_sampler, faces[j], level0, x[j], y[j], 0, rgba, j);
+ const float *out = get_texel_2d(samp, face(addr, faces[j]), x[j], y[j]);
+ int c;
+ for (c = 0; c < 4; c++) {
+ rgba[c][j] = out[c];
+ }
}
}
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float c0[QUAD_SIZE],
+ enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
unsigned level0, j;
int width, height, depth;
int x[4], y[4], z[4];
+ union tex_tile_address addr;
level0 = samp->level;
- width = texture->width[level0];
- height = texture->height[level0];
- depth = texture->depth[level0];
+ width = u_minify(texture->width0, level0);
+ height = u_minify(texture->height0, level0);
+ depth = u_minify(texture->depth0, level0);
assert(width > 0);
assert(height > 0);
samp->nearest_texcoord_t(t, height, y);
samp->nearest_texcoord_p(p, depth, z);
+ addr.value = 0;
+ addr.bits.level = samp->level;
+
for (j = 0; j < QUAD_SIZE; j++) {
- get_texel(tgsi_sampler, 0, level0, x[j], y[j], z[j], rgba, j);
+ const float *out = get_texel_3d(samp, addr, x[j], y[j], z[j]);
+ int c;
+ for (c = 0; c < 4; c++) {
+ rgba[c][j] = out[c];
+ }
}
}
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float c0[QUAD_SIZE],
+ enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
int width;
int x0[4], x1[4];
float xw[4]; /* weights */
-
+ union tex_tile_address addr;
level0 = samp->level;
- width = texture->width[level0];
+ width = u_minify(texture->width0, level0);
assert(width > 0);
- samp->linear_texcoord_s(s, width, x0, x1, xw);
+ addr.value = 0;
+ addr.bits.level = samp->level;
+ samp->linear_texcoord_s(s, width, x0, x1, xw);
for (j = 0; j < QUAD_SIZE; j++) {
- float tx[4][4]; /* texels */
+ const float *tx0 = get_texel_2d(samp, addr, x0[j], 0);
+ const float *tx1 = get_texel_2d(samp, addr, x1[j], 0);
int c;
- get_texel(tgsi_sampler, 0, level0, x0[j], 0, 0, tx, 0);
- get_texel(tgsi_sampler, 0, level0, x1[j], 0, 0, tx, 1);
/* interpolate R, G, B, A */
for (c = 0; c < 4; c++) {
- rgba[c][j] = lerp(xw[j], tx[c][0], tx[c][1]);
+ rgba[c][j] = lerp(xw[j], tx0[c], tx1[c]);
}
}
}
+
static void
img_filter_2d_linear(struct tgsi_sampler *tgsi_sampler,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float c0[QUAD_SIZE],
+ enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
const struct pipe_texture *texture = samp->texture;
- const unsigned *faces = samp->faces; /* zero when not cube-mapping */
unsigned level0, j;
int width, height;
int x0[4], y0[4], x1[4], y1[4];
float xw[4], yw[4]; /* weights */
+ union tex_tile_address addr;
+ level0 = samp->level;
+ width = u_minify(texture->width0, level0);
+ height = u_minify(texture->height0, level0);
+
+ assert(width > 0);
+ assert(height > 0);
+
+ addr.value = 0;
+ addr.bits.level = samp->level;
+
+ samp->linear_texcoord_s(s, width, x0, x1, xw);
+ samp->linear_texcoord_t(t, height, y0, y1, yw);
+
+ for (j = 0; j < QUAD_SIZE; j++) {
+ const float *tx0 = get_texel_2d(samp, addr, x0[j], y0[j]);
+ const float *tx1 = get_texel_2d(samp, addr, x1[j], y0[j]);
+ const float *tx2 = get_texel_2d(samp, addr, x0[j], y1[j]);
+ const float *tx3 = get_texel_2d(samp, addr, x1[j], y1[j]);
+ int c;
+
+ /* interpolate R, G, B, A */
+ for (c = 0; c < 4; c++) {
+ rgba[c][j] = lerp_2d(xw[j], yw[j],
+ tx0[c], tx1[c],
+ tx2[c], tx3[c]);
+ }
+ }
+}
+
+
+static void
+img_filter_cube_linear(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ const float c0[QUAD_SIZE],
+ enum tgsi_sampler_control control,
+ float rgba[NUM_CHANNELS][QUAD_SIZE])
+{
+ const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ const struct pipe_texture *texture = samp->texture;
+ const unsigned *faces = samp->faces; /* zero when not cube-mapping */
+ unsigned level0, j;
+ int width, height;
+ int x0[4], y0[4], x1[4], y1[4];
+ float xw[4], yw[4]; /* weights */
+ union tex_tile_address addr;
level0 = samp->level;
- width = texture->width[level0];
- height = texture->height[level0];
+ width = u_minify(texture->width0, level0);
+ height = u_minify(texture->height0, level0);
assert(width > 0);
+ assert(height > 0);
+
+ addr.value = 0;
+ addr.bits.level = samp->level;
samp->linear_texcoord_s(s, width, x0, x1, xw);
samp->linear_texcoord_t(t, height, y0, y1, yw);
for (j = 0; j < QUAD_SIZE; j++) {
- float tx[4][4]; /* texels */
+ union tex_tile_address addrj = face(addr, faces[j]);
+ const float *tx0 = get_texel_2d(samp, addrj, x0[j], y0[j]);
+ const float *tx1 = get_texel_2d(samp, addrj, x1[j], y0[j]);
+ const float *tx2 = get_texel_2d(samp, addrj, x0[j], y1[j]);
+ const float *tx3 = get_texel_2d(samp, addrj, x1[j], y1[j]);
int c;
- get_texel(tgsi_sampler, faces[j], level0, x0[j], y0[j], 0, tx, 0);
- get_texel(tgsi_sampler, faces[j], level0, x1[j], y0[j], 0, tx, 1);
- get_texel(tgsi_sampler, faces[j], level0, x0[j], y1[j], 0, tx, 2);
- get_texel(tgsi_sampler, faces[j], level0, x1[j], y1[j], 0, tx, 3);
/* interpolate R, G, B, A */
for (c = 0; c < 4; c++) {
rgba[c][j] = lerp_2d(xw[j], yw[j],
- tx[c][0], tx[c][1],
- tx[c][2], tx[c][3]);
+ tx0[c], tx1[c],
+ tx2[c], tx3[c]);
}
}
}
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float c0[QUAD_SIZE],
+ enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
int width, height, depth;
int x0[4], x1[4], y0[4], y1[4], z0[4], z1[4];
float xw[4], yw[4], zw[4]; /* interpolation weights */
+ union tex_tile_address addr;
level0 = samp->level;
- width = texture->width[level0];
- height = texture->height[level0];
- depth = texture->depth[level0];
+ width = u_minify(texture->width0, level0);
+ height = u_minify(texture->height0, level0);
+ depth = u_minify(texture->depth0, level0);
+
+ addr.value = 0;
+ addr.bits.level = level0;
assert(width > 0);
assert(height > 0);
samp->linear_texcoord_p(p, depth, z0, z1, zw);
for (j = 0; j < QUAD_SIZE; j++) {
- float tx0[4][4], tx1[4][4];
int c;
-
- get_texel(tgsi_sampler, 0, level0, x0[j], y0[j], z0[j], tx0, 0);
- get_texel(tgsi_sampler, 0, level0, x1[j], y0[j], z0[j], tx0, 1);
- get_texel(tgsi_sampler, 0, level0, x0[j], y1[j], z0[j], tx0, 2);
- get_texel(tgsi_sampler, 0, level0, x1[j], y1[j], z0[j], tx0, 3);
- get_texel(tgsi_sampler, 0, level0, x0[j], y0[j], z1[j], tx1, 0);
- get_texel(tgsi_sampler, 0, level0, x1[j], y0[j], z1[j], tx1, 1);
- get_texel(tgsi_sampler, 0, level0, x0[j], y1[j], z1[j], tx1, 2);
- get_texel(tgsi_sampler, 0, level0, x1[j], y1[j], z1[j], tx1, 3);
+ const float *tx00 = get_texel_3d(samp, addr, x0[j], y0[j], z0[j]);
+ const float *tx01 = get_texel_3d(samp, addr, x1[j], y0[j], z0[j]);
+ const float *tx02 = get_texel_3d(samp, addr, x0[j], y1[j], z0[j]);
+ const float *tx03 = get_texel_3d(samp, addr, x1[j], y1[j], z0[j]);
+
+ const float *tx10 = get_texel_3d(samp, addr, x0[j], y0[j], z1[j]);
+ const float *tx11 = get_texel_3d(samp, addr, x1[j], y0[j], z1[j]);
+ const float *tx12 = get_texel_3d(samp, addr, x0[j], y1[j], z1[j]);
+ const float *tx13 = get_texel_3d(samp, addr, x1[j], y1[j], z1[j]);
+
/* interpolate R, G, B, A */
for (c = 0; c < 4; c++) {
rgba[c][j] = lerp_3d(xw[j], yw[j], zw[j],
- tx0[c][0], tx0[c][1],
- tx0[c][2], tx0[c][3],
- tx1[c][0], tx1[c][1],
- tx1[c][2], tx1[c][3]);
+ tx00[c], tx01[c],
+ tx02[c], tx03[c],
+ tx10[c], tx11[c],
+ tx12[c], tx13[c]);
}
}
}
+/* Calculate level of detail for every fragment.
+ * Note that lambda has already been biased by global LOD bias.
+ */
+static INLINE void
+compute_lod(const struct pipe_sampler_state *sampler,
+ const float biased_lambda,
+ const float lodbias[QUAD_SIZE],
+ float lod[QUAD_SIZE])
+{
+ uint i;
-
-
+ for (i = 0; i < QUAD_SIZE; i++) {
+ lod[i] = biased_lambda + lodbias[i];
+ lod[i] = CLAMP(lod[i], sampler->min_lod, sampler->max_lod);
+ }
+}
static void
mip_filter_linear(struct tgsi_sampler *tgsi_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 float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ const float c0[QUAD_SIZE],
+ enum tgsi_sampler_control control,
+ float rgba[NUM_CHANNELS][QUAD_SIZE])
{
struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
const struct pipe_texture *texture = samp->texture;
int level0;
float lambda;
+ float lod[QUAD_SIZE];
- lambda = samp->compute_lambda(samp, s, t, p, lodbias);
+ if (control == tgsi_sampler_lod_bias) {
+ lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias;
+ compute_lod(samp->sampler, lambda, c0, lod);
+ } else {
+ assert(control == tgsi_sampler_lod_explicit);
+
+ memcpy(lod, c0, sizeof(lod));
+ }
+
+ /* XXX: Take into account all lod values.
+ */
+ lambda = lod[0];
level0 = (int)lambda;
if (lambda < 0.0) {
samp->level = 0;
- samp->mag_img_filter( tgsi_sampler, s, t, p, 0, rgba );
+ samp->mag_img_filter(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba);
}
else if (level0 >= texture->last_level) {
samp->level = texture->last_level;
- samp->min_img_filter( tgsi_sampler, s, t, p, 0, rgba );
+ samp->min_img_filter(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba);
}
else {
float levelBlend = lambda - level0;
int c,j;
samp->level = level0;
- samp->min_img_filter( tgsi_sampler, s, t, p, 0, rgba0 );
+ samp->min_img_filter(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba0);
samp->level = level0+1;
- samp->min_img_filter( tgsi_sampler, s, t, p, 0, rgba1 );
+ samp->min_img_filter(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba1);
for (j = 0; j < QUAD_SIZE; j++) {
for (c = 0; c < 4; c++) {
}
-
static void
mip_filter_nearest(struct tgsi_sampler *tgsi_sampler,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float c0[QUAD_SIZE],
+ enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
const struct pipe_texture *texture = samp->texture;
float lambda;
+ float lod[QUAD_SIZE];
+
+ if (control == tgsi_sampler_lod_bias) {
+ lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias;
+ compute_lod(samp->sampler, lambda, c0, lod);
+ } else {
+ assert(control == tgsi_sampler_lod_explicit);
+
+ memcpy(lod, c0, sizeof(lod));
+ }
- lambda = samp->compute_lambda(samp, s, t, p, lodbias);
+ /* XXX: Take into account all lod values.
+ */
+ lambda = lod[0];
if (lambda < 0.0) {
samp->level = 0;
- samp->mag_img_filter( tgsi_sampler, s, t, p, 0, rgba );
+ samp->mag_img_filter(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba);
}
else {
samp->level = (int)(lambda + 0.5) ;
samp->level = MIN2(samp->level, (int)texture->last_level);
- samp->min_img_filter( tgsi_sampler, s, t, p, 0, rgba );
+ samp->min_img_filter(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba);
}
+
+#if 0
+ printf("RGBA %g %g %g %g, %g %g %g %g, %g %g %g %g, %g %g %g %g\n",
+ rgba[0][0], rgba[1][0], rgba[2][0], rgba[3][0],
+ rgba[0][1], rgba[1][1], rgba[2][1], rgba[3][1],
+ rgba[0][2], rgba[1][2], rgba[2][2], rgba[3][2],
+ rgba[0][3], rgba[1][3], rgba[2][3], rgba[3][3]);
+#endif
}
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float c0[QUAD_SIZE],
+ enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
- float lambda = samp->compute_lambda(samp, s, t, p, lodbias);
+ float lambda;
+ float lod[QUAD_SIZE];
+
+ if (control == tgsi_sampler_lod_bias) {
+ lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias;
+ compute_lod(samp->sampler, lambda, c0, lod);
+ } else {
+ assert(control == tgsi_sampler_lod_explicit);
+
+ memcpy(lod, c0, sizeof(lod));
+ }
+
+ /* XXX: Take into account all lod values.
+ */
+ lambda = lod[0];
if (lambda < 0.0) {
- samp->mag_img_filter( tgsi_sampler, s, t, p, 0, rgba );
+ samp->mag_img_filter(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba);
}
else {
- samp->min_img_filter( tgsi_sampler, s, t, p, 0, rgba );
+ samp->min_img_filter(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba);
}
}
-/* Specialized version of mip_filter_linear with hard-wired calls to
+/**
+ * Specialized version of mip_filter_linear with hard-wired calls to
* 2d lambda calculation and 2d_linear_repeat_POT img filters.
*/
static void
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float c0[QUAD_SIZE],
+ enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
const struct pipe_texture *texture = samp->texture;
int level0;
float lambda;
+ float lod[QUAD_SIZE];
+
+ if (control == tgsi_sampler_lod_bias) {
+ lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias;
+ compute_lod(samp->sampler, lambda, c0, lod);
+ } else {
+ assert(control == tgsi_sampler_lod_explicit);
+
+ memcpy(lod, c0, sizeof(lod));
+ }
- lambda = compute_lambda_2d(samp, s, t, p, lodbias);
+ /* XXX: Take into account all lod values.
+ */
+ lambda = lod[0];
level0 = (int)lambda;
/* Catches both negative and large values of level0:
else
samp->level = texture->last_level;
- img_filter_2d_linear_repeat_POT( tgsi_sampler, s, t, p, 0, rgba );
+ img_filter_2d_linear_repeat_POT(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba);
}
else {
float levelBlend = lambda - level0;
int c,j;
samp->level = level0;
- img_filter_2d_linear_repeat_POT( tgsi_sampler, s, t, p, 0, rgba0 );
+ img_filter_2d_linear_repeat_POT(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba0);
samp->level = level0+1;
- img_filter_2d_linear_repeat_POT( tgsi_sampler, s, t, p, 0, rgba1 );
+ img_filter_2d_linear_repeat_POT(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba1);
for (j = 0; j < QUAD_SIZE; j++) {
for (c = 0; c < 4; c++) {
-/* Compare stage in the little sampling pipeline.
+/**
+ * Do shadow/depth comparisons.
*/
static void
sample_compare(struct tgsi_sampler *tgsi_sampler,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float c0[QUAD_SIZE],
+ enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
int j, k0, k1, k2, k3;
float val;
- samp->mip_filter( tgsi_sampler, s, t, p, lodbias, rgba );
-
+ samp->mip_filter(tgsi_sampler, s, t, p, c0, control, rgba);
/**
* Compare texcoord 'p' (aka R) against texture value 'rgba[0]'
}
}
-/* Calculate cube faces.
+
+/**
+ * Compute which cube face is referenced by each texcoord and put that
+ * info into the sampler faces[] array. Then sample the cube faces
*/
static void
sample_cube(struct tgsi_sampler *tgsi_sampler,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float c0[QUAD_SIZE],
+ enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
unsigned face;
float sc, tc, ma;
- if (arx > ary && arx > arz) {
+ if (arx >= ary && arx >= arz) {
if (rx >= 0.0F) {
face = PIPE_TEX_FACE_POS_X;
sc = -rz;
ma = arx;
}
}
- else if (ary > arx && ary > arz) {
+ else if (ary >= arx && ary >= arz) {
if (ry >= 0.0F) {
face = PIPE_TEX_FACE_POS_Y;
sc = rx;
}
}
- ssss[j] = ( sc / ma + 1.0F ) * 0.5F;
- tttt[j] = ( tc / ma + 1.0F ) * 0.5F;
- samp->faces[j] = face;
+ {
+ const float ima = 1.0 / ma;
+ ssss[j] = ( sc * ima + 1.0F ) * 0.5F;
+ tttt[j] = ( tc * ima + 1.0F ) * 0.5F;
+ samp->faces[j] = face;
+ }
}
/* In our little pipeline, the compare stage is next. If compare
* is not active, this will point somewhere deeper into the
* pipeline, eg. to mip_filter or even img_filter.
*/
- samp->compare(tgsi_sampler, ssss, tttt, NULL, lodbias, rgba);
+ samp->compare(tgsi_sampler, ssss, tttt, NULL, c0, control, rgba);
}
-
-static wrap_nearest_func get_nearest_unorm_wrap( unsigned mode )
+static wrap_nearest_func
+get_nearest_unorm_wrap(unsigned mode)
{
switch (mode) {
case PIPE_TEX_WRAP_CLAMP:
}
-static wrap_nearest_func get_nearest_wrap( unsigned mode )
+static wrap_nearest_func
+get_nearest_wrap(unsigned mode)
{
switch (mode) {
case PIPE_TEX_WRAP_REPEAT:
}
}
-static wrap_linear_func get_linear_unorm_wrap( unsigned mode )
+
+static wrap_linear_func
+get_linear_unorm_wrap(unsigned mode)
{
switch (mode) {
case PIPE_TEX_WRAP_CLAMP:
}
}
-static wrap_linear_func get_linear_wrap( unsigned mode )
+
+static wrap_linear_func
+get_linear_wrap(unsigned mode)
{
switch (mode) {
case PIPE_TEX_WRAP_REPEAT:
}
}
-static compute_lambda_func get_lambda_func( const union sp_sampler_key key )
+
+static compute_lambda_func
+get_lambda_func(const union sp_sampler_key key)
{
if (key.bits.processor == TGSI_PROCESSOR_VERTEX)
return compute_lambda_vert;
}
}
-static filter_func get_img_filter( const union sp_sampler_key key,
- unsigned filter,
- const struct pipe_sampler_state *sampler )
+
+static filter_func
+get_img_filter(const union sp_sampler_key key,
+ unsigned filter,
+ const struct pipe_sampler_state *sampler)
{
switch (key.bits.target) {
case PIPE_TEXTURE_1D:
}
}
}
- /* Fallthrough to default versions:
+ /* Otherwise use default versions:
*/
- case PIPE_TEXTURE_CUBE:
if (filter == PIPE_TEX_FILTER_NEAREST)
return img_filter_2d_nearest;
else
return img_filter_2d_linear;
break;
+ case PIPE_TEXTURE_CUBE:
+ if (filter == PIPE_TEX_FILTER_NEAREST)
+ return img_filter_cube_nearest;
+ else
+ return img_filter_cube_linear;
+ break;
case PIPE_TEXTURE_3D:
if (filter == PIPE_TEX_FILTER_NEAREST)
return img_filter_3d_nearest;
samp->texture = texture;
samp->cache = tex_cache;
- samp->xpot = util_unsigned_logbase2( texture->width[0] );
- samp->ypot = util_unsigned_logbase2( texture->height[0] );
+ samp->xpot = util_unsigned_logbase2( texture->width0 );
+ samp->ypot = util_unsigned_logbase2( texture->height0 );
samp->level = CLAMP((int) sampler->min_lod, 0, (int) texture->last_level);
}
}
-/* Create a sampler varient for a given set of non-orthogonal state. Currently the
+/**
+ * Create a sampler varient for a given set of non-orthogonal state.
*/
struct sp_sampler_varient *
sp_create_sampler_varient( const struct pipe_sampler_state *sampler,
break;
}
- if (sampler->compare_mode != FALSE) {
+ if (sampler->compare_mode != PIPE_TEX_COMPARE_NONE) {
samp->compare = sample_compare;
}
else {
return samp;
}
-
-
-
-
-
-