Am 07.05.2013 12:21, schrieb Chia-I Wu: > Make use of tgsi_util_get_texture_coord_dim() to replace the big switch table. > > There is a subtle difference with this change. When TXP is used with an array > texture, the layer is now also projected. This behavior matches the TGSI doc. > Since GLSL does not allow TXP on an array texture, I am not sure which > behavior is correct or preferred. > > Signed-off-by: Chia-I Wu <olva...@gmail.com> > --- > src/gallium/auxiliary/tgsi/tgsi_exec.c | 220 > ++++++++------------------------ > 1 file changed, 52 insertions(+), 168 deletions(-) > > diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c > b/src/gallium/auxiliary/tgsi/tgsi_exec.c > index 75b0663..cb66a40 100644 > --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c > +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c > @@ -1780,201 +1780,85 @@ exec_tex(struct tgsi_exec_machine *mach, > uint modifier, uint sampler) > { > const uint unit = inst->Src[sampler].Register.Index; > - union tgsi_exec_channel r[4], cubearraycomp, cubelod; > - const union tgsi_exec_channel *lod = &ZeroVec; > + const union tgsi_exec_channel *args[5], *proj = NULL; > + union tgsi_exec_channel r[5]; > enum tgsi_sampler_control control = tgsi_sampler_lod_none; > uint chan; > int8_t offsets[3]; > + int dim, shadow_ref, i; > > /* always fetch all 3 offsets, overkill but keeps code simple */ > fetch_texel_offsets(mach, inst, offsets); > > 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) { > - lod = &r[3]; > - } > - } > - > - if (modifier == TEX_MODIFIER_EXPLICIT_LOD) { > - control = tgsi_sampler_lod_explicit; > - } else if (modifier == TEX_MODIFIER_LOD_BIAS){ > - control = tgsi_sampler_lod_bias; > - } > - > - switch (inst->Texture.Texture) { > - case TGSI_TEXTURE_1D: > - FETCH(&r[0], 0, TGSI_CHAN_X); > - > - if (modifier == TEX_MODIFIER_PROJECTED) { > - micro_div(&r[0], &r[0], &r[3]); > - } > - > - fetch_texel(mach->Sampler, unit, unit, > - &r[0], &ZeroVec, &ZeroVec, &ZeroVec, lod, /* S, T, P, C, > LOD */ > - 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 > */ > - 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]); > - } > + dim = tgsi_util_get_texture_coord_dim(inst->Texture.Texture, &shadow_ref); > > - 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; > + assert(dim <= 4); > + if (shadow_ref >= 0) > + assert(shadow_ref >= dim && shadow_ref < Elements(args)); > > - case TGSI_TEXTURE_SHADOW2D: > - case TGSI_TEXTURE_SHADOWRECT: > - FETCH(&r[0], 0, TGSI_CHAN_X); > - FETCH(&r[1], 0, TGSI_CHAN_Y); > - FETCH(&r[2], 0, TGSI_CHAN_Z); > + /* fetch modifier to the last argument */ > + if (modifier != TEX_MODIFIER_NONE) { > + const int last = Elements(args) - 1; > > - 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 modifier from src0.w or src1.x */ > + if (sampler == 1) { > + assert(dim <= TGSI_CHAN_W && shadow_ref != TGSI_CHAN_W); > + FETCH(&r[last], 0, TGSI_CHAN_W); > } > - > - fetch_texel(mach->Sampler, unit, unit, > - &r[0], &r[1], &r[2], &ZeroVec, lod, /* S, T, P, C, LOD > */ > - NULL, offsets, control, > - &r[0], &r[1], &r[2], &r[3]); /* outputs */ > - break; > - > - case TGSI_TEXTURE_1D_ARRAY: > - 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]); > + else { > + assert(shadow_ref != 4); > + FETCH(&r[last], 1, TGSI_CHAN_X); > } > > - 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_SHADOW1D_ARRAY: > - FETCH(&r[0], 0, TGSI_CHAN_X); > - 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[2], &r[2], &r[3]); > + if (modifier != TEX_MODIFIER_PROJECTED) { > + args[last] = &r[last]; > } > - > - fetch_texel(mach->Sampler, unit, unit, > - &r[0], &r[1], &r[2], &ZeroVec, lod, /* S, T, P, C, LOD */ > - NULL, offsets, control, > - &r[0], &r[1], &r[2], &r[3]); /* outputs */ > - break; > - > - case TGSI_TEXTURE_2D_ARRAY: > - FETCH(&r[0], 0, TGSI_CHAN_X); > - 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]); > + else { > + proj = &r[last]; > + args[last] = &ZeroVec; > } > > - fetch_texel(mach->Sampler, unit, unit, > - &r[0], &r[1], &r[2], &ZeroVec, lod, /* S, T, P, C, LOD */ > - NULL, offsets, control, > - &r[0], &r[1], &r[2], &r[3]); /* outputs */ > - break; > - case TGSI_TEXTURE_SHADOW2D_ARRAY: > - case TGSI_TEXTURE_SHADOWCUBE: > - 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_texel(mach->Sampler, unit, unit, > - &r[0], &r[1], &r[2], &r[3], &ZeroVec, /* S, T, P, C, > LOD */ > - NULL, offsets, control, > - &r[0], &r[1], &r[2], &r[3]); /* outputs */ > - break; > - case TGSI_TEXTURE_CUBE_ARRAY: > - 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); > + /* point unused arguments to zero vector */ > + for (i = dim; i < last; i++) > + args[i] = &ZeroVec; > > - if (modifier == TEX_MODIFIER_EXPLICIT_LOD || > - modifier == TEX_MODIFIER_LOD_BIAS) > - FETCH(&cubelod, 1, TGSI_CHAN_X); > - else > - cubelod = ZeroVec; > + if (modifier == TEX_MODIFIER_EXPLICIT_LOD) > + control = tgsi_sampler_lod_explicit; > + else if (modifier == TEX_MODIFIER_LOD_BIAS) > + control = tgsi_sampler_lod_bias; > + } > + else { > + for (i = dim; i < Elements(args); i++) > + args[i] = &ZeroVec; > + } > > - fetch_texel(mach->Sampler, unit, unit, > - &r[0], &r[1], &r[2], &r[3], &cubelod, /* S, T, P, C, > LOD */ > - NULL, offsets, control, > - &r[0], &r[1], &r[2], &r[3]); /* outputs */ > - break; > - case TGSI_TEXTURE_3D: > - case TGSI_TEXTURE_CUBE: > - FETCH(&r[0], 0, TGSI_CHAN_X); > - FETCH(&r[1], 0, TGSI_CHAN_Y); > - FETCH(&r[2], 0, TGSI_CHAN_Z); > + /* fetch coordinates */ > + for (i = 0; i < dim; i++) { > + FETCH(&r[i], 0, TGSI_CHAN_X + i); > > - 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]); > - } > + if (proj) > + micro_div(&r[i], &r[i], proj); > > - fetch_texel(mach->Sampler, unit, unit, > - &r[0], &r[1], &r[2], &ZeroVec, lod, > - NULL, offsets, control, > - &r[0], &r[1], &r[2], &r[3]); > - break; > + args[i] = &r[i]; > + } > > - case TGSI_TEXTURE_SHADOWCUBE_ARRAY: > - 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 reference value */ > + if (shadow_ref >= 0) { > + FETCH(&r[shadow_ref], shadow_ref / 4, TGSI_CHAN_X + (shadow_ref % 4)); > > - FETCH(&cubearraycomp, 1, TGSI_CHAN_X); > + if (proj) > + micro_div(&r[shadow_ref], &r[shadow_ref], proj); > > - fetch_texel(mach->Sampler, unit, unit, > - &r[0], &r[1], &r[2], &r[3], &cubearraycomp, /* S, T, P, C, > LOD */ > - NULL, offsets, control, > - &r[0], &r[1], &r[2], &r[3]); /* outputs */ > - break; > - default: > - assert(0); > + args[shadow_ref] = &r[shadow_ref]; > } > > + fetch_texel(mach->Sampler, unit, unit, > + args[0], args[1], args[2], args[3], args[4], > + NULL, offsets, control, > + &r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */ > + > #if 0 > debug_printf("fetch r: %g %g %g %g\n", > r[0].f[0], r[0].f[1], r[0].f[2], r[0].f[3]); >
Provided there are no piglit regressions, series looks good to me. As for array layer projection, I wouldn't worry too much about it. GL_MESA_texture_array can do projected textures with fixed function (and hence projection) but I couldn't figure out if the layer should be projected or not. llvmpipe already does project it so it might just be correct. Roland _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev