From 8e8326595f7ad5bf6b2d7ac1110504f97f7b3138 Mon Sep 17 00:00:00 2001 From: Laku Date: Wed, 22 Aug 2018 10:02:18 +0300 Subject: [PATCH 1/4] implement lop3 --- src/video_core/engines/shader_bytecode.h | 19 ++++++++++ .../renderer_opengl/gl_shader_decompiler.cpp | 36 +++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 67194b0e3..a36df65f9 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h @@ -280,6 +280,19 @@ union Instruction { BitField<56, 1, u64> invert_b; } lop32i; + union { + BitField<28, 8, u64> imm_lut28; + BitField<48, 8, u64> imm_lut48; + + u32 GetImmLut28() const { + return static_cast(imm_lut28); + } + + u32 GetImmLut48() const { + return static_cast(imm_lut48); + } + } lop3; + u32 GetImm20_19() const { u32 imm{static_cast(imm20_19)}; imm <<= 12; @@ -650,6 +663,9 @@ public: LOP_R, LOP_IMM, LOP32I, + LOP3_C, + LOP3_R, + LOP3_IMM, MOV_C, MOV_R, MOV_IMM, @@ -872,6 +888,9 @@ private: INST("0101110001000---", Id::LOP_R, Type::ArithmeticInteger, "LOP_R"), INST("0011100001000---", Id::LOP_IMM, Type::ArithmeticInteger, "LOP_IMM"), INST("000001----------", Id::LOP32I, Type::ArithmeticIntegerImmediate, "LOP32I"), + INST("0000001---------", Id::LOP3_C, Type::ArithmeticInteger, "LOP3_C"), + INST("0101101111100---", Id::LOP3_R, Type::ArithmeticInteger, "LOP3_R"), + INST("0011110---------", Id::LOP3_IMM, Type::ArithmeticInteger, "LOP3_IMM"), INST("0100110001001---", Id::SHL_C, Type::Shift, "SHL_C"), INST("0101110001001---", Id::SHL_R, Type::Shift, "SHL_R"), INST("0011100-01001---", Id::SHL_IMM, Type::Shift, "SHL_IMM"), diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 5b976b636..7926726a1 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -849,6 +849,28 @@ private: } } + void WriteLop3Instruction(Register dest, const std::string& op_a, const std::string& op_b, + const std::string& op_c, const std::string& imm_lut) { + std::string result; + result += '('; + + for (u32 i = 0; i < 32; ++i) { + std::string ix = std::to_string(i); + if (i) + result += '|'; + result += "(((" + imm_lut + ">>(((" + op_c + ">>" + ix + ")&1)|((" + op_b + ">>" + ix + + ")&1)<<1|((" + op_a + ">>" + ix + ")&1)<<2))&1)<<" + ix + ")"; + } + + result += ')'; + + LOG_DEBUG(HW_GPU, "LOP3 Shader code: {}", result); + + if (dest != Tegra::Shader::Register::ZeroIndex) { + regs.SetRegisterToInteger(dest, true, 0, result, 1, 1); + } + } + void WriteTexsInstruction(const Instruction& instr, const std::string& coord, const std::string& texture) { // Add an extra scope and declare the texture coords inside to prevent @@ -1297,6 +1319,20 @@ private: instr.alu.lop.pred_result_mode, instr.alu.lop.pred48); break; } + case OpCode::Id::LOP3_C: + case OpCode::Id::LOP3_R: + case OpCode::Id::LOP3_IMM: { + std::string op_c = regs.GetRegisterAsInteger(instr.gpr39); + std::string lut; + if (opcode->GetId() == OpCode::Id::LOP3_R) { + lut = '(' + std::to_string(instr.alu.lop3.GetImmLut28()) + ')'; + } else { + lut = '(' + std::to_string(instr.alu.lop3.GetImmLut48()) + ')'; + } + + WriteLop3Instruction(instr.gpr0, op_a, op_b, op_c, lut); + break; + } case OpCode::Id::IMNMX_C: case OpCode::Id::IMNMX_R: case OpCode::Id::IMNMX_IMM: { From 4877e6c2f658eb259041b8590c2590475f343b14 Mon Sep 17 00:00:00 2001 From: Laku Date: Wed, 22 Aug 2018 11:45:28 +0300 Subject: [PATCH 2/4] remove debug logging --- src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 7926726a1..07bd0d21b 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -864,8 +864,6 @@ private: result += ')'; - LOG_DEBUG(HW_GPU, "LOP3 Shader code: {}", result); - if (dest != Tegra::Shader::Register::ZeroIndex) { regs.SetRegisterToInteger(dest, true, 0, result, 1, 1); } From e70a3c5a5d6f117ec915aab4635e79e346da24d9 Mon Sep 17 00:00:00 2001 From: Laku Date: Wed, 22 Aug 2018 21:33:32 +0300 Subject: [PATCH 3/4] fixes --- .../renderer_opengl/gl_shader_decompiler.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 07bd0d21b..15194d5a6 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -851,22 +851,28 @@ private: void WriteLop3Instruction(Register dest, const std::string& op_a, const std::string& op_b, const std::string& op_c, const std::string& imm_lut) { + if (dest == Tegra::Shader::Register::ZeroIndex) + return; + + static constexpr std::array ix = { + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", + "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", + "22", "23", "24", "25", "26", "27", "28", "29", "30", "31"}; + std::string result; result += '('; for (u32 i = 0; i < 32; ++i) { - std::string ix = std::to_string(i); if (i) result += '|'; - result += "(((" + imm_lut + ">>(((" + op_c + ">>" + ix + ")&1)|((" + op_b + ">>" + ix + - ")&1)<<1|((" + op_a + ">>" + ix + ")&1)<<2))&1)<<" + ix + ")"; + result += "(((" + imm_lut + " >> (((" + op_c + " >> " + ix[i] + ") & 1) | ((" + op_b + + " >> " + ix[i] + ") & 1) << 1 | ((" + op_a + " >> " + ix[i] + + ") & 1) << 2)) & 1) << " + ix[i] + ")"; } result += ')'; - if (dest != Tegra::Shader::Register::ZeroIndex) { - regs.SetRegisterToInteger(dest, true, 0, result, 1, 1); - } + regs.SetRegisterToInteger(dest, true, 0, result, 1, 1); } void WriteTexsInstruction(const Instruction& instr, const std::string& coord, From b2ca8089ce04a77c5c481e063db8066361a1ae46 Mon Sep 17 00:00:00 2001 From: Laku Date: Thu, 23 Aug 2018 00:01:40 +0300 Subject: [PATCH 4/4] more fixes --- .../renderer_opengl/gl_shader_decompiler.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 15194d5a6..2d3706221 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -851,10 +851,11 @@ private: void WriteLop3Instruction(Register dest, const std::string& op_a, const std::string& op_b, const std::string& op_c, const std::string& imm_lut) { - if (dest == Tegra::Shader::Register::ZeroIndex) + if (dest == Tegra::Shader::Register::ZeroIndex) { return; + } - static constexpr std::array ix = { + static constexpr std::array shift_amounts = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31"}; @@ -862,12 +863,12 @@ private: std::string result; result += '('; - for (u32 i = 0; i < 32; ++i) { + for (size_t i = 0; i < shift_amounts.size(); ++i) { if (i) result += '|'; - result += "(((" + imm_lut + " >> (((" + op_c + " >> " + ix[i] + ") & 1) | ((" + op_b + - " >> " + ix[i] + ") & 1) << 1 | ((" + op_a + " >> " + ix[i] + - ") & 1) << 2)) & 1) << " + ix[i] + ")"; + result += "(((" + imm_lut + " >> (((" + op_c + " >> " + shift_amounts[i] + + ") & 1) | ((" + op_b + " >> " + shift_amounts[i] + ") & 1) << 1 | ((" + op_a + + " >> " + shift_amounts[i] + ") & 1) << 2)) & 1) << " + shift_amounts[i] + ")"; } result += ')';