[Mesa-dev] [PATCH 2/2] tgsi: clean up exec_tex()
Roland Scheidegger
sroland at vmware.com
Tue May 7 05:51:59 PDT 2013
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 <olvaffe at 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
More information about the mesa-dev
mailing list