summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary/tgsi
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary/tgsi')
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.c48
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_info_opcodes.h1
2 files changed, 45 insertions, 4 deletions
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index 9c019a311d7..afed96c9b1d 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -2351,15 +2351,22 @@ static void
exec_lodq(struct tgsi_exec_machine *mach,
const struct tgsi_full_instruction *inst)
{
- uint unit;
+ uint resource_unit, sampler_unit;
int dim;
int i;
union tgsi_exec_channel coords[4];
const union tgsi_exec_channel *args[ARRAY_SIZE(coords)];
union tgsi_exec_channel r[2];
- unit = fetch_sampler_unit(mach, inst, 1);
- dim = tgsi_util_get_texture_coord_dim(inst->Texture.Texture);
+ resource_unit = fetch_sampler_unit(mach, inst, 1);
+ if (inst->Instruction.Opcode == TGSI_OPCODE_LOD) {
+ uint target = mach->SamplerViews[resource_unit].Resource;
+ dim = tgsi_util_get_texture_coord_dim(target);
+ sampler_unit = fetch_sampler_unit(mach, inst, 2);
+ } else {
+ dim = tgsi_util_get_texture_coord_dim(inst->Texture.Texture);
+ sampler_unit = resource_unit;
+ }
assert(dim <= ARRAY_SIZE(coords));
/* fetch coordinates */
for (i = 0; i < dim; i++) {
@@ -2369,7 +2376,7 @@ exec_lodq(struct tgsi_exec_machine *mach,
for (i = dim; i < ARRAY_SIZE(coords); i++) {
args[i] = &ZeroVec;
}
- mach->Sampler->query_lod(mach->Sampler, unit, unit,
+ mach->Sampler->query_lod(mach->Sampler, resource_unit, sampler_unit,
args[0]->f,
args[1]->f,
args[2]->f,
@@ -2386,6 +2393,35 @@ exec_lodq(struct tgsi_exec_machine *mach,
store_dest(mach, &r[1], &inst->Dst[0], inst, TGSI_CHAN_Y,
TGSI_EXEC_DATA_FLOAT);
}
+ if (inst->Instruction.Opcode == TGSI_OPCODE_LOD) {
+ unsigned char swizzles[4];
+ unsigned chan;
+ swizzles[0] = inst->Src[1].Register.SwizzleX;
+ swizzles[1] = inst->Src[1].Register.SwizzleY;
+ swizzles[2] = inst->Src[1].Register.SwizzleZ;
+ swizzles[3] = inst->Src[1].Register.SwizzleW;
+
+ for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
+ if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+ if (swizzles[chan] >= 2) {
+ store_dest(mach, &ZeroVec,
+ &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
+ } else {
+ store_dest(mach, &r[swizzles[chan]],
+ &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
+ }
+ }
+ }
+ } else {
+ if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) {
+ store_dest(mach, &r[0], &inst->Dst[0], inst, TGSI_CHAN_X,
+ TGSI_EXEC_DATA_FLOAT);
+ }
+ if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) {
+ store_dest(mach, &r[1], &inst->Dst[0], inst, TGSI_CHAN_Y,
+ TGSI_EXEC_DATA_FLOAT);
+ }
+ }
}
static void
@@ -5718,6 +5754,10 @@ exec_instruction(
assert(0);
break;
+ case TGSI_OPCODE_LOD:
+ exec_lodq(mach, inst);
+ break;
+
case TGSI_OPCODE_UARL:
exec_vector_unary(mach, inst, micro_uarl, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_UINT);
break;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_info_opcodes.h b/src/gallium/auxiliary/tgsi/tgsi_info_opcodes.h
index fdb0f1078a1..1b2803cf3fe 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_info_opcodes.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_info_opcodes.h
@@ -249,3 +249,4 @@ OPCODE(1, 2, COMP, U64DIV)
OPCODE(1, 2, COMP, I64MOD)
OPCODE(1, 2, COMP, U64MOD)
OPCODE(1, 2, COMP, DDIV)
+OPCODE(1, 3, OTHR, LOD)