const union tgsi_exec_channel *s,
const union tgsi_exec_channel *t,
const union tgsi_exec_channel *p,
- float lodbias, /* XXX should be float[4] */
+ const union tgsi_exec_channel *lodbias,
union tgsi_exec_channel *r,
union tgsi_exec_channel *g,
union tgsi_exec_channel *b,
uint j;
float rgba[NUM_CHANNELS][QUAD_SIZE];
- sampler->get_samples(sampler, s->f, t->f, p->f, lodbias, rgba);
+ sampler->get_samples(sampler, s->f, t->f, p->f, lodbias->f, rgba);
for (j = 0; j < 4; j++) {
r->f[j] = rgba[0][j];
{
const uint unit = inst->Src[1].Register.Index;
union tgsi_exec_channel r[4];
+ const union tgsi_exec_channel *lodBias = &ZeroVec;
uint chan_index;
- float lodBias = 0.0f;
+
+ if (modifier != TEX_MODIFIER_NONE) {
+ FETCH(&r[3], 0, CHAN_W);
+ if (modifier != TEX_MODIFIER_PROJECTED) {
+ lodBias = &r[3];
+ }
+ }
switch (inst->Texture.Texture) {
case TGSI_TEXTURE_1D:
case TGSI_TEXTURE_SHADOW1D:
FETCH(&r[0], 0, CHAN_X);
- if (modifier != TEX_MODIFIER_NONE) {
- FETCH(&r[1], 0, CHAN_W);
- if (modifier == TEX_MODIFIER_PROJECTED) {
- micro_div(&r[0], &r[0], &r[1]);
- } else {
- lodBias = r[1].f[0];
- }
+ if (modifier == TEX_MODIFIER_PROJECTED) {
+ micro_div(&r[0], &r[0], &r[3]);
}
fetch_texel(mach->Samplers[unit],
FETCH(&r[1], 0, CHAN_Y);
FETCH(&r[2], 0, CHAN_Z);
- if (modifier != TEX_MODIFIER_NONE) {
- FETCH(&r[3], 0, CHAN_W);
- if (modifier == TEX_MODIFIER_PROJECTED) {
- micro_div(&r[0], &r[0], &r[3]);
- micro_div(&r[1], &r[1], &r[3]);
- micro_div(&r[2], &r[2], &r[3]);
- } else {
- lodBias = r[3].f[0];
- }
+ if (modifier == TEX_MODIFIER_PROJECTED) {
+ micro_div(&r[0], &r[0], &r[3]);
+ micro_div(&r[1], &r[1], &r[3]);
+ micro_div(&r[2], &r[2], &r[3]);
}
fetch_texel(mach->Samplers[unit],
FETCH(&r[1], 0, CHAN_Y);
FETCH(&r[2], 0, CHAN_Z);
- if (modifier != TEX_MODIFIER_NONE) {
- FETCH(&r[3], 0, CHAN_W);
- if (modifier == TEX_MODIFIER_PROJECTED) {
- micro_div(&r[0], &r[0], &r[3]);
- micro_div(&r[1], &r[1], &r[3]);
- micro_div(&r[2], &r[2], &r[3]);
- } else {
- lodBias = r[3].f[0];
- }
+ if (modifier == TEX_MODIFIER_PROJECTED) {
+ micro_div(&r[0], &r[0], &r[3]);
+ micro_div(&r[1], &r[1], &r[3]);
+ micro_div(&r[2], &r[2], &r[3]);
}
fetch_texel(mach->Samplers[unit],
FETCH(&r[0], 0, CHAN_X);
fetch_texel(mach->Samplers[unit],
- &r[0], &ZeroVec, &ZeroVec, 0.0f, /* S, T, P, BIAS */
- &r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */
+ &r[0], &ZeroVec, &ZeroVec, &ZeroVec, /* S, T, P, BIAS */
+ &r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */
break;
case TGSI_TEXTURE_2D:
FETCH(&r[2], 0, CHAN_Z);
fetch_texel(mach->Samplers[unit],
- &r[0], &r[1], &r[2], 0.0f, /* inputs */
- &r[0], &r[1], &r[2], &r[3]); /* outputs */
+ &r[0], &r[1], &r[2], &ZeroVec, /* inputs */
+ &r[0], &r[1], &r[2], &r[3]); /* outputs */
break;
case TGSI_TEXTURE_3D:
FETCH(&r[2], 0, CHAN_Z);
fetch_texel(mach->Samplers[unit],
- &r[0], &r[1], &r[2], 0.0f,
+ &r[0], &r[1], &r[2], &ZeroVec,
&r[0], &r[1], &r[2], &r[3]);
break;
*
* 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
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->width0;
- 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_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 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 maxx = MAX2(dsdx, dsdy) * texture->width0;
float maxy = MAX2(dtdx, dtdy) * texture->height0;
float maxz = MAX2(dpdx, dpdy) * texture->depth0;
- float rho, lambda;
+ 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 the LOD bias.
+ * 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;
}
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float lodbias[QUAD_SIZE],
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float lodbias[QUAD_SIZE],
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float lodbias[QUAD_SIZE],
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float lodbias[QUAD_SIZE],
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float lodbias[QUAD_SIZE],
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float lodbias[QUAD_SIZE],
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float lodbias[QUAD_SIZE],
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float lodbias[QUAD_SIZE],
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float lodbias[QUAD_SIZE],
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float lodbias[QUAD_SIZE],
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float lodbias[QUAD_SIZE],
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
}
+/* 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,
+ const float lodbias[QUAD_SIZE],
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);
+ lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias;
+
+ compute_lod(samp->sampler, lambda, lodbias, 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, 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, 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, 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, rgba1 );
for (j = 0; j < QUAD_SIZE; j++) {
for (c = 0; c < 4; c++) {
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float lodbias[QUAD_SIZE],
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];
- lambda = samp->compute_lambda(samp, s, t, p, lodbias);
+ lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias;
+
+ compute_lod(samp->sampler, lambda, lodbias, lod);
+
+ /* XXX: Take into account all lod values.
+ */
+ lambda = lod[0];
if (lambda < 0.0) {
samp->level = 0;
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, rgba );
}
#if 0
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float lodbias[QUAD_SIZE],
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];
+
+ lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias;
+
+ compute_lod(samp->sampler, lambda, lodbias, 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, rgba );
}
else {
- samp->min_img_filter( tgsi_sampler, s, t, p, 0, rgba );
+ samp->min_img_filter( tgsi_sampler, s, t, p, NULL, rgba );
}
}
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float lodbias[QUAD_SIZE],
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 = compute_lambda_2d(samp, s, t, p) + samp->sampler->lod_bias;
- lambda = compute_lambda_2d(samp, s, t, p, lodbias);
+ compute_lod(samp->sampler, lambda, lodbias, lod);
+
+ /* 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, 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, 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, rgba1 );
for (j = 0; j < QUAD_SIZE; j++) {
for (c = 0; c < 4; c++) {
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float lodbias[QUAD_SIZE],
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float lodbias[QUAD_SIZE],
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);