From 3cb753eeb104ff7bc7f7158d23e7046ee0bf6c04 Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 9 Jun 2018 15:56:50 -0500 Subject: [PATCH 1/2] GPU: Added decodings for the ISET family of instructions. --- src/video_core/engines/shader_bytecode.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index d748026b8c..9f17225f81 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h @@ -487,6 +487,9 @@ public: ISETP_C, ISETP_IMM, ISETP_R, + ISET_R, + ISET_C, + ISET_IMM, PSETP, XMAD_IMM, XMAD_CR, @@ -506,6 +509,7 @@ public: Memory, FloatSet, FloatSetPredicate, + IntegerSet, IntegerSetPredicate, PredicateSetPredicate, Conversion, @@ -677,6 +681,9 @@ private: INST("010010110110----", Id::ISETP_C, Type::IntegerSetPredicate, "ISETP_C"), INST("010110110110----", Id::ISETP_R, Type::IntegerSetPredicate, "ISETP_R"), INST("0011011-0110----", Id::ISETP_IMM, Type::IntegerSetPredicate, "ISETP_IMM"), + INST("010110110101----", Id::ISET_R, Type::IntegerSet, "ISET_R"), + INST("010010110101----", Id::ISET_C, Type::IntegerSet, "ISET_C"), + INST("0011011-0101----", Id::ISET_IMM, Type::IntegerSet, "ISET_IMM"), INST("0101000010010---", Id::PSETP, Type::PredicateSetPredicate, "PSETP"), INST("0011011-00------", Id::XMAD_IMM, Type::Arithmetic, "XMAD_IMM"), INST("0100111---------", Id::XMAD_CR, Type::Arithmetic, "XMAD_CR"), From b366b885a13623e13afba36e52765d949bb05766 Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 9 Jun 2018 16:19:13 -0500 Subject: [PATCH 2/2] GPU: Implement the iset family of shader instructions. --- src/video_core/engines/shader_bytecode.h | 9 +++++ .../renderer_opengl/gl_shader_decompiler.cpp | 39 ++++++++++++++++++- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 9f17225f81..ec8dbd370b 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h @@ -329,6 +329,15 @@ union Instruction { BitField<56, 1, u64> neg_imm; } fset; + union { + BitField<39, 3, u64> pred39; + BitField<42, 1, u64> neg_pred; + BitField<44, 1, u64> bf; + BitField<45, 2, PredOperation> op; + BitField<48, 1, u64> is_signed; + BitField<49, 3, PredCondition> cond; + } iset; + union { BitField<10, 2, Register::Size> size; BitField<12, 1, u64> is_output_signed; diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 37fbb94daa..8521be4a19 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -1423,8 +1423,8 @@ private: op_b = "abs(" + op_b + ')'; } - // The fset instruction sets a register to 1.0 if the condition is true, and to 0 - // otherwise. + // The fset instruction sets a register to 1.0 or -1 (depending on the bf bit) if the + // condition is true, and to 0 otherwise. std::string second_pred = GetPredicateCondition(instr.fset.pred39, instr.fset.neg_pred != 0); @@ -1442,6 +1442,41 @@ private: } break; } + case OpCode::Type::IntegerSet: { + std::string op_a = regs.GetRegisterAsInteger(instr.gpr8, 0, instr.iset.is_signed); + + std::string op_b; + + if (instr.is_b_imm) { + op_b = std::to_string(instr.alu.GetSignedImm20_20()); + } else { + if (instr.is_b_gpr) { + op_b = regs.GetRegisterAsInteger(instr.gpr20, 0, instr.iset.is_signed); + } else { + op_b = regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset, + GLSLRegister::Type::Integer); + } + } + + // The iset instruction sets a register to 1.0 or -1 (depending on the bf bit) if the + // condition is true, and to 0 otherwise. + std::string second_pred = + GetPredicateCondition(instr.iset.pred39, instr.iset.neg_pred != 0); + + std::string comparator = GetPredicateComparison(instr.iset.cond); + std::string combiner = GetPredicateCombiner(instr.iset.op); + + std::string predicate = "(((" + op_a + ") " + comparator + " (" + op_b + ")) " + + combiner + " (" + second_pred + "))"; + + if (instr.iset.bf) { + regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1); + } else { + regs.SetRegisterToInteger(instr.gpr0, false, 0, predicate + " ? 0xFFFFFFFF : 0", 1, + 1); + } + break; + } default: { switch (opcode->GetId()) { case OpCode::Id::EXIT: {