From: Ben Skeggs Date: Sat, 7 Jun 2008 06:08:36 +0000 (+1000) Subject: nv50: POW! X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ea4b09cbcbd9db82648ab30f18c0f46a66ab9f69;p=mesa.git nv50: POW! --- diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 9fcd7c36c61..79893a9ad4f 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -14,15 +14,17 @@ /* ARL * LIT - other buggery - * POW * * MSB - Like MAD, but MUL+SUB * - Fuck it off, introduce a way to negate args for ops that * support it. * - * Look into inlining IMMD for ops other than MOV + * Look into inlining IMMD for ops other than MOV (make it general?) * - Maybe even relax restrictions a bit, can't do P_RESULT + P_IMMD, * but can emit to P_TEMP first - then MOV later. NVIDIA does this + * + * Verify half-insns work where expected - and force disable them where they + * don't work - MUL has it forcibly disabled atm as it fixes POW.. */ struct nv50_reg { enum { @@ -489,6 +491,7 @@ emit_mul(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0, unsigned inst[2] = { 0, 0 }; inst[0] |= 0xc0000000; + set_long(pc, inst); check_swap_src_0_1(pc, &src0, &src1); set_dst(pc, dst, inst); @@ -870,6 +873,19 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) emit_mul(pc, dst[c], src[0][c], src[1][c]); } break; + case TGSI_OPCODE_POW: + temp = alloc_temp(pc, NULL); + emit_flop(pc, 3, temp, src[0][0]); + emit_mul(pc, temp, temp, src[1][0]); + emit_preex2(pc, temp, temp); + emit_flop(pc, 6, temp, temp); + for (c = 0; c < 4; c++) { + if (!(mask & (1 << c))) + continue; + emit_mov(pc, dst[c], temp); + } + free_temp(pc, temp); + break; case TGSI_OPCODE_RCP: for (c = 0; c < 4; c++) { if (!(mask & (1 << c)))