[Mesa-dev] [PATCH] tgsi: add texel offsets and derivatives to sampler interface
Roland Scheidegger
sroland at vmware.com
Fri Mar 1 12:40:49 PST 2013
Am 01.03.2013 19:54, schrieb Brian Paul:
> 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?
Yes sounds good. After all we could get more if someone tries some
advanced gather at some point.
>
>
>> + 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:
Yes.
>
>> +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()?
I blame lazy copy&paste :-). But you are certainly right it was repeated
5 times.
(FWIW it isn't really optimized as it always fetches all 3 offsets
regardless the texture dimension. Could be improved but that way needs
less code for this probably not often used feature.)
>
>>
>> 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])
>> {
Roland
More information about the mesa-dev
mailing list