Просмотр исходного кода

Merge pull request #1083 from Subv/conv_neg

Shaders: Implemented I2F_C and F2I_C, along with the negation bits of the conversion instructions.
bunnei 8 лет назад
Родитель
Сommit
a2fa37b499
1 измененных файлов с 53 добавлено и 13 удалено
  1. 53 13
      src/video_core/renderer_opengl/gl_shader_decompiler.cpp

+ 53 - 13
src/video_core/renderer_opengl/gl_shader_decompiler.cpp

@@ -367,20 +367,23 @@ public:
     }
 
     /// Generates code representing a uniform (C buffer) register, interpreted as the input type.
-    std::string GetUniform(u64 index, u64 offset, GLSLRegister::Type type) {
+    std::string GetUniform(u64 index, u64 offset, GLSLRegister::Type type,
+                           Register::Size size = Register::Size::Word) {
         declr_const_buffers[index].MarkAsUsed(index, offset, stage);
         std::string value = 'c' + std::to_string(index) + '[' + std::to_string(offset / 4) + "][" +
                             std::to_string(offset % 4) + ']';
 
         if (type == GLSLRegister::Type::Float) {
-            return value;
+            // Do nothing, default
         } else if (type == GLSLRegister::Type::Integer) {
-            return "floatBitsToInt(" + value + ')';
+            value = "floatBitsToInt(" + value + ')';
         } else if (type == GLSLRegister::Type::UnsignedInteger) {
-            return "floatBitsToUint(" + value + ')';
+            value = "floatBitsToUint(" + value + ')';
         } else {
             UNREACHABLE();
         }
+
+        return ConvertIntegerSize(value, size);
     }
 
     std::string GetUniformIndirect(u64 cbuf_index, s64 offset, const std::string& index_str,
@@ -1247,20 +1250,41 @@ private:
                     op_a = "abs(" + op_a + ')';
                 }
 
+                if (instr.conversion.negate_a) {
+                    op_a = "-(" + op_a + ')';
+                }
+
                 regs.SetRegisterToInteger(instr.gpr0, instr.conversion.is_output_signed, 0, op_a, 1,
                                           1, instr.alu.saturate_d, 0, instr.conversion.dest_size);
                 break;
             }
-            case OpCode::Id::I2F_R: {
+            case OpCode::Id::I2F_R:
+            case OpCode::Id::I2F_C: {
                 ASSERT_MSG(instr.conversion.dest_size == Register::Size::Word, "Unimplemented");
                 ASSERT_MSG(!instr.conversion.selector, "Unimplemented");
-                std::string op_a = regs.GetRegisterAsInteger(
-                    instr.gpr20, 0, instr.conversion.is_input_signed, instr.conversion.src_size);
+
+                std::string op_a{};
+
+                if (instr.is_b_gpr) {
+                    op_a =
+                        regs.GetRegisterAsInteger(instr.gpr20, 0, instr.conversion.is_input_signed,
+                                                  instr.conversion.src_size);
+                } else {
+                    op_a = regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
+                                           instr.conversion.is_input_signed
+                                               ? GLSLRegister::Type::Integer
+                                               : GLSLRegister::Type::UnsignedInteger,
+                                           instr.conversion.src_size);
+                }
 
                 if (instr.conversion.abs_a) {
                     op_a = "abs(" + op_a + ')';
                 }
 
+                if (instr.conversion.negate_a) {
+                    op_a = "-(" + op_a + ')';
+                }
+
                 regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1);
                 break;
             }
@@ -1269,6 +1293,14 @@ private:
                 ASSERT_MSG(instr.conversion.src_size == Register::Size::Word, "Unimplemented");
                 std::string op_a = regs.GetRegisterAsFloat(instr.gpr20);
 
+                if (instr.conversion.abs_a) {
+                    op_a = "abs(" + op_a + ')';
+                }
+
+                if (instr.conversion.negate_a) {
+                    op_a = "-(" + op_a + ')';
+                }
+
                 switch (instr.conversion.f2f.rounding) {
                 case Tegra::Shader::F2fRoundingOp::None:
                     break;
@@ -1291,21 +1323,29 @@ private:
                     break;
                 }
 
-                if (instr.conversion.abs_a) {
-                    op_a = "abs(" + op_a + ')';
-                }
-
                 regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1, instr.alu.saturate_d);
                 break;
             }
-            case OpCode::Id::F2I_R: {
+            case OpCode::Id::F2I_R:
+            case OpCode::Id::F2I_C: {
                 ASSERT_MSG(instr.conversion.src_size == Register::Size::Word, "Unimplemented");
-                std::string op_a = regs.GetRegisterAsFloat(instr.gpr20);
+                std::string op_a{};
+
+                if (instr.is_b_gpr) {
+                    op_a = regs.GetRegisterAsFloat(instr.gpr20);
+                } else {
+                    op_a = regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
+                                           GLSLRegister::Type::Float);
+                }
 
                 if (instr.conversion.abs_a) {
                     op_a = "abs(" + op_a + ')';
                 }
 
+                if (instr.conversion.negate_a) {
+                    op_a = "-(" + op_a + ')';
+                }
+
                 switch (instr.conversion.f2i.rounding) {
                 case Tegra::Shader::F2iRoundingOp::None:
                     break;