Am 01.03.2013 19:54, schrieb Brian Paul: > Looks good, just minor things below. > > Reviewed-by: Brian Paul <bri...@vmware.com> > > On 03/01/2013 11:41 AM, srol...@vmware.com wrote: >> From: Roland Scheidegger<srol...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev