[Mesa-dev] [PATCH] tgsi: add texel offsets and derivatives to sampler interface
Brian Paul
brianp at vmware.com
Fri Mar 1 10:54:18 PST 2013
Looks good, just minor things below.
Reviewed-by: Brian Paul <brianp at vmware.com>
On 03/01/2013 11:41 AM, sroland at vmware.com wrote:
> From: Roland Scheidegger<sroland at vmware.com>
>
> Something I never got around to implement, but this is the tgsi execution
> side for implementing texel offsets (for ordinary texturing) and explicit
> derivatives for sampling (though I guess the ordering of the components
> for the derivs parameters is debatable).
> There is certainly a runtime cost associated with this.
> Unless there are different interfaces used depending on the "complexity"
> of the texture instructions, this is impossible to avoid.
> Offsets are always active (I think checking if they are active or not is
> probably not worth it since it should mostly be an add), whereas the
> sampler_control is extended for explicit derivatives.
> For now softpipe (the only user of this) just drops all those new values
> on the floor (which is the part I never implemented...).
>
> Additionally this also fixes (discovered by accident) inconsistent
> projective divide for the comparison coord - the code did do the
> projection for shadow2d targets, but not shadow1d ones. This also
> drops checking for projection modifier on array targets, since they
> aren't possible in any extension I know of (hence we don't actually
> know if the array layer should also be divided or not).
> ---
> src/gallium/auxiliary/tgsi/tgsi_exec.c | 255 ++++++++++++++++++++------
> src/gallium/auxiliary/tgsi/tgsi_exec.h | 10 +-
> src/gallium/drivers/softpipe/sp_tex_sample.c | 10 +-
> 3 files changed, 210 insertions(+), 65 deletions(-)
>
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
> index 6277c3e..feb5928 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
> @@ -1720,6 +1720,8 @@ fetch_texel( struct tgsi_sampler *sampler,
> const union tgsi_exec_channel *p,
> const union tgsi_exec_channel *c0,
> const union tgsi_exec_channel *c1,
> + float derivs[3][2][TGSI_QUAD_SIZE],
> + const int8_t offset[3],
> enum tgsi_sampler_control control,
> union tgsi_exec_channel *r,
> union tgsi_exec_channel *g,
> @@ -1731,7 +1733,7 @@ fetch_texel( struct tgsi_sampler *sampler,
>
> /* FIXME: handle explicit derivs, offsets */
> sampler->get_samples(sampler, sview_idx, sampler_idx,
> - s->f, t->f, p->f, c0->f, c1->f, control, rgba);
> + s->f, t->f, p->f, c0->f, c1->f, derivs, offset, control, rgba);
>
> for (j = 0; j< 4; j++) {
> r->f[j] = rgba[0][j];
> @@ -1765,6 +1767,23 @@ exec_tex(struct tgsi_exec_machine *mach,
> const union tgsi_exec_channel *lod =&ZeroVec;
> enum tgsi_sampler_control control = tgsi_sampler_lod_none;
> uint chan;
> + int8_t offsets[3];
> +
> + if (inst->Texture.NumOffsets == 1) {
> + union tgsi_exec_channel index;
> + union tgsi_exec_channel offset[3];
> + index.i[0] = index.i[1] = index.i[2] = index.i[3] = inst->TexOffsets[0].Index;
> + fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
> + inst->TexOffsets[0].SwizzleX,&index,&ZeroVec,&offset[0]);
> + fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
> + inst->TexOffsets[0].SwizzleY,&index,&ZeroVec,&offset[1]);
> + fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
> + inst->TexOffsets[0].SwizzleZ,&index,&ZeroVec,&offset[2]);
> + offsets[0] = offset[0].i[0];
> + offsets[1] = offset[1].i[0];
> + offsets[2] = offset[2].i[0];
> + } else
assert(inst->Texture.NumOffsets == 0) here just to be safe?
> + offsets[0] = offsets[1] = offsets[2] = 0;
>
> assert(modifier != TEX_MODIFIER_LEVEL_ZERO);
>
> @@ -1791,25 +1810,41 @@ exec_tex(struct tgsi_exec_machine *mach,
>
> fetch_texel(mach->Sampler, unit, unit,
> &r[0],&ZeroVec,&ZeroVec,&ZeroVec, lod, /* S, T, P, C, LOD */
> - control,
> + NULL, offsets, control,
> &r[0],&r[1],&r[2],&r[3]); /* R, G, B, A */
> break;
> +
> case TGSI_TEXTURE_SHADOW1D:
> FETCH(&r[0], 0, TGSI_CHAN_X);
> FETCH(&r[2], 0, TGSI_CHAN_Z);
>
> if (modifier == TEX_MODIFIER_PROJECTED) {
> micro_div(&r[0],&r[0],&r[3]);
> + micro_div(&r[2],&r[2],&r[3]);
> }
>
> fetch_texel(mach->Sampler, unit, unit,
> &r[0],&ZeroVec,&r[2],&ZeroVec, lod, /* S, T, P, C, LOD */
> - control,
> + NULL, offsets, control,
> &r[0],&r[1],&r[2],&r[3]); /* R, G, B, A */
> break;
>
> case TGSI_TEXTURE_2D:
> case TGSI_TEXTURE_RECT:
> + FETCH(&r[0], 0, TGSI_CHAN_X);
> + FETCH(&r[1], 0, TGSI_CHAN_Y);
> +
> + if (modifier == TEX_MODIFIER_PROJECTED) {
> + micro_div(&r[0],&r[0],&r[3]);
> + micro_div(&r[1],&r[1],&r[3]);
> + }
> +
> + fetch_texel(mach->Sampler, unit, unit,
> +&r[0],&r[1],&ZeroVec,&ZeroVec, lod, /* S, T, P, C, LOD */
> + NULL, offsets, control,
> +&r[0],&r[1],&r[2],&r[3]); /* outputs */
> + break;
> +
> case TGSI_TEXTURE_SHADOW2D:
> case TGSI_TEXTURE_SHADOWRECT:
> FETCH(&r[0], 0, TGSI_CHAN_X);
> @@ -1824,7 +1859,7 @@ exec_tex(struct tgsi_exec_machine *mach,
>
> fetch_texel(mach->Sampler, unit, unit,
> &r[0],&r[1],&r[2],&ZeroVec, lod, /* S, T, P, C, LOD */
> - control,
> + NULL, offsets, control,
> &r[0],&r[1],&r[2],&r[3]); /* outputs */
> break;
>
> @@ -1832,13 +1867,11 @@ exec_tex(struct tgsi_exec_machine *mach,
> FETCH(&r[0], 0, TGSI_CHAN_X);
> FETCH(&r[1], 0, TGSI_CHAN_Y);
>
> - if (modifier == TEX_MODIFIER_PROJECTED) {
> - micro_div(&r[0],&r[0],&r[3]);
> - }
> + assert(modifier != TEX_MODIFIER_PROJECTED);
>
> fetch_texel(mach->Sampler, unit, unit,
> &r[0],&r[1],&ZeroVec,&ZeroVec, lod, /* S, T, P, C, LOD */
> - control,
> + NULL, offsets, control,
> &r[0],&r[1],&r[2],&r[3]); /* outputs */
> break;
> case TGSI_TEXTURE_SHADOW1D_ARRAY:
> @@ -1846,13 +1879,11 @@ exec_tex(struct tgsi_exec_machine *mach,
> FETCH(&r[1], 0, TGSI_CHAN_Y);
> FETCH(&r[2], 0, TGSI_CHAN_Z);
>
> - if (modifier == TEX_MODIFIER_PROJECTED) {
> - micro_div(&r[0],&r[0],&r[3]);
> - }
> + assert(modifier != TEX_MODIFIER_PROJECTED);
>
> fetch_texel(mach->Sampler, unit, unit,
> &r[0],&r[1],&r[2],&ZeroVec, lod, /* S, T, P, C, LOD */
> - control,
> + NULL, offsets, control,
> &r[0],&r[1],&r[2],&r[3]); /* outputs */
> break;
>
> @@ -1861,14 +1892,11 @@ exec_tex(struct tgsi_exec_machine *mach,
> FETCH(&r[1], 0, TGSI_CHAN_Y);
> FETCH(&r[2], 0, TGSI_CHAN_Z);
>
> - if (modifier == TEX_MODIFIER_PROJECTED) {
> - micro_div(&r[0],&r[0],&r[3]);
> - micro_div(&r[1],&r[1],&r[3]);
> - }
> + assert(modifier != TEX_MODIFIER_PROJECTED);
>
> fetch_texel(mach->Sampler, unit, unit,
> &r[0],&r[1],&r[2],&ZeroVec, lod, /* S, T, P, C, LOD */
> - control,
> + NULL, offsets, control,
> &r[0],&r[1],&r[2],&r[3]); /* outputs */
> break;
> case TGSI_TEXTURE_SHADOW2D_ARRAY:
> @@ -1880,7 +1908,7 @@ exec_tex(struct tgsi_exec_machine *mach,
>
> fetch_texel(mach->Sampler, unit, unit,
> &r[0],&r[1],&r[2],&r[3],&ZeroVec, /* S, T, P, C, LOD */
> - control,
> + NULL, offsets, control,
> &r[0],&r[1],&r[2],&r[3]); /* outputs */
> break;
> case TGSI_TEXTURE_CUBE_ARRAY:
> @@ -1897,7 +1925,7 @@ exec_tex(struct tgsi_exec_machine *mach,
>
> fetch_texel(mach->Sampler, unit, unit,
> &r[0],&r[1],&r[2],&r[3],&cubelod, /* S, T, P, C, LOD */
> - control,
> + NULL, offsets, control,
> &r[0],&r[1],&r[2],&r[3]); /* outputs */
> break;
> case TGSI_TEXTURE_3D:
> @@ -1914,7 +1942,7 @@ exec_tex(struct tgsi_exec_machine *mach,
>
> fetch_texel(mach->Sampler, unit, unit,
> &r[0],&r[1],&r[2],&ZeroVec, lod,
> - control,
> + NULL, offsets, control,
> &r[0],&r[1],&r[2],&r[3]);
> break;
>
> @@ -1928,7 +1956,7 @@ exec_tex(struct tgsi_exec_machine *mach,
>
> fetch_texel(mach->Sampler, unit, unit,
> &r[0],&r[1],&r[2],&r[3],&cubearraycomp, /* S, T, P, C, LOD */
> - control,
> + NULL, offsets, control,
> &r[0],&r[1],&r[2],&r[3]); /* outputs */
> break;
> default:
> @@ -1953,72 +1981,132 @@ exec_tex(struct tgsi_exec_machine *mach,
> }
> }
>
> +
Maybe put a comment on this function to explain it:
> +static void
> +fetch_assign_deriv_channel(struct tgsi_exec_machine *mach,
> + const struct tgsi_full_instruction *inst,
> + unsigned regdsrcx,
> + unsigned chan,
> + float derivs[2][TGSI_QUAD_SIZE])
> +{
> + union tgsi_exec_channel d;
> + FETCH(&d, regdsrcx, chan);
> + derivs[0][0] = d.f[0];
> + derivs[0][1] = d.f[1];
> + derivs[0][2] = d.f[2];
> + derivs[0][3] = d.f[3];
> + FETCH(&d, regdsrcx + 1, chan);
> + derivs[1][0] = d.f[0];
> + derivs[1][1] = d.f[1];
> + derivs[1][2] = d.f[2];
> + derivs[1][3] = d.f[3];
> +}
> +
> static void
> exec_txd(struct tgsi_exec_machine *mach,
> const struct tgsi_full_instruction *inst)
> {
> const uint unit = inst->Src[3].Register.Index;
> union tgsi_exec_channel r[4];
> + float derivs[3][2][TGSI_QUAD_SIZE];
> uint chan;
> + int8_t offsets[3];
>
> - /*
> - * XXX: This is fake TXD -- the derivatives are not taken into account, yet.
> - */
> + if (inst->Texture.NumOffsets == 1) {
> + union tgsi_exec_channel index;
> + union tgsi_exec_channel offset[3];
> + index.i[0] = index.i[1] = index.i[2] = index.i[3] = inst->TexOffsets[0].Index;
> + fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
> + inst->TexOffsets[0].SwizzleX,&index,&ZeroVec,&offset[0]);
> + fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
> + inst->TexOffsets[0].SwizzleY,&index,&ZeroVec,&offset[1]);
> + fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
> + inst->TexOffsets[0].SwizzleZ,&index,&ZeroVec,&offset[2]);
> + offsets[0] = offset[0].i[0];
> + offsets[1] = offset[1].i[0];
> + offsets[2] = offset[2].i[0];
> + } else
> + offsets[0] = offsets[1] = offsets[2] = 0;
>
> switch (inst->Texture.Texture) {
> case TGSI_TEXTURE_1D:
> - case TGSI_TEXTURE_SHADOW1D:
> -
> FETCH(&r[0], 0, TGSI_CHAN_X);
>
> + fetch_assign_deriv_channel(mach, inst, 1, TGSI_CHAN_X, derivs[0]);
> +
> fetch_texel(mach->Sampler, unit, unit,
> &r[0],&ZeroVec,&ZeroVec,&ZeroVec,&ZeroVec, /* S, T, P, C, LOD */
> - tgsi_sampler_lod_none,
> + derivs, offsets, tgsi_sampler_derivs_explicit,
> &r[0],&r[1],&r[2],&r[3]); /* R, G, B, A */
> break;
>
> + case TGSI_TEXTURE_SHADOW1D:
> case TGSI_TEXTURE_1D_ARRAY:
> - case TGSI_TEXTURE_2D:
> - case TGSI_TEXTURE_RECT:
> case TGSI_TEXTURE_SHADOW1D_ARRAY:
> - case TGSI_TEXTURE_SHADOW2D:
> - case TGSI_TEXTURE_SHADOWRECT:
> -
> + /* SHADOW1D/1D_ARRAY would not need Y/Z respectively, but don't bother */
> FETCH(&r[0], 0, TGSI_CHAN_X);
> FETCH(&r[1], 0, TGSI_CHAN_Y);
> FETCH(&r[2], 0, TGSI_CHAN_Z);
>
> + fetch_assign_deriv_channel(mach, inst, 1, TGSI_CHAN_X, derivs[0]);
> +
> fetch_texel(mach->Sampler, unit, unit,
> -&r[0],&r[1],&r[2],&ZeroVec,&ZeroVec, /* inputs */
> - tgsi_sampler_lod_none,
> -&r[0],&r[1],&r[2],&r[3]); /* outputs */
> +&r[0],&r[1],&r[2],&ZeroVec,&ZeroVec, /* S, T, P, C, LOD */
> + derivs, offsets, tgsi_sampler_derivs_explicit,
> +&r[0],&r[1],&r[2],&r[3]); /* R, G, B, A */
> break;
>
> - case TGSI_TEXTURE_2D_ARRAY:
> - case TGSI_TEXTURE_3D:
> - case TGSI_TEXTURE_CUBE:
> - case TGSI_TEXTURE_CUBE_ARRAY:
> + case TGSI_TEXTURE_2D:
> + case TGSI_TEXTURE_RECT:
> FETCH(&r[0], 0, TGSI_CHAN_X);
> FETCH(&r[1], 0, TGSI_CHAN_Y);
> - FETCH(&r[2], 0, TGSI_CHAN_Z);
> +
> + fetch_assign_deriv_channel(mach, inst, 1, TGSI_CHAN_X, derivs[0]);
> + fetch_assign_deriv_channel(mach, inst, 1, TGSI_CHAN_Y, derivs[1]);
>
> fetch_texel(mach->Sampler, unit, unit,
> -&r[0],&r[1],&r[2],&ZeroVec,&ZeroVec,
> - tgsi_sampler_lod_none,
> -&r[0],&r[1],&r[2],&r[3]);
> +&r[0],&r[1],&ZeroVec,&ZeroVec,&ZeroVec, /* S, T, P, C, LOD */
> + derivs, offsets, tgsi_sampler_derivs_explicit,
> +&r[0],&r[1],&r[2],&r[3]); /* R, G, B, A */
> break;
>
> +
> + case TGSI_TEXTURE_SHADOW2D:
> + case TGSI_TEXTURE_SHADOWRECT:
> + case TGSI_TEXTURE_2D_ARRAY:
> case TGSI_TEXTURE_SHADOW2D_ARRAY:
> + /* only SHADOW2D_ARRAY actually needs W */
> + FETCH(&r[0], 0, TGSI_CHAN_X);
> + FETCH(&r[1], 0, TGSI_CHAN_Y);
> + FETCH(&r[2], 0, TGSI_CHAN_Z);
> + FETCH(&r[3], 0, TGSI_CHAN_W);
>
> + fetch_assign_deriv_channel(mach, inst, 1, TGSI_CHAN_X, derivs[0]);
> + fetch_assign_deriv_channel(mach, inst, 1, TGSI_CHAN_Y, derivs[1]);
> +
> + fetch_texel(mach->Sampler, unit, unit,
> +&r[0],&r[1],&r[2],&r[3],&ZeroVec, /* inputs */
> + derivs, offsets, tgsi_sampler_derivs_explicit,
> +&r[0],&r[1],&r[2],&r[3]); /* outputs */
> + break;
> +
> + case TGSI_TEXTURE_3D:
> + case TGSI_TEXTURE_CUBE:
> + case TGSI_TEXTURE_CUBE_ARRAY:
> + /* only TEXTURE_CUBE_ARRAY actually needs W */
> FETCH(&r[0], 0, TGSI_CHAN_X);
> FETCH(&r[1], 0, TGSI_CHAN_Y);
> FETCH(&r[2], 0, TGSI_CHAN_Z);
> FETCH(&r[3], 0, TGSI_CHAN_W);
>
> + fetch_assign_deriv_channel(mach, inst, 1, TGSI_CHAN_X, derivs[0]);
> + fetch_assign_deriv_channel(mach, inst, 1, TGSI_CHAN_Y, derivs[1]);
> + fetch_assign_deriv_channel(mach, inst, 1, TGSI_CHAN_Z, derivs[2]);
> +
> fetch_texel(mach->Sampler, unit, unit,
> -&r[0],&r[1],&r[2],&r[3],&ZeroVec,
> - tgsi_sampler_lod_none,
> -&r[0],&r[1],&r[2],&r[3]);
> +&r[0],&r[1],&r[2],&r[3],&ZeroVec, /* inputs */
> + derivs, offsets, tgsi_sampler_derivs_explicit,
> +&r[0],&r[1],&r[2],&r[3]); /* outputs */
> break;
>
> default:
> @@ -2142,6 +2230,23 @@ exec_sample(struct tgsi_exec_machine *mach,
> const union tgsi_exec_channel *lod =&ZeroVec;
> enum tgsi_sampler_control control = tgsi_sampler_lod_none;
> uint chan;
> + int8_t offsets[3];
> +
> + if (inst->Texture.NumOffsets == 1) {
> + union tgsi_exec_channel index;
> + union tgsi_exec_channel offset[3];
> + index.i[0] = index.i[1] = index.i[2] = index.i[3] = inst->TexOffsets[0].Index;
> + fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
> + inst->TexOffsets[0].SwizzleX,&index,&ZeroVec,&offset[0]);
> + fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
> + inst->TexOffsets[0].SwizzleY,&index,&ZeroVec,&offset[1]);
> + fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
> + inst->TexOffsets[0].SwizzleZ,&index,&ZeroVec,&offset[2]);
> + offsets[0] = offset[0].i[0];
> + offsets[1] = offset[1].i[0];
> + offsets[2] = offset[2].i[0];
> + } else
> + offsets[0] = offsets[1] = offsets[2] = 0;
>
> assert(modifier != TEX_MODIFIER_PROJECTED);
>
> @@ -2170,13 +2275,13 @@ exec_sample(struct tgsi_exec_machine *mach,
> FETCH(&r[2], 3, TGSI_CHAN_X);
> fetch_texel(mach->Sampler, resource_unit, sampler_unit,
> &r[0],&ZeroVec,&r[2],&ZeroVec, lod, /* S, T, P, C, LOD */
> - control,
> + NULL, offsets, control,
> &r[0],&r[1],&r[2],&r[3]); /* R, G, B, A */
> }
> else {
> fetch_texel(mach->Sampler, resource_unit, sampler_unit,
> &r[0],&ZeroVec,&ZeroVec,&ZeroVec, lod, /* S, T, P, C, LOD */
> - control,
> + NULL, offsets, control,
> &r[0],&r[1],&r[2],&r[3]); /* R, G, B, A */
> }
> break;
> @@ -2189,13 +2294,13 @@ exec_sample(struct tgsi_exec_machine *mach,
> FETCH(&r[2], 3, TGSI_CHAN_X);
> fetch_texel(mach->Sampler, resource_unit, sampler_unit,
> &r[0],&r[1],&r[2],&ZeroVec, lod, /* S, T, P, C, LOD */
> - control,
> + NULL, offsets, control,
> &r[0],&r[1],&r[2],&r[3]); /* outputs */
> }
> else {
> fetch_texel(mach->Sampler, resource_unit, sampler_unit,
> &r[0],&r[1],&ZeroVec,&ZeroVec, lod, /* S, T, P, C, LOD */
> - control,
> + NULL, offsets, control,
> &r[0],&r[1],&r[2],&r[3]); /* outputs */
> }
> break;
> @@ -2209,13 +2314,13 @@ exec_sample(struct tgsi_exec_machine *mach,
> FETCH(&r[3], 3, TGSI_CHAN_X);
> fetch_texel(mach->Sampler, resource_unit, sampler_unit,
> &r[0],&r[1],&r[2],&r[3], lod,
> - control,
> + NULL, offsets, control,
> &r[0],&r[1],&r[2],&r[3]);
> }
> else {
> fetch_texel(mach->Sampler, resource_unit, sampler_unit,
> &r[0],&r[1],&r[2],&ZeroVec, lod,
> - control,
> + NULL, offsets, control,
> &r[0],&r[1],&r[2],&r[3]);
> }
> break;
> @@ -2228,13 +2333,13 @@ exec_sample(struct tgsi_exec_machine *mach,
> FETCH(&r[4], 3, TGSI_CHAN_X);
> fetch_texel(mach->Sampler, resource_unit, sampler_unit,
> &r[0],&r[1],&r[2],&r[3],&r[4],
> - control,
> + NULL, offsets, control,
> &r[0],&r[1],&r[2],&r[3]);
> }
> else {
> fetch_texel(mach->Sampler, resource_unit, sampler_unit,
> &r[0],&r[1],&r[2],&r[3], lod,
> - control,
> + NULL, offsets, control,
> &r[0],&r[1],&r[2],&r[3]);
> }
> break;
> @@ -2258,18 +2363,35 @@ exec_sample_d(struct tgsi_exec_machine *mach,
> const uint resource_unit = inst->Src[1].Register.Index;
> const uint sampler_unit = inst->Src[2].Register.Index;
> union tgsi_exec_channel r[4];
> + float derivs[3][2][TGSI_QUAD_SIZE];
> uint chan;
> - /*
> - * XXX: This is fake SAMPLE_D -- the derivatives are not taken into account, yet.
> - */
> + int8_t offsets[3];
> +
> + if (inst->Texture.NumOffsets == 1) {
> + union tgsi_exec_channel index;
> + union tgsi_exec_channel offset[3];
> + index.i[0] = index.i[1] = index.i[2] = index.i[3] = inst->TexOffsets[0].Index;
> + fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
> + inst->TexOffsets[0].SwizzleX,&index,&ZeroVec,&offset[0]);
> + fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
> + inst->TexOffsets[0].SwizzleY,&index,&ZeroVec,&offset[1]);
> + fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
> + inst->TexOffsets[0].SwizzleZ,&index,&ZeroVec,&offset[2]);
> + offsets[0] = offset[0].i[0];
> + offsets[1] = offset[1].i[0];
> + offsets[2] = offset[2].i[0];
> + } else
> + offsets[0] = offsets[1] = offsets[2] = 0;
This block of code seems to be repeated several times. Can it be put
into a helper function like get_texel_offsets()?
>
> switch (mach->SamplerViews[resource_unit].Resource) {
> case TGSI_TEXTURE_1D:
> FETCH(&r[0], 0, TGSI_CHAN_X);
>
> + fetch_assign_deriv_channel(mach, inst, 3, TGSI_CHAN_X, derivs[0]);
> +
> fetch_texel(mach->Sampler, resource_unit, sampler_unit,
> &r[0],&ZeroVec,&ZeroVec,&ZeroVec,&ZeroVec, /* S, T, P, C, LOD */
> - tgsi_sampler_lod_none,
> + derivs, offsets, tgsi_sampler_derivs_explicit,
> &r[0],&r[1],&r[2],&r[3]); /* R, G, B, A */
> break;
>
> @@ -2278,9 +2400,12 @@ exec_sample_d(struct tgsi_exec_machine *mach,
> FETCH(&r[0], 0, TGSI_CHAN_X);
> FETCH(&r[1], 0, TGSI_CHAN_Y);
>
> + fetch_assign_deriv_channel(mach, inst, 3, TGSI_CHAN_X, derivs[0]);
> + fetch_assign_deriv_channel(mach, inst, 3, TGSI_CHAN_Y, derivs[1]);
> +
> fetch_texel(mach->Sampler, resource_unit, sampler_unit,
> &r[0],&r[1],&ZeroVec,&ZeroVec,&ZeroVec, /* inputs */
> - tgsi_sampler_lod_none,
> + derivs, offsets, tgsi_sampler_derivs_explicit,
> &r[0],&r[1],&r[2],&r[3]); /* outputs */
> break;
>
> @@ -2290,9 +2415,13 @@ exec_sample_d(struct tgsi_exec_machine *mach,
> FETCH(&r[1], 0, TGSI_CHAN_Y);
> FETCH(&r[2], 0, TGSI_CHAN_Z);
>
> + fetch_assign_deriv_channel(mach, inst, 3, TGSI_CHAN_X, derivs[0]);
> + fetch_assign_deriv_channel(mach, inst, 3, TGSI_CHAN_Y, derivs[1]);
> + fetch_assign_deriv_channel(mach, inst, 3, TGSI_CHAN_Z, derivs[2]);
> +
> fetch_texel(mach->Sampler, resource_unit, sampler_unit,
> &r[0],&r[1],&r[2],&ZeroVec,&ZeroVec,
> - tgsi_sampler_lod_none,
> + derivs, offsets, tgsi_sampler_derivs_explicit,
> &r[0],&r[1],&r[2],&r[3]);
> break;
>
> @@ -2302,9 +2431,13 @@ exec_sample_d(struct tgsi_exec_machine *mach,
> FETCH(&r[2], 0, TGSI_CHAN_Z);
> FETCH(&r[3], 0, TGSI_CHAN_W);
>
> + fetch_assign_deriv_channel(mach, inst, 3, TGSI_CHAN_X, derivs[0]);
> + fetch_assign_deriv_channel(mach, inst, 3, TGSI_CHAN_Y, derivs[1]);
> + fetch_assign_deriv_channel(mach, inst, 3, TGSI_CHAN_Z, derivs[2]);
> +
> fetch_texel(mach->Sampler, resource_unit, sampler_unit,
> &r[0],&r[1],&r[2],&r[3],&ZeroVec,
> - tgsi_sampler_lod_none,
> + derivs, offsets, tgsi_sampler_derivs_explicit,
> &r[0],&r[1],&r[2],&r[3]);
> break;
>
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h
> index c009a97c..ef1fa82 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_exec.h
> +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h
> @@ -92,8 +92,8 @@ enum tgsi_sampler_control {
> tgsi_sampler_lod_none,
> tgsi_sampler_lod_bias,
> tgsi_sampler_lod_explicit,
> - tgsi_sampler_lod_zero
> - /* FIXME: tgsi_sampler_derivs_explicit */
> + tgsi_sampler_lod_zero,
> + tgsi_sampler_derivs_explicit
> };
>
> /**
> @@ -108,10 +108,12 @@ struct tgsi_sampler
> * s - the first texture coordinate for sampling.
> * t - the second texture coordinate for sampling - unused for 1D,
> layer for 1D arrays.
> - * p - the third coordinate for sampling for 3D, cube, cube arrays,
> + * r - the third coordinate for sampling for 3D, cube, cube arrays,
> * layer for 2D arrays. Compare value for 1D/2D shadows.
> * c0 - Compare value for shadow cube and shadow 2d arrays,
> * layer for cube arrays.
> + * derivs - explicit derivatives.
> + * offset - texel offsets
> * lod - lod value, except for shadow cube arrays (compare value there).
> */
> void (*get_samples)(struct tgsi_sampler *sampler,
> @@ -122,6 +124,8 @@ struct tgsi_sampler
> const float r[TGSI_QUAD_SIZE],
> const float c0[TGSI_QUAD_SIZE],
> const float c1[TGSI_QUAD_SIZE],
> + float derivs[3][2][TGSI_QUAD_SIZE],
> + const int8_t offset[3],
> enum tgsi_sampler_control control,
> float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]);
> void (*get_dims)(struct tgsi_sampler *sampler,
> diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c
> index 30ecc6f..8e16ff9 100644
> --- a/src/gallium/drivers/softpipe/sp_tex_sample.c
> +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
> @@ -1645,6 +1645,8 @@ compute_lod(const struct pipe_sampler_state *sampler,
> switch (control) {
> case tgsi_sampler_lod_none:
> case tgsi_sampler_lod_zero:
> + /* XXX FIXME */
> + case tgsi_sampler_derivs_explicit:
> lod[0] = lod[1] = lod[2] = lod[3] = CLAMP(biased_lambda, min_lod, max_lod);
> break;
> case tgsi_sampler_lod_bias:
> @@ -1687,6 +1689,8 @@ compute_lambda_lod(struct sp_sampler_variant *samp,
>
> switch (control) {
> case tgsi_sampler_lod_none:
> + /* XXX FIXME */
> + case tgsi_sampler_derivs_explicit:
> 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;
> @@ -2085,7 +2089,9 @@ mip_filter_linear_aniso(struct sp_sampler_variant *samp,
> float dvdy = (t[QUAD_TOP_LEFT] - t[QUAD_BOTTOM_LEFT]) * t_to_v;
>
> if (control == tgsi_sampler_lod_bias ||
> - control == tgsi_sampler_lod_none) {
> + control == tgsi_sampler_lod_none ||
> + /* XXX FIXME */
> + control == tgsi_sampler_derivs_explicit) {
> /* note: instead of working with Px and Py, we will use the
> * squared length instead, to avoid sqrt.
> */
> @@ -3051,6 +3057,8 @@ sp_tgsi_get_samples(struct tgsi_sampler *tgsi_sampler,
> const float p[TGSI_QUAD_SIZE],
> const float c0[TGSI_QUAD_SIZE],
> const float lod[TGSI_QUAD_SIZE],
> + float derivs[3][2][TGSI_QUAD_SIZE],
> + const int8_t offset[3],
> enum tgsi_sampler_control control,
> float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
> {
More information about the mesa-dev
mailing list