diff options
| author | 2019-04-20 00:42:34 -0400 | |
|---|---|---|
| committer | 2019-04-20 00:42:34 -0400 | |
| commit | da0c3bc65836ed8f10ee6689ac7b041c3fd64631 (patch) | |
| tree | 4e740e63b175c1b03de4529f2c1e810f38472c5b /src/video_core/shader | |
| parent | Merge pull request #2409 from ReinUsesLisp/half-floats (diff) | |
| parent | Do some corrections in conversion shader instructions. (diff) | |
| download | yuzu-da0c3bc65836ed8f10ee6689ac7b041c3fd64631.tar.gz yuzu-da0c3bc65836ed8f10ee6689ac7b041c3fd64631.tar.xz yuzu-da0c3bc65836ed8f10ee6689ac7b041c3fd64631.zip | |
Merge pull request #2407 from FernandoS27/f2f
Do some corrections in conversion shader instructions.
Diffstat (limited to 'src/video_core/shader')
| -rw-r--r-- | src/video_core/shader/decode/conversion.cpp | 69 |
1 files changed, 53 insertions, 16 deletions
diff --git a/src/video_core/shader/decode/conversion.cpp b/src/video_core/shader/decode/conversion.cpp index 55a6fbbf2..ba15b1115 100644 --- a/src/video_core/shader/decode/conversion.cpp +++ b/src/video_core/shader/decode/conversion.cpp | |||
| @@ -18,13 +18,29 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) { | |||
| 18 | const auto opcode = OpCode::Decode(instr); | 18 | const auto opcode = OpCode::Decode(instr); |
| 19 | 19 | ||
| 20 | switch (opcode->get().GetId()) { | 20 | switch (opcode->get().GetId()) { |
| 21 | case OpCode::Id::I2I_R: { | 21 | case OpCode::Id::I2I_R: |
| 22 | case OpCode::Id::I2I_C: | ||
| 23 | case OpCode::Id::I2I_IMM: { | ||
| 22 | UNIMPLEMENTED_IF(instr.conversion.selector); | 24 | UNIMPLEMENTED_IF(instr.conversion.selector); |
| 25 | UNIMPLEMENTED_IF(instr.conversion.dst_size != Register::Size::Word); | ||
| 26 | UNIMPLEMENTED_IF(instr.alu.saturate_d); | ||
| 23 | 27 | ||
| 24 | const bool input_signed = instr.conversion.is_input_signed; | 28 | const bool input_signed = instr.conversion.is_input_signed; |
| 25 | const bool output_signed = instr.conversion.is_output_signed; | 29 | const bool output_signed = instr.conversion.is_output_signed; |
| 26 | 30 | ||
| 27 | Node value = GetRegister(instr.gpr20); | 31 | Node value = [&]() { |
| 32 | switch (opcode->get().GetId()) { | ||
| 33 | case OpCode::Id::I2I_R: | ||
| 34 | return GetRegister(instr.gpr20); | ||
| 35 | case OpCode::Id::I2I_C: | ||
| 36 | return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()); | ||
| 37 | case OpCode::Id::I2I_IMM: | ||
| 38 | return Immediate(instr.alu.GetSignedImm20_20()); | ||
| 39 | default: | ||
| 40 | UNREACHABLE(); | ||
| 41 | return Immediate(0); | ||
| 42 | } | ||
| 43 | }(); | ||
| 28 | value = ConvertIntegerSize(value, instr.conversion.src_size, input_signed); | 44 | value = ConvertIntegerSize(value, instr.conversion.src_size, input_signed); |
| 29 | 45 | ||
| 30 | value = GetOperandAbsNegInteger(value, instr.conversion.abs_a, instr.conversion.negate_a, | 46 | value = GetOperandAbsNegInteger(value, instr.conversion.abs_a, instr.conversion.negate_a, |
| @@ -38,17 +54,24 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) { | |||
| 38 | break; | 54 | break; |
| 39 | } | 55 | } |
| 40 | case OpCode::Id::I2F_R: | 56 | case OpCode::Id::I2F_R: |
| 41 | case OpCode::Id::I2F_C: { | 57 | case OpCode::Id::I2F_C: |
| 42 | UNIMPLEMENTED_IF(instr.conversion.dest_size != Register::Size::Word); | 58 | case OpCode::Id::I2F_IMM: { |
| 59 | UNIMPLEMENTED_IF(instr.conversion.dst_size != Register::Size::Word); | ||
| 43 | UNIMPLEMENTED_IF(instr.conversion.selector); | 60 | UNIMPLEMENTED_IF(instr.conversion.selector); |
| 44 | UNIMPLEMENTED_IF_MSG(instr.generates_cc, | 61 | UNIMPLEMENTED_IF_MSG(instr.generates_cc, |
| 45 | "Condition codes generation in I2F is not implemented"); | 62 | "Condition codes generation in I2F is not implemented"); |
| 46 | 63 | ||
| 47 | Node value = [&]() { | 64 | Node value = [&]() { |
| 48 | if (instr.is_b_gpr) { | 65 | switch (opcode->get().GetId()) { |
| 66 | case OpCode::Id::I2F_R: | ||
| 49 | return GetRegister(instr.gpr20); | 67 | return GetRegister(instr.gpr20); |
| 50 | } else { | 68 | case OpCode::Id::I2F_C: |
| 51 | return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()); | 69 | return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()); |
| 70 | case OpCode::Id::I2F_IMM: | ||
| 71 | return Immediate(instr.alu.GetSignedImm20_20()); | ||
| 72 | default: | ||
| 73 | UNREACHABLE(); | ||
| 74 | return Immediate(0); | ||
| 52 | } | 75 | } |
| 53 | }(); | 76 | }(); |
| 54 | const bool input_signed = instr.conversion.is_input_signed; | 77 | const bool input_signed = instr.conversion.is_input_signed; |
| @@ -62,24 +85,31 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) { | |||
| 62 | break; | 85 | break; |
| 63 | } | 86 | } |
| 64 | case OpCode::Id::F2F_R: | 87 | case OpCode::Id::F2F_R: |
| 65 | case OpCode::Id::F2F_C: { | 88 | case OpCode::Id::F2F_C: |
| 66 | UNIMPLEMENTED_IF(instr.conversion.dest_size != Register::Size::Word); | 89 | case OpCode::Id::F2F_IMM: { |
| 67 | UNIMPLEMENTED_IF(instr.conversion.src_size != Register::Size::Word); | 90 | UNIMPLEMENTED_IF(instr.conversion.f2f.dst_size != Register::Size::Word); |
| 91 | UNIMPLEMENTED_IF(instr.conversion.f2f.src_size != Register::Size::Word); | ||
| 68 | UNIMPLEMENTED_IF_MSG(instr.generates_cc, | 92 | UNIMPLEMENTED_IF_MSG(instr.generates_cc, |
| 69 | "Condition codes generation in F2F is not implemented"); | 93 | "Condition codes generation in F2F is not implemented"); |
| 70 | 94 | ||
| 71 | Node value = [&]() { | 95 | Node value = [&]() { |
| 72 | if (instr.is_b_gpr) { | 96 | switch (opcode->get().GetId()) { |
| 97 | case OpCode::Id::F2F_R: | ||
| 73 | return GetRegister(instr.gpr20); | 98 | return GetRegister(instr.gpr20); |
| 74 | } else { | 99 | case OpCode::Id::F2F_C: |
| 75 | return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()); | 100 | return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()); |
| 101 | case OpCode::Id::F2F_IMM: | ||
| 102 | return GetImmediate19(instr); | ||
| 103 | default: | ||
| 104 | UNREACHABLE(); | ||
| 105 | return Immediate(0); | ||
| 76 | } | 106 | } |
| 77 | }(); | 107 | }(); |
| 78 | 108 | ||
| 79 | value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a); | 109 | value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a); |
| 80 | 110 | ||
| 81 | value = [&]() { | 111 | value = [&]() { |
| 82 | switch (instr.conversion.f2f.rounding) { | 112 | switch (instr.conversion.f2f.GetRoundingMode()) { |
| 83 | case Tegra::Shader::F2fRoundingOp::None: | 113 | case Tegra::Shader::F2fRoundingOp::None: |
| 84 | return value; | 114 | return value; |
| 85 | case Tegra::Shader::F2fRoundingOp::Round: | 115 | case Tegra::Shader::F2fRoundingOp::Round: |
| @@ -102,15 +132,22 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) { | |||
| 102 | break; | 132 | break; |
| 103 | } | 133 | } |
| 104 | case OpCode::Id::F2I_R: | 134 | case OpCode::Id::F2I_R: |
| 105 | case OpCode::Id::F2I_C: { | 135 | case OpCode::Id::F2I_C: |
| 136 | case OpCode::Id::F2I_IMM: { | ||
| 106 | UNIMPLEMENTED_IF(instr.conversion.src_size != Register::Size::Word); | 137 | UNIMPLEMENTED_IF(instr.conversion.src_size != Register::Size::Word); |
| 107 | UNIMPLEMENTED_IF_MSG(instr.generates_cc, | 138 | UNIMPLEMENTED_IF_MSG(instr.generates_cc, |
| 108 | "Condition codes generation in F2I is not implemented"); | 139 | "Condition codes generation in F2I is not implemented"); |
| 109 | Node value = [&]() { | 140 | Node value = [&]() { |
| 110 | if (instr.is_b_gpr) { | 141 | switch (opcode->get().GetId()) { |
| 142 | case OpCode::Id::F2I_R: | ||
| 111 | return GetRegister(instr.gpr20); | 143 | return GetRegister(instr.gpr20); |
| 112 | } else { | 144 | case OpCode::Id::F2I_C: |
| 113 | return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()); | 145 | return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()); |
| 146 | case OpCode::Id::F2I_IMM: | ||
| 147 | return GetImmediate19(instr); | ||
| 148 | default: | ||
| 149 | UNREACHABLE(); | ||
| 150 | return Immediate(0); | ||
| 114 | } | 151 | } |
| 115 | }(); | 152 | }(); |
| 116 | 153 | ||
| @@ -134,7 +171,7 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) { | |||
| 134 | }(); | 171 | }(); |
| 135 | const bool is_signed = instr.conversion.is_output_signed; | 172 | const bool is_signed = instr.conversion.is_output_signed; |
| 136 | value = SignedOperation(OperationCode::ICastFloat, is_signed, PRECISE, value); | 173 | value = SignedOperation(OperationCode::ICastFloat, is_signed, PRECISE, value); |
| 137 | value = ConvertIntegerSize(value, instr.conversion.dest_size, is_signed); | 174 | value = ConvertIntegerSize(value, instr.conversion.dst_size, is_signed); |
| 138 | 175 | ||
| 139 | SetRegister(bb, instr.gpr0, value); | 176 | SetRegister(bb, instr.gpr0, value); |
| 140 | break; | 177 | break; |