diff options
Diffstat (limited to 'src/gallium/auxiliary/tgsi')
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_exec.c | 48 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_info_opcodes.h | 1 |
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) |