gallium: fix tgsi SAMPLE_L opcode to use separate source for explicit lod

It looks like using coord.w as explicit lod value is a mistake, most likely
because some dx10 docs had it specified that way. Seems this was changed though:
http://msdn.microsoft.com/en-us/library/windows/desktop/hh447229%28v=vs.85%29.aspx
- let's just hope it doesn't depend on runtime build version or something.
Not only would this need translation (so go against the stated goal these
opcodes should be close to dx10 semantics) but it would prevent usage of this
opcode with cube arrays, which is apparently possible:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb509699%28v=vs.85%29.aspx
(Note not only does this show cube arrays using explicit lod, but also the
confusion with this opcode: it lists an explicit lod parameter value, but then
states last component of location is used as lod).
(For "true" hw drivers, only nv50 had code to handle it, and it appears the
code was already right for the new semantics, though fix up the seemingly
wrong c/d arguments while there.)

v2: fix comment, separate out other changes.

Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
This commit is contained in:
Roland Scheidegger
2013-02-12 16:41:56 +01:00
parent 4bfdef87e6
commit 427d36a227
7 changed files with 10 additions and 20 deletions
@@ -241,13 +241,10 @@ analyse_sample(struct analysis_context *ctx,
tex_info->sampler_unit = inst->Src[2].Register.Index;
if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV ||
modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_LOD ||
modifier == LP_BLD_TEX_MODIFIER_LOD_BIAS || shadow) {
/* We don't track insts with additional regs, although we could */
indirect = TRUE;
} else {
if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_LOD) {
readmask |= TGSI_WRITEMASK_W;
}
}
for (chan = 0; chan < 4; ++chan) {
@@ -1428,9 +1428,8 @@ emit_sample(struct lp_build_tgsi_soa_context *bld,
explicit_lod = NULL;
}
else if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_LOD) {
/* lod bias comes from src 3.r but explicit lod from 0.a */
lod_bias = NULL;
explicit_lod = lp_build_emit_fetch( &bld->bld_base, inst, 0, 3 );
explicit_lod = lp_build_emit_fetch( &bld->bld_base, inst, 3, 0 );
}
else if (modifier == LP_BLD_TEX_MODIFIER_LOD_ZERO) {
lod_bias = NULL;
+1 -1
View File
@@ -2154,7 +2154,7 @@ exec_sample(struct tgsi_exec_machine *mach,
control = tgsi_sampler_lod_bias;
}
else if (modifier == TEX_MODIFIER_EXPLICIT_LOD) {
FETCH(&c1, 0, TGSI_CHAN_W);
FETCH(&c1, 3, TGSI_CHAN_X);
lod = &c1;
control = tgsi_sampler_lod_explicit;
}
+1 -1
View File
@@ -190,7 +190,7 @@ static const struct tgsi_opcode_info opcode_info[TGSI_OPCODE_LAST] =
{ 1, 4, 0, 0, 0, 0, OTHR, "SAMPLE_C", TGSI_OPCODE_SAMPLE_C },
{ 1, 4, 0, 0, 0, 0, OTHR, "SAMPLE_C_LZ", TGSI_OPCODE_SAMPLE_C_LZ },
{ 1, 5, 0, 0, 0, 0, OTHR, "SAMPLE_D", TGSI_OPCODE_SAMPLE_D },
{ 1, 3, 0, 0, 0, 0, OTHR, "SAMPLE_L", TGSI_OPCODE_SAMPLE_L },
{ 1, 4, 0, 0, 0, 0, OTHR, "SAMPLE_L", TGSI_OPCODE_SAMPLE_L },
{ 1, 3, 0, 0, 0, 0, OTHR, "GATHER4", TGSI_OPCODE_GATHER4 },
{ 1, 2, 0, 0, 0, 0, OTHR, "SVIEWINFO", TGSI_OPCODE_SVIEWINFO },
{ 1, 2, 0, 0, 0, 0, OTHR, "SAMPLE_POS", TGSI_OPCODE_SAMPLE_POS },
+1 -1
View File
@@ -176,7 +176,7 @@ OP14(SAMPLE_B)
OP14(SAMPLE_C)
OP14(SAMPLE_C_LZ)
OP15(SAMPLE_D)
OP13(SAMPLE_L)
OP14(SAMPLE_L)
OP13(GATHER4)
OP12(SVIEWINFO)
OP13(SAMPLE_POS)
+3 -4
View File
@@ -1423,11 +1423,10 @@ instructions. If in doubt double check Direct3D documentation.
.. opcode:: SAMPLE_L - SAMPLE_L is identical to the SAMPLE opcode except
that the LOD is provided directly as a scalar value,
representing no anisotropy. Source addresses A channel
is used as the LOD.
SAMPLE_L dst, address, sampler_view, sampler
representing no anisotropy.
SAMPLE_L dst, address, sampler_view, sampler, explicit_lod
e.g.
SAMPLE_L TEMP[0], TEMP[1], SVIEW[0], SAMP[0]
SAMPLE_L TEMP[0], TEMP[1], SVIEW[0], SAMP[0], TEMP[2].x
.. opcode:: GATHER4 - Gathers the four texels to be used in a bi-linear
filtering operation and packs them into a single register.
@@ -470,14 +470,9 @@ struct sm4_to_tgsi_converter
case SM4_OPCODE_SAMPLE_D: // dst, coord, res, samp, ddx, ddy
ureg_SAMPLE_D(ureg, _dst(), _src(1), resources[_idx(SM4_FILE_RESOURCE, 2)], samplers[_idx(SM4_FILE_SAMPLER, 3)], _src(4), _src(5));
break;
case SM4_OPCODE_SAMPLE_L: // dst, coord, res, samp, bias.x
{
struct ureg_dst tmp = _tmp();
ureg_MOV(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_XYZ), _src(1));
ureg_MOV(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_W), ureg_swizzle(_src(4), 0, 0, 0, 0));
ureg_SAMPLE_L(ureg, _dst(), ureg_src(tmp), resources[_idx(SM4_FILE_RESOURCE, 2)], samplers[_idx(SM4_FILE_SAMPLER, 3)]);
case SM4_OPCODE_SAMPLE_L: // dst, coord, res, samp, lod.x
ureg_SAMPLE_L(ureg, _dst(), _src(1), resources[_idx(SM4_FILE_RESOURCE, 2)], samplers[_idx(SM4_FILE_SAMPLER, 3)], _src(4));
break;
}
default:
ok = false;
break;