summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/shader_bytecode.h15
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp30
2 files changed, 35 insertions, 10 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index ab45cfbef..2cda1e63e 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -168,13 +168,22 @@ enum class SubOp : u64 {
168 Min = 0x8, 168 Min = 0x8,
169}; 169};
170 170
171enum class FloatRoundingOp : u64 { 171enum class F2iRoundingOp : u64 {
172 None = 0, 172 None = 0,
173 Floor = 1, 173 Floor = 1,
174 Ceil = 2, 174 Ceil = 2,
175 Trunc = 3, 175 Trunc = 3,
176}; 176};
177 177
178enum class F2fRoundingOp : u64 {
179 None = 0,
180 Pass = 3,
181 Round = 8,
182 Floor = 9,
183 Ceil = 10,
184 Trunc = 11,
185};
186
178enum class UniformType : u64 { 187enum class UniformType : u64 {
179 UnsignedByte = 0, 188 UnsignedByte = 0,
180 SignedByte = 1, 189 SignedByte = 1,
@@ -314,11 +323,11 @@ union Instruction {
314 BitField<50, 1, u64> saturate_a; 323 BitField<50, 1, u64> saturate_a;
315 324
316 union { 325 union {
317 BitField<39, 2, FloatRoundingOp> rounding; 326 BitField<39, 2, F2iRoundingOp> rounding;
318 } f2i; 327 } f2i;
319 328
320 union { 329 union {
321 BitField<39, 4, u64> rounding; 330 BitField<39, 4, F2fRoundingOp> rounding;
322 } f2f; 331 } f2f;
323 } conversion; 332 } conversion;
324 333
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index f84cedc1d..8e249584f 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -1056,10 +1056,27 @@ private:
1056 break; 1056 break;
1057 } 1057 }
1058 case OpCode::Id::F2F_R: { 1058 case OpCode::Id::F2F_R: {
1059 // TODO(Subv): Implement rounding operations.
1060 ASSERT_MSG(instr.conversion.f2f.rounding == 0, "Unimplemented rounding operation");
1061 std::string op_a = regs.GetRegisterAsFloat(instr.gpr20); 1059 std::string op_a = regs.GetRegisterAsFloat(instr.gpr20);
1062 1060
1061 switch (instr.conversion.f2f.rounding) {
1062 case Tegra::Shader::F2fRoundingOp::None:
1063 break;
1064 case Tegra::Shader::F2fRoundingOp::Floor:
1065 op_a = "floor(" + op_a + ')';
1066 break;
1067 case Tegra::Shader::F2fRoundingOp::Ceil:
1068 op_a = "ceil(" + op_a + ')';
1069 break;
1070 case Tegra::Shader::F2fRoundingOp::Trunc:
1071 op_a = "trunc(" + op_a + ')';
1072 break;
1073 default:
1074 NGLOG_CRITICAL(HW_GPU, "Unimplemented f2f rounding mode {}",
1075 static_cast<u32>(instr.conversion.f2f.rounding.Value()));
1076 UNREACHABLE();
1077 break;
1078 }
1079
1063 if (instr.conversion.abs_a) { 1080 if (instr.conversion.abs_a) {
1064 op_a = "abs(" + op_a + ')'; 1081 op_a = "abs(" + op_a + ')';
1065 } 1082 }
@@ -1074,17 +1091,16 @@ private:
1074 op_a = "abs(" + op_a + ')'; 1091 op_a = "abs(" + op_a + ')';
1075 } 1092 }
1076 1093
1077 using Tegra::Shader::FloatRoundingOp;
1078 switch (instr.conversion.f2i.rounding) { 1094 switch (instr.conversion.f2i.rounding) {
1079 case FloatRoundingOp::None: 1095 case Tegra::Shader::F2iRoundingOp::None:
1080 break; 1096 break;
1081 case FloatRoundingOp::Floor: 1097 case Tegra::Shader::F2iRoundingOp::Floor:
1082 op_a = "floor(" + op_a + ')'; 1098 op_a = "floor(" + op_a + ')';
1083 break; 1099 break;
1084 case FloatRoundingOp::Ceil: 1100 case Tegra::Shader::F2iRoundingOp::Ceil:
1085 op_a = "ceil(" + op_a + ')'; 1101 op_a = "ceil(" + op_a + ')';
1086 break; 1102 break;
1087 case FloatRoundingOp::Trunc: 1103 case Tegra::Shader::F2iRoundingOp::Trunc:
1088 op_a = "trunc(" + op_a + ')'; 1104 op_a = "trunc(" + op_a + ')';
1089 break; 1105 break;
1090 default: 1106 default: