|
|
@@ -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]); |