diff options
author | Dave Airlie <[email protected]> | 2020-05-18 15:43:16 +1000 |
---|---|---|
committer | Marge Bot <[email protected]> | 2020-05-18 21:56:29 +0000 |
commit | 38560e0d1d0d01826cc460f5455732cda1b227bc (patch) | |
tree | 1b0e53e6a86edd7fa98648adcecee52ac1d845c0 | |
parent | ff9c95421a64a349ca70a61b1a6c9cd22198cd67 (diff) |
r600/sfn: fix cayman float instruction emission.
This is enough to get glxgears working.
Reviewed-by: Gert Wollny <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5084>
-rw-r--r-- | src/gallium/drivers/r600/sfn/sfn_emitaluinstruction.cpp | 22 | ||||
-rw-r--r-- | src/gallium/drivers/r600/sfn/sfn_ir_to_assembly.cpp | 5 |
2 files changed, 23 insertions, 4 deletions
diff --git a/src/gallium/drivers/r600/sfn/sfn_emitaluinstruction.cpp b/src/gallium/drivers/r600/sfn/sfn_emitaluinstruction.cpp index 2637c868ee9..ba84e57ac1a 100644 --- a/src/gallium/drivers/r600/sfn/sfn_emitaluinstruction.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_emitaluinstruction.cpp @@ -318,15 +318,31 @@ bool EmitAluInstruction::emit_alu_trans_op1(const nir_alu_instr& instr, EAluOp o { AluInstruction *ir = nullptr; std::set<int> src_idx; - for (int i = 0; i < 4 ; ++i) { - if (instr.dest.write_mask & (1 << i)){ + + if (get_chip_class() == CAYMAN) { + int last_slot = (instr.dest.write_mask & 0x8) ? 4 : 3; + for (int i = 0; i < last_slot; ++i) { ir = new AluInstruction(opcode, from_nir(instr.dest, i), - from_nir(instr.src[0], i), last_write); + from_nir(instr.src[0], 0), instr.dest.write_mask & (1 << i) ? write : empty); if (absolute || instr.src[0].abs) ir->set_flag(alu_src0_abs); if (instr.src[0].negate) ir->set_flag(alu_src0_neg); if (instr.dest.saturate) ir->set_flag(alu_dst_clamp); + + if (i == (last_slot - 1)) ir->set_flag(alu_last_instr); + emit_instruction(ir); } + } else { + for (int i = 0; i < 4 ; ++i) { + if (instr.dest.write_mask & (1 << i)){ + ir = new AluInstruction(opcode, from_nir(instr.dest, i), + from_nir(instr.src[0], i), last_write); + if (absolute || instr.src[0].abs) ir->set_flag(alu_src0_abs); + if (instr.src[0].negate) ir->set_flag(alu_src0_neg); + if (instr.dest.saturate) ir->set_flag(alu_dst_clamp); + emit_instruction(ir); + } + } } return true; } diff --git a/src/gallium/drivers/r600/sfn/sfn_ir_to_assembly.cpp b/src/gallium/drivers/r600/sfn/sfn_ir_to_assembly.cpp index 9794057df93..6bb6486eb92 100644 --- a/src/gallium/drivers/r600/sfn/sfn_ir_to_assembly.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_ir_to_assembly.cpp @@ -145,7 +145,10 @@ bool AssemblyFromShaderLegacy::do_lower(const std::vector<InstructionBlock>& ir) else if (impl->m_bc->cf_last->op == CF_OP_CALL_FS) impl->m_bc->cf_last->op = CF_OP_NOP; - impl->m_bc->cf_last->end_of_program = 1; + if (impl->m_shader->bc.chip_class != CAYMAN) + impl->m_bc->cf_last->end_of_program = 1; + else + cm_bytecode_add_cf_end(impl->m_bc); return true; } |