summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/shader_bytecode.h24
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp47
2 files changed, 64 insertions, 7 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index 22c122fcc..93654eb66 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -173,6 +173,13 @@ enum class SubOp : u64 {
173 Min = 0x8, 173 Min = 0x8,
174}; 174};
175 175
176enum class FloatRoundingOp : u64 {
177 None = 0,
178 Floor = 1,
179 Ceil = 2,
180 Trunc = 3,
181};
182
176union Instruction { 183union Instruction {
177 Instruction& operator=(const Instruction& instr) { 184 Instruction& operator=(const Instruction& instr) {
178 value = instr.value; 185 value = instr.value;
@@ -277,11 +284,20 @@ union Instruction {
277 284
278 union { 285 union {
279 BitField<10, 2, Register::Size> size; 286 BitField<10, 2, Register::Size> size;
280 BitField<13, 1, u64> is_signed; 287 BitField<12, 1, u64> is_output_signed;
288 BitField<13, 1, u64> is_input_signed;
281 BitField<41, 2, u64> selector; 289 BitField<41, 2, u64> selector;
282 BitField<45, 1, u64> negate_a; 290 BitField<45, 1, u64> negate_a;
283 BitField<49, 1, u64> abs_a; 291 BitField<49, 1, u64> abs_a;
284 BitField<50, 1, u64> saturate_a; 292 BitField<50, 1, u64> saturate_a;
293
294 union {
295 BitField<39, 2, FloatRoundingOp> rounding;
296 } f2i;
297
298 union {
299 BitField<39, 4, u64> rounding;
300 } f2f;
285 } conversion; 301 } conversion;
286 302
287 union { 303 union {
@@ -535,9 +551,9 @@ private:
535 INST("0100110010101---", Id::F2F_C, Type::Conversion, "F2F_C"), 551 INST("0100110010101---", Id::F2F_C, Type::Conversion, "F2F_C"),
536 INST("0101110010101---", Id::F2F_R, Type::Conversion, "F2F_R"), 552 INST("0101110010101---", Id::F2F_R, Type::Conversion, "F2F_R"),
537 INST("0011100-10101---", Id::F2F_IMM, Type::Conversion, "F2F_IMM"), 553 INST("0011100-10101---", Id::F2F_IMM, Type::Conversion, "F2F_IMM"),
538 INST("0100110010110---", Id::F2I_C, Type::Arithmetic, "F2I_C"), 554 INST("0100110010110---", Id::F2I_C, Type::Conversion, "F2I_C"),
539 INST("0101110010110---", Id::F2I_R, Type::Arithmetic, "F2I_R"), 555 INST("0101110010110---", Id::F2I_R, Type::Conversion, "F2I_R"),
540 INST("0011100-10110---", Id::F2I_IMM, Type::Arithmetic, "F2I_IMM"), 556 INST("0011100-10110---", Id::F2I_IMM, Type::Conversion, "F2I_IMM"),
541 INST("0100110010011---", Id::MOV_C, Type::Arithmetic, "MOV_C"), 557 INST("0100110010011---", Id::MOV_C, Type::Arithmetic, "MOV_C"),
542 INST("0101110010011---", Id::MOV_R, Type::Arithmetic, "MOV_R"), 558 INST("0101110010011---", Id::MOV_R, Type::Arithmetic, "MOV_R"),
543 INST("0011100-10011---", Id::MOV_IMM, Type::Arithmetic, "MOV_IMM"), 559 INST("0011100-10011---", Id::MOV_IMM, Type::Arithmetic, "MOV_IMM"),
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 9943394c6..4b14bb47e 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -929,18 +929,20 @@ private:
929 ASSERT_MSG(!instr.conversion.selector, "Unimplemented"); 929 ASSERT_MSG(!instr.conversion.selector, "Unimplemented");
930 930
931 std::string op_a = 931 std::string op_a =
932 regs.GetRegisterAsInteger(instr.gpr20, 0, instr.conversion.is_signed); 932 regs.GetRegisterAsInteger(instr.gpr20, 0, instr.conversion.is_input_signed);
933 933
934 if (instr.conversion.abs_a) { 934 if (instr.conversion.abs_a) {
935 op_a = "abs(" + op_a + ')'; 935 op_a = "abs(" + op_a + ')';
936 } 936 }
937 937
938 regs.SetRegisterToInteger(instr.gpr0, instr.conversion.is_signed, 0, op_a, 1, 1); 938 regs.SetRegisterToInteger(instr.gpr0, instr.conversion.is_output_signed, 0, op_a, 1,
939 1);
939 break; 940 break;
940 } 941 }
941 case OpCode::Id::I2F_R: { 942 case OpCode::Id::I2F_R: {
943 ASSERT_MSG(!instr.conversion.selector, "Unimplemented");
942 std::string op_a = 944 std::string op_a =
943 regs.GetRegisterAsInteger(instr.gpr20, 0, instr.conversion.is_signed); 945 regs.GetRegisterAsInteger(instr.gpr20, 0, instr.conversion.is_input_signed);
944 946
945 if (instr.conversion.abs_a) { 947 if (instr.conversion.abs_a) {
946 op_a = "abs(" + op_a + ')'; 948 op_a = "abs(" + op_a + ')';
@@ -950,6 +952,8 @@ private:
950 break; 952 break;
951 } 953 }
952 case OpCode::Id::F2F_R: { 954 case OpCode::Id::F2F_R: {
955 // TODO(Subv): Implement rounding operations.
956 ASSERT_MSG(instr.conversion.f2f.rounding == 0, "Unimplemented rounding operation");
953 std::string op_a = regs.GetRegisterAsFloat(instr.gpr20); 957 std::string op_a = regs.GetRegisterAsFloat(instr.gpr20);
954 958
955 if (instr.conversion.abs_a) { 959 if (instr.conversion.abs_a) {
@@ -959,6 +963,43 @@ private:
959 regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1); 963 regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1);
960 break; 964 break;
961 } 965 }
966 case OpCode::Id::F2I_R: {
967 std::string op_a = regs.GetRegisterAsFloat(instr.gpr20);
968
969 if (instr.conversion.abs_a) {
970 op_a = "abs(" + op_a + ')';
971 }
972
973 using Tegra::Shader::FloatRoundingOp;
974 switch (instr.conversion.f2i.rounding) {
975 case FloatRoundingOp::None:
976 break;
977 case FloatRoundingOp::Floor:
978 op_a = "floor(" + op_a + ')';
979 break;
980 case FloatRoundingOp::Ceil:
981 op_a = "ceil(" + op_a + ')';
982 break;
983 case FloatRoundingOp::Trunc:
984 op_a = "trunc(" + op_a + ')';
985 break;
986 default:
987 NGLOG_CRITICAL(HW_GPU, "Unimplemented f2i rounding mode {}",
988 static_cast<u32>(instr.conversion.f2i.rounding.Value()));
989 UNREACHABLE();
990 break;
991 }
992
993 if (instr.conversion.is_output_signed) {
994 op_a = "int(" + op_a + ')';
995 } else {
996 op_a = "uint(" + op_a + ')';
997 }
998
999 regs.SetRegisterToInteger(instr.gpr0, instr.conversion.is_output_signed, 0, op_a, 1,
1000 1);
1001 break;
1002 }
962 default: { 1003 default: {
963 NGLOG_CRITICAL(HW_GPU, "Unhandled conversion instruction: {}", opcode->GetName()); 1004 NGLOG_CRITICAL(HW_GPU, "Unhandled conversion instruction: {}", opcode->GetName());
964 UNREACHABLE(); 1005 UNREACHABLE();