uint j;
float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
+ /* FIXME: handle explicit derivs, offsets */
sampler->get_samples(sampler, s->f, t->f, p->f, c0->f, c1->f, control, rgba);
for (j = 0; j < 4; j++) {
const uint unit = inst->Src[sampler].Register.Index;
union tgsi_exec_channel r[4], cubearraycomp, cubelod;
const union tgsi_exec_channel *lod = &ZeroVec;
- enum tgsi_sampler_control control;
+ enum tgsi_sampler_control control = tgsi_sampler_lod_none;
uint chan;
+ assert(modifier != TEX_MODIFIER_LEVEL_ZERO);
+
if (modifier != TEX_MODIFIER_NONE && (sampler == 1)) {
FETCH(&r[3], 0, TGSI_CHAN_W);
if (modifier != TEX_MODIFIER_PROJECTED) {
if (modifier == TEX_MODIFIER_EXPLICIT_LOD) {
control = tgsi_sampler_lod_explicit;
- } else {
+ } else if (modifier == TEX_MODIFIER_LOD_BIAS){
control = tgsi_sampler_lod_bias;
}
}
fetch_texel(mach->Samplers[unit],
- &r[0], &ZeroVec, &ZeroVec, lod, &ZeroVec, /* S, T, P, LOD */
+ &r[0], &ZeroVec, &ZeroVec, &ZeroVec, lod, /* S, T, P, C, LOD */
control,
&r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */
break;
}
fetch_texel(mach->Samplers[unit],
- &r[0], &ZeroVec, &r[2], lod, &ZeroVec, /* S, T, P, LOD */
+ &r[0], &ZeroVec, &r[2], &ZeroVec, lod, /* S, T, P, C, LOD */
control,
&r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */
break;
}
fetch_texel(mach->Samplers[unit],
- &r[0], &r[1], &r[2], lod, &ZeroVec, /* S, T, P, LOD */
+ &r[0], &r[1], &r[2], &ZeroVec, lod, /* S, T, P, C, LOD */
control,
&r[0], &r[1], &r[2], &r[3]); /* outputs */
break;
}
fetch_texel(mach->Samplers[unit],
- &r[0], &r[1], &ZeroVec, lod, &ZeroVec, /* S, T, P, LOD */
+ &r[0], &r[1], &ZeroVec, &ZeroVec, lod, /* S, T, P, C, LOD */
control,
&r[0], &r[1], &r[2], &r[3]); /* outputs */
break;
}
fetch_texel(mach->Samplers[unit],
- &r[0], &r[1], &r[2], lod, &ZeroVec, /* S, T, P, LOD */
+ &r[0], &r[1], &r[2], &ZeroVec, lod, /* S, T, P, C, LOD */
control,
&r[0], &r[1], &r[2], &r[3]); /* outputs */
break;
}
fetch_texel(mach->Samplers[unit],
- &r[0], &r[1], &r[2], lod, &ZeroVec, /* S, T, P, LOD */
+ &r[0], &r[1], &r[2], &ZeroVec, lod, /* S, T, P, C, LOD */
control,
&r[0], &r[1], &r[2], &r[3]); /* outputs */
break;
FETCH(&r[3], 0, TGSI_CHAN_W);
fetch_texel(mach->Samplers[unit],
- &r[0], &r[1], &r[2], &r[3], &ZeroVec, /* S, T, P, LOD */
+ &r[0], &r[1], &r[2], &r[3], &ZeroVec, /* S, T, P, C, LOD */
control,
&r[0], &r[1], &r[2], &r[3]); /* outputs */
break;
cubelod = ZeroVec;
fetch_texel(mach->Samplers[unit],
- &r[0], &r[1], &r[2], &r[3], &cubelod, /* S, T, P, LOD */
+ &r[0], &r[1], &r[2], &r[3], &cubelod, /* S, T, P, C, LOD */
control,
&r[0], &r[1], &r[2], &r[3]); /* outputs */
break;
}
fetch_texel(mach->Samplers[unit],
- &r[0], &r[1], &r[2], lod, &ZeroVec,
+ &r[0], &r[1], &r[2], &ZeroVec, lod,
control,
&r[0], &r[1], &r[2], &r[3]);
break;
FETCH(&cubearraycomp, 1, TGSI_CHAN_X);
fetch_texel(mach->Samplers[unit],
- &r[0], &r[1], &r[2], &r[3], &cubearraycomp, /* S, T, P, LOD */
+ &r[0], &r[1], &r[2], &r[3], &cubearraycomp, /* S, T, P, C, LOD */
control,
&r[0], &r[1], &r[2], &r[3]); /* outputs */
break;
FETCH(&r[0], 0, TGSI_CHAN_X);
fetch_texel(mach->Samplers[unit],
- &r[0], &ZeroVec, &ZeroVec, &ZeroVec, &ZeroVec, /* S, T, P, BIAS */
- tgsi_sampler_lod_bias,
+ &r[0], &ZeroVec, &ZeroVec, &ZeroVec, &ZeroVec, /* S, T, P, C, LOD */
+ tgsi_sampler_lod_none,
&r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */
break;
fetch_texel(mach->Samplers[unit],
&r[0], &r[1], &r[2], &ZeroVec, &ZeroVec, /* inputs */
- tgsi_sampler_lod_bias,
+ tgsi_sampler_lod_none,
&r[0], &r[1], &r[2], &r[3]); /* outputs */
break;
fetch_texel(mach->Samplers[unit],
&r[0], &r[1], &r[2], &ZeroVec, &ZeroVec,
- tgsi_sampler_lod_bias,
+ tgsi_sampler_lod_none,
&r[0], &r[1], &r[2], &r[3]);
break;
fetch_texel(mach->Samplers[unit],
&r[0], &r[1], &r[2], &r[3], &ZeroVec,
- tgsi_sampler_lod_bias,
+ tgsi_sampler_lod_none,
&r[0], &r[1], &r[2], &r[3]);
break;
{
const uint resource_unit = inst->Src[1].Register.Index;
const uint sampler_unit = inst->Src[2].Register.Index;
- union tgsi_exec_channel r[4];
+ union tgsi_exec_channel r[4], c1;
const union tgsi_exec_channel *lod = &ZeroVec;
- enum tgsi_sampler_control control;
+ enum tgsi_sampler_control control = tgsi_sampler_lod_none;
uint chan;
assert(modifier != TEX_MODIFIER_PROJECTED);
if (modifier != TEX_MODIFIER_NONE) {
if (modifier == TEX_MODIFIER_LOD_BIAS) {
- FETCH(&r[3], 3, TGSI_CHAN_X);
- lod = &r[3];
+ FETCH(&c1, 3, TGSI_CHAN_X);
+ lod = &c1;
+ control = tgsi_sampler_lod_bias;
}
else if (modifier == TEX_MODIFIER_EXPLICIT_LOD) {
- FETCH(&r[3], 0, TGSI_CHAN_W);
- lod = &r[3];
+ FETCH(&c1, 0, TGSI_CHAN_W);
+ lod = &c1;
+ control = tgsi_sampler_lod_explicit;
}
- else
+ else {
assert(modifier == TEX_MODIFIER_LEVEL_ZERO);
- }
-
- if (modifier == TEX_MODIFIER_EXPLICIT_LOD ||
- modifier == TEX_MODIFIER_LEVEL_ZERO) {
- control = tgsi_sampler_lod_explicit;
- } else {
- control = tgsi_sampler_lod_bias;
+ control = tgsi_sampler_lod_zero;
+ }
}
FETCH(&r[0], 0, TGSI_CHAN_X);
if (compare) {
FETCH(&r[2], 3, TGSI_CHAN_X);
fetch_texel(mach->Samplers[sampler_unit],
- &r[0], &ZeroVec, &r[2], lod, &ZeroVec, /* S, T, P, LOD */
+ &r[0], &ZeroVec, &r[2], &ZeroVec, lod, /* S, T, P, C, LOD */
control,
&r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */
}
else {
fetch_texel(mach->Samplers[sampler_unit],
- &r[0], &ZeroVec, &ZeroVec, lod, &ZeroVec, /* S, T, P, LOD */
+ &r[0], &ZeroVec, &ZeroVec, &ZeroVec, lod, /* S, T, P, C, LOD */
control,
&r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */
}
if (compare) {
FETCH(&r[2], 3, TGSI_CHAN_X);
fetch_texel(mach->Samplers[sampler_unit],
- &r[0], &r[1], &r[2], lod, &ZeroVec, /* S, T, P, LOD */
+ &r[0], &r[1], &r[2], &ZeroVec, lod, /* S, T, P, C, LOD */
control,
&r[0], &r[1], &r[2], &r[3]); /* outputs */
}
else {
fetch_texel(mach->Samplers[sampler_unit],
- &r[0], &r[1], &ZeroVec, lod, &ZeroVec, /* S, T, P, LOD */
+ &r[0], &r[1], &ZeroVec, &ZeroVec, lod, /* S, T, P, C, LOD */
control,
&r[0], &r[1], &r[2], &r[3]); /* outputs */
}
if(compare) {
FETCH(&r[3], 3, TGSI_CHAN_X);
fetch_texel(mach->Samplers[sampler_unit],
- &r[0], &r[1], &r[2], &r[3], &ZeroVec,
+ &r[0], &r[1], &r[2], &r[3], lod,
control,
&r[0], &r[1], &r[2], &r[3]);
}
else {
fetch_texel(mach->Samplers[sampler_unit],
- &r[0], &r[1], &r[2], lod, &ZeroVec,
+ &r[0], &r[1], &r[2], &ZeroVec, lod,
control,
&r[0], &r[1], &r[2], &r[3]);
}
FETCH(&r[2], 0, TGSI_CHAN_Z);
FETCH(&r[3], 0, TGSI_CHAN_W);
if(compare) {
- assert(modifier == TEX_MODIFIER_NONE);
- /*
- * FIXME: lod bias and explicit lod are prohibited but
- * for sample_c_lz we pass the level zero info as explicit
- * lod 0.
- */
FETCH(&r[4], 3, TGSI_CHAN_X);
fetch_texel(mach->Samplers[sampler_unit],
&r[0], &r[1], &r[2], &r[3], &r[4],
FETCH(&r[0], 0, TGSI_CHAN_X);
fetch_texel(mach->Samplers[sampler_unit],
- &r[0], &ZeroVec, &ZeroVec, &ZeroVec, &ZeroVec, /* S, T, P, BIAS */
- tgsi_sampler_lod_bias,
+ &r[0], &ZeroVec, &ZeroVec, &ZeroVec, &ZeroVec, /* S, T, P, C, LOD */
+ tgsi_sampler_lod_none,
&r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */
break;
fetch_texel(mach->Samplers[sampler_unit],
&r[0], &r[1], &ZeroVec, &ZeroVec, &ZeroVec, /* inputs */
- tgsi_sampler_lod_bias,
+ tgsi_sampler_lod_none,
&r[0], &r[1], &r[2], &r[3]); /* outputs */
break;
fetch_texel(mach->Samplers[sampler_unit],
&r[0], &r[1], &r[2], &ZeroVec, &ZeroVec,
- tgsi_sampler_lod_bias,
+ tgsi_sampler_lod_none,
&r[0], &r[1], &r[2], &r[3]);
break;
fetch_texel(mach->Samplers[sampler_unit],
&r[0], &r[1], &r[2], &r[3], &ZeroVec,
- tgsi_sampler_lod_bias,
+ tgsi_sampler_lod_none,
&r[0], &r[1], &r[2], &r[3]);
break;
* \param s the incoming texcoords
* \param size the texture image size
* \param icoord returns the integer texcoords
- * \return integer texture index
*/
static void
wrap_nearest_repeat(float s, unsigned size, int *icoord)
}
-/* Calculate level of detail for every fragment.
+/* Calculate level of detail for every fragment,
+ * with lambda already computed.
* Note that lambda has already been biased by global LOD bias.
+ * \param biased_lambda per-quad lambda.
+ * \param lod_in per-fragment lod_bias or explicit_lod.
+ * \param lod returns the per-fragment lod.
*/
static INLINE void
compute_lod(const struct pipe_sampler_state *sampler,
+ enum tgsi_sampler_control control,
const float biased_lambda,
- const float lodbias[TGSI_QUAD_SIZE],
+ const float lod_in[TGSI_QUAD_SIZE],
float lod[TGSI_QUAD_SIZE])
{
+ float min_lod = sampler->min_lod;
+ float max_lod = sampler->max_lod;
uint i;
- for (i = 0; i < TGSI_QUAD_SIZE; i++) {
- lod[i] = biased_lambda + lodbias[i];
- lod[i] = CLAMP(lod[i], sampler->min_lod, sampler->max_lod);
+ switch (control) {
+ case tgsi_sampler_lod_none:
+ case tgsi_sampler_lod_zero:
+ lod[0] = lod[1] = lod[2] = lod[3] = CLAMP(biased_lambda, min_lod, max_lod);
+ break;
+ case tgsi_sampler_lod_bias:
+ for (i = 0; i < TGSI_QUAD_SIZE; i++) {
+ lod[i] = biased_lambda + lod_in[i];
+ lod[i] = CLAMP(lod[i], min_lod, max_lod);
+ }
+ break;
+ case tgsi_sampler_lod_explicit:
+ for (i = 0; i < TGSI_QUAD_SIZE; i++) {
+ lod[i] = CLAMP(lod_in[i], min_lod, max_lod);
+ }
+ break;
+ default:
+ assert(0);
+ lod[0] = lod[1] = lod[2] = lod[3] = 0.0f;
+ }
+}
+
+
+/* Calculate level of detail for every fragment.
+ * \param lod_in per-fragment lod_bias or explicit_lod.
+ * \param lod results per-fragment lod.
+ */
+static INLINE void
+compute_lambda_lod(struct sp_sampler_variant *samp,
+ const float s[TGSI_QUAD_SIZE],
+ const float t[TGSI_QUAD_SIZE],
+ const float p[TGSI_QUAD_SIZE],
+ const float lod_in[TGSI_QUAD_SIZE],
+ enum tgsi_sampler_control control,
+ float lod[TGSI_QUAD_SIZE])
+{
+ const struct pipe_sampler_state *sampler = samp->sampler;
+ float lod_bias = sampler->lod_bias;
+ float min_lod = sampler->min_lod;
+ float max_lod = sampler->max_lod;
+ float lambda;
+ uint i;
+
+ switch (control) {
+ case tgsi_sampler_lod_none:
+ lambda = samp->compute_lambda(samp, s, t, p) + lod_bias;
+ lod[0] = lod[1] = lod[2] = lod[3] = CLAMP(lambda, min_lod, max_lod);
+ break;
+ case tgsi_sampler_lod_bias:
+ lambda = samp->compute_lambda(samp, s, t, p) + lod_bias;
+ for (i = 0; i < TGSI_QUAD_SIZE; i++) {
+ lod[i] = lambda + lod_in[i];
+ lod[i] = CLAMP(lod[i], min_lod, max_lod);
+ }
+ break;
+ case tgsi_sampler_lod_explicit:
+ for (i = 0; i < TGSI_QUAD_SIZE; i++) {
+ lod[i] = CLAMP(lod_in[i], min_lod, max_lod);
+ }
+ break;
+ case tgsi_sampler_lod_zero:
+ /* this is all static state in the sampler really need clamp here? */
+ lod[0] = lod[1] = lod[2] = lod[3] = CLAMP(lod_bias, min_lod, max_lod);
+ break;
+ default:
+ assert(0);
+ lod[0] = lod[1] = lod[2] = lod[3] = 0.0f;
}
}
const float t[TGSI_QUAD_SIZE],
const float p[TGSI_QUAD_SIZE],
const float c0[TGSI_QUAD_SIZE],
- const float c1[TGSI_QUAD_SIZE],
+ const float lod_in[TGSI_QUAD_SIZE],
enum tgsi_sampler_control control,
float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
{
int j;
float lod[TGSI_QUAD_SIZE];
- if (control == tgsi_sampler_lod_bias) {
- float lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias;
- if (samp->key.bits.target == PIPE_TEXTURE_CUBE_ARRAY)
- compute_lod(samp->sampler, lambda, c1, lod);
- else
- compute_lod(samp->sampler, lambda, c0, lod);
- } else {
- assert(control == tgsi_sampler_lod_explicit);
-
- if (samp->key.bits.target == PIPE_TEXTURE_CUBE_ARRAY)
- memcpy(lod, c1, sizeof(lod));
- else
- memcpy(lod, c0, sizeof(lod));
-
- }
+ compute_lambda_lod(samp, s, t, p, lod_in, control, lod);
for (j = 0; j < TGSI_QUAD_SIZE; j++) {
int level0 = samp->view->u.tex.first_level + (int)lod[j];
const float t[TGSI_QUAD_SIZE],
const float p[TGSI_QUAD_SIZE],
const float c0[TGSI_QUAD_SIZE],
- const float c1[TGSI_QUAD_SIZE],
+ const float lod_in[TGSI_QUAD_SIZE],
enum tgsi_sampler_control control,
float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
{
float lod[TGSI_QUAD_SIZE];
int j;
- if (control == tgsi_sampler_lod_bias) {
- float lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias;
- if (samp->key.bits.target == PIPE_TEXTURE_CUBE_ARRAY)
- compute_lod(samp->sampler, lambda, c1, lod);
- else
- compute_lod(samp->sampler, lambda, c0, lod);
- } else {
- assert(control == tgsi_sampler_lod_explicit);
-
- if (samp->key.bits.target == PIPE_TEXTURE_CUBE_ARRAY)
- memcpy(lod, c1, sizeof(lod));
- else
- memcpy(lod, c0, sizeof(lod));
- }
+ compute_lambda_lod(samp, s, t, p, lod_in, control, lod);
for (j = 0; j < TGSI_QUAD_SIZE; j++) {
if (lod[j] < 0.0)
const float t[TGSI_QUAD_SIZE],
const float p[TGSI_QUAD_SIZE],
const float c0[TGSI_QUAD_SIZE],
- const float c1[TGSI_QUAD_SIZE],
+ const float lod_in[TGSI_QUAD_SIZE],
enum tgsi_sampler_control control,
float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
{
float lod[TGSI_QUAD_SIZE];
int j;
- if (control == tgsi_sampler_lod_bias) {
- float lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias;
- if (samp->key.bits.target == PIPE_TEXTURE_CUBE_ARRAY)
- compute_lod(samp->sampler, lambda, c1, lod);
- else
- compute_lod(samp->sampler, lambda, c0, lod);
- } else {
- assert(control == tgsi_sampler_lod_explicit);
-
- if (samp->key.bits.target == PIPE_TEXTURE_CUBE_ARRAY)
- memcpy(lod, c1, sizeof(lod));
- else
- memcpy(lod, c0, sizeof(lod));
- }
+ compute_lambda_lod(samp, s, t, p, lod_in, control, lod);
for (j = 0; j < TGSI_QUAD_SIZE; j++) {
if (lod[j] < 0.0) {
const float t[TGSI_QUAD_SIZE],
const float p[TGSI_QUAD_SIZE],
const float c0[TGSI_QUAD_SIZE],
- const float c1[TGSI_QUAD_SIZE],
+ const float lod_in[TGSI_QUAD_SIZE],
enum tgsi_sampler_control control,
float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
{
const float t[TGSI_QUAD_SIZE],
const float p[TGSI_QUAD_SIZE],
const float c0[TGSI_QUAD_SIZE],
- const float c1[TGSI_QUAD_SIZE],
+ const float lod_in[TGSI_QUAD_SIZE],
enum tgsi_sampler_control control,
float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
{
float dvdx = (t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]) * t_to_v;
float dvdy = (t[QUAD_TOP_LEFT] - t[QUAD_BOTTOM_LEFT]) * t_to_v;
- if (control == tgsi_sampler_lod_bias) {
+ if (control == tgsi_sampler_lod_bias ||
+ control == tgsi_sampler_lod_none) {
/* note: instead of working with Px and Py, we will use the
* squared length instead, to avoid sqrt.
*/
* this since 0.5*log(x) = log(sqrt(x))
*/
lambda = 0.5F * util_fast_log2(Pmin2) + samp->sampler->lod_bias;
- compute_lod(samp->sampler, lambda, c0, lod);
+ compute_lod(samp->sampler, control, lambda, lod_in, lod);
}
else {
- assert(control == tgsi_sampler_lod_explicit);
-
- memcpy(lod, c0, sizeof(lod));
+ assert(control == tgsi_sampler_lod_explicit ||
+ control == tgsi_sampler_lod_zero);
+ compute_lod(samp->sampler, control, samp->sampler->lod_bias, lod_in, lod);
}
/* XXX: Take into account all lod values.
const float t[TGSI_QUAD_SIZE],
const float p[TGSI_QUAD_SIZE],
const float c0[TGSI_QUAD_SIZE],
- const float c1[TGSI_QUAD_SIZE],
+ const float lod_in[TGSI_QUAD_SIZE],
enum tgsi_sampler_control control,
float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
{
struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
const struct pipe_resource *texture = samp->view->texture;
int j;
- float lambda;
float lod[TGSI_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));
- }
+ compute_lambda_lod(samp, s, t, p, lod_in, control, lod);
for (j = 0; j < TGSI_QUAD_SIZE; j++) {
int level0 = samp->view->u.tex.first_level + (int)lod[j];