diff options
author | Christoph Bumiller <[email protected]> | 2010-08-17 11:51:51 +0200 |
---|---|---|
committer | Christoph Bumiller <[email protected]> | 2010-08-17 13:08:52 +0200 |
commit | ce1629564d1cce80b2762d266640e3181a68e848 (patch) | |
tree | 56b18f99238ad4deb78d3f0247d6db3866255826 /src/gallium/drivers/nv50 | |
parent | 62f933a6f617050a267079b27360eaae2d0e1a70 (diff) |
nv50: more TGSI opcodes (SIN, SCS, ARL, RET, KILP)
Diffstat (limited to 'src/gallium/drivers/nv50')
-rw-r--r-- | src/gallium/drivers/nv50/nv50_pc_emit.c | 22 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_pc_optimize.c | 13 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_tgsi_to_nc.c | 38 |
3 files changed, 63 insertions, 10 deletions
diff --git a/src/gallium/drivers/nv50/nv50_pc_emit.c b/src/gallium/drivers/nv50/nv50_pc_emit.c index 3a3b277c139..b5f4383aa1a 100644 --- a/src/gallium/drivers/nv50/nv50_pc_emit.c +++ b/src/gallium/drivers/nv50/nv50_pc_emit.c @@ -748,8 +748,30 @@ emit_bitop2(struct nv_pc *pc, struct nv_instruction *i) } static void +emit_arl(struct nv_pc *pc, struct nv_instruction *i) +{ + assert(SFILE(i, 0) == NV_FILE_GPR); + assert(SFILE(i, 1) == NV_FILE_IMM); + + assert(!i->flags_def); + + pc->emit[0] = 0x00000001; + pc->emit[1] = 0xc0000000; + + set_dst(pc, i->def[0]); + set_pred(pc, i); + set_src_0(pc, i->src[0]); + pc->emit[0] |= (get_immd_u32(i->src[1]) & 0x3f) << 16; +} + +static void emit_shift(struct nv_pc *pc, struct nv_instruction *i) { + if (DFILE(i, 0) == NV_FILE_ADDR) { + emit_arl(pc, i); + return; + } + pc->emit[0] = 0x30000001; pc->emit[1] = 0xc4000000; diff --git a/src/gallium/drivers/nv50/nv50_pc_optimize.c b/src/gallium/drivers/nv50/nv50_pc_optimize.c index b35dd728417..3e6e09a904f 100644 --- a/src/gallium/drivers/nv50/nv50_pc_optimize.c +++ b/src/gallium/drivers/nv50/nv50_pc_optimize.c @@ -293,14 +293,15 @@ check_swap_src_0_1(struct nv_instruction *nvi) static int nv_pass_fold_stores(struct nv_pass *ctx, struct nv_basic_block *b) { - struct nv_instruction *nvi, *sti; + struct nv_instruction *nvi, *sti, *next; int j; - for (sti = b->entry; sti; sti = sti->next) { - if (!sti->def[0] || sti->def[0]->reg.file != NV_FILE_OUT) - continue; + for (sti = b->entry; sti; sti = next) { + next = sti->next; /* only handling MOV to $oX here */ + if (!sti->def[0] || sti->def[0]->reg.file != NV_FILE_OUT) + continue; if (sti->opcode != NV_OP_MOV && sti->opcode != NV_OP_STA) continue; @@ -320,9 +321,9 @@ nv_pass_fold_stores(struct nv_pass *ctx, struct nv_basic_block *b) continue; nvi->def[0] = sti->def[0]; - sti->def[0] = NULL; nvi->fixed = sti->fixed; - sti->fixed = 0; + + nv_nvi_delete(sti); } DESCEND_ARBITRARY(j, nv_pass_fold_stores); diff --git a/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c b/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c index d6c5a8d6606..dafff725b8f 100644 --- a/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c +++ b/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c @@ -685,6 +685,8 @@ translate_opcode(uint opcode) case TGSI_OPCODE_CEIL: return NV_OP_CEIL; case TGSI_OPCODE_FLR: return NV_OP_FLOOR; case TGSI_OPCODE_TRUNC: return NV_OP_TRUNC; + case TGSI_OPCODE_COS: return NV_OP_COS; + case TGSI_OPCODE_SIN: return NV_OP_SIN; case TGSI_OPCODE_DDX: return NV_OP_DFDX; case TGSI_OPCODE_DDY: return NV_OP_DFDY; case TGSI_OPCODE_F2I: @@ -1226,6 +1228,14 @@ bld_instruction(struct bld_context *bld, dst0[c] = bld_insn_2(bld, opcode, src0, src1); } break; + case TGSI_OPCODE_ARL: + src1 = bld_imm_u32(bld, 4); + FOR_EACH_DST0_ENABLED_CHANNEL(c, insn) { + src0 = emit_fetch(bld, insn, 0, c); + (temp = bld_insn_1(bld, NV_OP_FLOOR, temp))->reg.type = NV_TYPE_S32; + dst0[c] = bld_insn_2(bld, NV_OP_SHL, temp, src1); + } + break; case TGSI_OPCODE_CMP: FOR_EACH_DST0_ENABLED_CHANNEL(c, insn) { src0 = emit_fetch(bld, insn, 0, c); @@ -1245,19 +1255,19 @@ bld_instruction(struct bld_context *bld, } break; case TGSI_OPCODE_COS: + case TGSI_OPCODE_SIN: src0 = emit_fetch(bld, insn, 0, 0); temp = bld_insn_1(bld, NV_OP_PRESIN, src0); if (insn->Dst[0].Register.WriteMask & 7) - temp = bld_insn_1(bld, NV_OP_COS, temp); + temp = bld_insn_1(bld, opcode, temp); for (c = 0; c < 3; ++c) if (insn->Dst[0].Register.WriteMask & (1 << c)) dst0[c] = temp; if (!(insn->Dst[0].Register.WriteMask & (1 << 3))) break; - /* XXX: if src0.x is src0.w, don't emit new insns */ src0 = emit_fetch(bld, insn, 0, 3); temp = bld_insn_1(bld, NV_OP_PRESIN, src0); - dst0[3] = bld_insn_1(bld, NV_OP_COS, temp); + dst0[3] = bld_insn_1(bld, opcode, temp); break; case TGSI_OPCODE_DP3: src0 = emit_fetch(bld, insn, 0, 0); @@ -1303,6 +1313,9 @@ bld_instruction(struct bld_context *bld, bld_kil(bld, src0); } break; + case TGSI_OPCODE_KILP: + (new_instruction(bld->pc, NV_OP_KIL))->fixed = 1; + break; case TGSI_OPCODE_IF: { struct nv_basic_block *b = new_basic_block(bld->pc); @@ -1496,6 +1509,20 @@ bld_instruction(struct bld_context *bld, dst0[c]->reg.type = NV_TYPE_F32; } break; + case TGSI_OPCODE_SCS: + if (insn->Dst[0].Register.WriteMask & 0x3) { + src0 = emit_fetch(bld, insn, 0, 0); + temp = bld_insn_1(bld, NV_OP_PRESIN, src0); + if (insn->Dst[0].Register.WriteMask & 0x1) + dst0[0] = bld_insn_1(bld, NV_OP_COS, temp); + if (insn->Dst[0].Register.WriteMask & 0x2) + dst0[1] = bld_insn_1(bld, NV_OP_SIN, temp); + } + if (insn->Dst[0].Register.WriteMask & 0x4) + dst0[2] = bld_imm_f32(bld, 0.0f); + if (insn->Dst[0].Register.WriteMask & 0x8) + dst0[3] = bld_imm_f32(bld, 1.0f); + break; case TGSI_OPCODE_SUB: FOR_EACH_DST0_ENABLED_CHANNEL(c, insn) { src0 = emit_fetch(bld, insn, 0, c); @@ -1527,12 +1554,15 @@ bld_instruction(struct bld_context *bld, dst0[c]->insn->src[2]->mod ^= NV_MOD_NEG; } break; + case TGSI_OPCODE_RET: + (new_instruction(bld->pc, NV_OP_RET))->fixed = 1; + break; case TGSI_OPCODE_END: if (bld->ti->p->type == PIPE_SHADER_FRAGMENT) bld_export_outputs(bld); break; default: - NOUVEAU_ERR("nv_bld: unhandled opcode %u\n", insn->Instruction.Opcode); + NOUVEAU_ERR("unhandled opcode %u\n", insn->Instruction.Opcode); abort(); break; } |