diff options
Diffstat (limited to 'src/gallium/auxiliary/tgsi/tgsi_exec.c')
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_exec.c | 100 |
1 files changed, 97 insertions, 3 deletions
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index 712e8aca794..38dc1efa551 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -1594,6 +1594,9 @@ store_dest(struct tgsi_exec_machine *mach, #define FETCH(VAL,INDEX,CHAN)\ fetch_source(mach, VAL, &inst->Src[INDEX], CHAN, TGSI_EXEC_DATA_FLOAT) +#define IFETCH(VAL,INDEX,CHAN)\ + fetch_source(mach, VAL, &inst->Src[INDEX], CHAN, TGSI_EXEC_DATA_INT) + /** * Execute ARB-style KIL which is predicated by a src register. @@ -1921,6 +1924,86 @@ exec_txd(struct tgsi_exec_machine *mach, } +static void +exec_txf(struct tgsi_exec_machine *mach, + const struct tgsi_full_instruction *inst) +{ + struct tgsi_sampler *sampler; + const uint unit = inst->Src[1].Register.Index; + union tgsi_exec_channel r[4]; + uint chan; + float rgba[NUM_CHANNELS][QUAD_SIZE]; + int j; + + IFETCH(&r[3], 0, CHAN_W); + + switch(inst->Texture.Texture) { + case TGSI_TEXTURE_3D: + case TGSI_TEXTURE_2D_ARRAY: + IFETCH(&r[2], 0, CHAN_Z); + /* fallthrough */ + case TGSI_TEXTURE_2D: + case TGSI_TEXTURE_RECT: + case TGSI_TEXTURE_SHADOW2D: + case TGSI_TEXTURE_SHADOWRECT: + case TGSI_TEXTURE_1D_ARRAY: + IFETCH(&r[1], 0, CHAN_Y); + /* fallthrough */ + case TGSI_TEXTURE_1D: + case TGSI_TEXTURE_SHADOW1D: + IFETCH(&r[0], 0, CHAN_X); + break; + default: + assert(0); + break; + } + + sampler = mach->Samplers[unit]; + sampler->get_texel(sampler, r[0].i, r[1].i, r[2].i, r[3].i, rgba); + + for (j = 0; j < QUAD_SIZE; j++) { + r[0].f[j] = rgba[0][j]; + r[1].f[j] = rgba[1][j]; + r[2].f[j] = rgba[2][j]; + r[3].f[j] = rgba[3][j]; + } + + for (chan = 0; chan < NUM_CHANNELS; chan++) { + if (inst->Dst[0].Register.WriteMask & (1 << chan)) { + store_dest(mach, &r[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT); + } + } +} + +static void +exec_txq(struct tgsi_exec_machine *mach, + const struct tgsi_full_instruction *inst) +{ + struct tgsi_sampler *sampler; + const uint unit = inst->Src[1].Register.Index; + int result[4]; + union tgsi_exec_channel r[4], src; + uint chan; + int i,j; + + fetch_source(mach, &src, &inst->Src[0], CHAN_X, TGSI_EXEC_DATA_INT); + sampler = mach->Samplers[unit]; + + sampler->get_dims(sampler, src.i[0], result); + + for (i = 0; i < QUAD_SIZE; i++) { + for (j = 0; j < 4; j++) { + r[j].i[i] = result[j]; + } + } + + for (chan = 0; chan < NUM_CHANNELS; chan++) { + if (inst->Dst[0].Register.WriteMask & (1 << chan)) { + store_dest(mach, &r[chan], &inst->Dst[0], inst, chan, + TGSI_EXEC_DATA_INT); + } + } +} static void exec_sample(struct tgsi_exec_machine *mach, @@ -2989,6 +3072,17 @@ micro_xor(union tgsi_exec_channel *dst, } static void +micro_mod(union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1) +{ + dst->i[0] = src0->i[0] % src1->i[0]; + dst->i[1] = src0->i[1] % src1->i[1]; + dst->i[2] = src0->i[2] % src1->i[2]; + dst->i[3] = src0->i[3] % src1->i[3]; +} + +static void micro_f2i(union tgsi_exec_channel *dst, const union tgsi_exec_channel *src) { @@ -3691,7 +3785,7 @@ exec_instruction( break; case TGSI_OPCODE_MOD: - assert (0); + exec_vector_binary(mach, inst, micro_mod, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT); break; case TGSI_OPCODE_XOR: @@ -3703,11 +3797,11 @@ exec_instruction( break; case TGSI_OPCODE_TXF: - assert (0); + exec_txf(mach, inst); break; case TGSI_OPCODE_TXQ: - assert (0); + exec_txq(mach, inst); break; case TGSI_OPCODE_EMIT: |