diff options
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 15 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 30 | 
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 {      Min = 0x8,  }; -enum class FloatRoundingOp : u64 { +enum class F2iRoundingOp : u64 {      None = 0,      Floor = 1,      Ceil = 2,      Trunc = 3,  }; +enum class F2fRoundingOp : u64 { +    None = 0, +    Pass = 3, +    Round = 8, +    Floor = 9, +    Ceil = 10, +    Trunc = 11, +}; +  enum class UniformType : u64 {      UnsignedByte = 0,      SignedByte = 1, @@ -314,11 +323,11 @@ union Instruction {          BitField<50, 1, u64> saturate_a;          union { -            BitField<39, 2, FloatRoundingOp> rounding; +            BitField<39, 2, F2iRoundingOp> rounding;          } f2i;          union { -            BitField<39, 4, u64> rounding; +            BitField<39, 4, F2fRoundingOp> rounding;          } f2f;      } conversion; 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:                  break;              }              case OpCode::Id::F2F_R: { -                // TODO(Subv): Implement rounding operations. -                ASSERT_MSG(instr.conversion.f2f.rounding == 0, "Unimplemented rounding operation");                  std::string op_a = regs.GetRegisterAsFloat(instr.gpr20); +                switch (instr.conversion.f2f.rounding) { +                case Tegra::Shader::F2fRoundingOp::None: +                    break; +                case Tegra::Shader::F2fRoundingOp::Floor: +                    op_a = "floor(" + op_a + ')'; +                    break; +                case Tegra::Shader::F2fRoundingOp::Ceil: +                    op_a = "ceil(" + op_a + ')'; +                    break; +                case Tegra::Shader::F2fRoundingOp::Trunc: +                    op_a = "trunc(" + op_a + ')'; +                    break; +                default: +                    NGLOG_CRITICAL(HW_GPU, "Unimplemented f2f rounding mode {}", +                                   static_cast<u32>(instr.conversion.f2f.rounding.Value())); +                    UNREACHABLE(); +                    break; +                } +                  if (instr.conversion.abs_a) {                      op_a = "abs(" + op_a + ')';                  } @@ -1074,17 +1091,16 @@ private:                      op_a = "abs(" + op_a + ')';                  } -                using Tegra::Shader::FloatRoundingOp;                  switch (instr.conversion.f2i.rounding) { -                case FloatRoundingOp::None: +                case Tegra::Shader::F2iRoundingOp::None:                      break; -                case FloatRoundingOp::Floor: +                case Tegra::Shader::F2iRoundingOp::Floor:                      op_a = "floor(" + op_a + ')';                      break; -                case FloatRoundingOp::Ceil: +                case Tegra::Shader::F2iRoundingOp::Ceil:                      op_a = "ceil(" + op_a + ')';                      break; -                case FloatRoundingOp::Trunc: +                case Tegra::Shader::F2iRoundingOp::Trunc:                      op_a = "trunc(" + op_a + ')';                      break;                  default: | 
