diff options
| author | 2019-08-28 16:09:33 -0300 | |
|---|---|---|
| committer | 2019-08-28 16:09:33 -0300 | |
| commit | e3534700d79aedd696f36430ea2a632506f2b1e3 (patch) | |
| tree | 92593bd4554714e738387fb05a8d1dd883066bbf /src | |
| parent | shader_ir/conversion: Implement F2I F16 Ra.H1 (diff) | |
| download | yuzu-e3534700d79aedd696f36430ea2a632506f2b1e3.tar.gz yuzu-e3534700d79aedd696f36430ea2a632506f2b1e3.tar.xz yuzu-e3534700d79aedd696f36430ea2a632506f2b1e3.zip | |
shader_ir/conversion: Split int and float selector and implement F2F H1
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 9 | ||||
| -rw-r--r-- | src/video_core/shader/decode/conversion.cpp | 34 |
2 files changed, 24 insertions, 19 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 35201c8be..747284700 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -1006,7 +1006,6 @@ union Instruction { | |||
| 1006 | } iset; | 1006 | } iset; |
| 1007 | 1007 | ||
| 1008 | union { | 1008 | union { |
| 1009 | BitField<41, 2, u64> selector; | ||
| 1010 | BitField<45, 1, u64> negate_a; | 1009 | BitField<45, 1, u64> negate_a; |
| 1011 | BitField<49, 1, u64> abs_a; | 1010 | BitField<49, 1, u64> abs_a; |
| 1012 | BitField<10, 2, Register::Size> src_size; | 1011 | BitField<10, 2, Register::Size> src_size; |
| @@ -1031,6 +1030,14 @@ union Instruction { | |||
| 1031 | return static_cast<F2fRoundingOp>(rounding.Value() & rounding_mask); | 1030 | return static_cast<F2fRoundingOp>(rounding.Value() & rounding_mask); |
| 1032 | } | 1031 | } |
| 1033 | } f2f; | 1032 | } f2f; |
| 1033 | |||
| 1034 | union { | ||
| 1035 | BitField<41, 2, u64> selector; | ||
| 1036 | } int_src; | ||
| 1037 | |||
| 1038 | union { | ||
| 1039 | BitField<41, 1, u64> selector; | ||
| 1040 | } float_src; | ||
| 1034 | } conversion; | 1041 | } conversion; |
| 1035 | 1042 | ||
| 1036 | union { | 1043 | union { |
diff --git a/src/video_core/shader/decode/conversion.cpp b/src/video_core/shader/decode/conversion.cpp index cf328aff8..32facd6ba 100644 --- a/src/video_core/shader/decode/conversion.cpp +++ b/src/video_core/shader/decode/conversion.cpp | |||
| @@ -14,6 +14,12 @@ using Tegra::Shader::Instruction; | |||
| 14 | using Tegra::Shader::OpCode; | 14 | using Tegra::Shader::OpCode; |
| 15 | using Tegra::Shader::Register; | 15 | using Tegra::Shader::Register; |
| 16 | 16 | ||
| 17 | namespace { | ||
| 18 | constexpr OperationCode GetFloatSelector(u64 selector) { | ||
| 19 | return selector == 0 ? OperationCode::FCastHalf0 : OperationCode::FCastHalf1; | ||
| 20 | } | ||
| 21 | } // Anonymous namespace | ||
| 22 | |||
| 17 | u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) { | 23 | u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) { |
| 18 | const Instruction instr = {program_code[pc]}; | 24 | const Instruction instr = {program_code[pc]}; |
| 19 | const auto opcode = OpCode::Decode(instr); | 25 | const auto opcode = OpCode::Decode(instr); |
| @@ -22,7 +28,7 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) { | |||
| 22 | case OpCode::Id::I2I_R: | 28 | case OpCode::Id::I2I_R: |
| 23 | case OpCode::Id::I2I_C: | 29 | case OpCode::Id::I2I_C: |
| 24 | case OpCode::Id::I2I_IMM: { | 30 | case OpCode::Id::I2I_IMM: { |
| 25 | UNIMPLEMENTED_IF(instr.conversion.selector.Value()); | 31 | UNIMPLEMENTED_IF(instr.conversion.int_src.selector != 0); |
| 26 | UNIMPLEMENTED_IF(instr.conversion.dst_size != Register::Size::Word); | 32 | UNIMPLEMENTED_IF(instr.conversion.dst_size != Register::Size::Word); |
| 27 | UNIMPLEMENTED_IF(instr.alu.saturate_d); | 33 | UNIMPLEMENTED_IF(instr.alu.saturate_d); |
| 28 | 34 | ||
| @@ -57,7 +63,7 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) { | |||
| 57 | case OpCode::Id::I2F_R: | 63 | case OpCode::Id::I2F_R: |
| 58 | case OpCode::Id::I2F_C: | 64 | case OpCode::Id::I2F_C: |
| 59 | case OpCode::Id::I2F_IMM: { | 65 | case OpCode::Id::I2F_IMM: { |
| 60 | UNIMPLEMENTED_IF(instr.conversion.selector.Value()); | 66 | UNIMPLEMENTED_IF(instr.conversion.int_src.selector != 0); |
| 61 | UNIMPLEMENTED_IF(instr.conversion.dst_size == Register::Size::Long); | 67 | UNIMPLEMENTED_IF(instr.conversion.dst_size == Register::Size::Long); |
| 62 | UNIMPLEMENTED_IF_MSG(instr.generates_cc, | 68 | UNIMPLEMENTED_IF_MSG(instr.generates_cc, |
| 63 | "Condition codes generation in I2F is not implemented"); | 69 | "Condition codes generation in I2F is not implemented"); |
| @@ -93,7 +99,6 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) { | |||
| 93 | case OpCode::Id::F2F_R: | 99 | case OpCode::Id::F2F_R: |
| 94 | case OpCode::Id::F2F_C: | 100 | case OpCode::Id::F2F_C: |
| 95 | case OpCode::Id::F2F_IMM: { | 101 | case OpCode::Id::F2F_IMM: { |
| 96 | UNIMPLEMENTED_IF(instr.conversion.selector.Value()); | ||
| 97 | UNIMPLEMENTED_IF(instr.conversion.dst_size == Register::Size::Long); | 102 | UNIMPLEMENTED_IF(instr.conversion.dst_size == Register::Size::Long); |
| 98 | UNIMPLEMENTED_IF(instr.conversion.src_size == Register::Size::Long); | 103 | UNIMPLEMENTED_IF(instr.conversion.src_size == Register::Size::Long); |
| 99 | UNIMPLEMENTED_IF_MSG(instr.generates_cc, | 104 | UNIMPLEMENTED_IF_MSG(instr.generates_cc, |
| @@ -114,8 +119,10 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) { | |||
| 114 | }(); | 119 | }(); |
| 115 | 120 | ||
| 116 | if (instr.conversion.src_size == Register::Size::Short) { | 121 | if (instr.conversion.src_size == Register::Size::Short) { |
| 117 | // TODO: figure where extract is sey in the encoding | 122 | value = Operation(GetFloatSelector(instr.conversion.float_src.selector), NO_PRECISE, |
| 118 | value = Operation(OperationCode::FCastHalf0, PRECISE, value); | 123 | std::move(value)); |
| 124 | } else { | ||
| 125 | ASSERT(instr.conversion.float_src.selector == 0); | ||
| 119 | } | 126 | } |
| 120 | 127 | ||
| 121 | value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a); | 128 | value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a); |
| @@ -170,19 +177,10 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) { | |||
| 170 | }(); | 177 | }(); |
| 171 | 178 | ||
| 172 | if (instr.conversion.src_size == Register::Size::Short) { | 179 | if (instr.conversion.src_size == Register::Size::Short) { |
| 173 | const OperationCode cast = [instr] { | 180 | value = Operation(GetFloatSelector(instr.conversion.float_src.selector), NO_PRECISE, |
| 174 | switch (instr.conversion.selector) { | 181 | std::move(value)); |
| 175 | case 0: | 182 | } else { |
| 176 | return OperationCode::FCastHalf0; | 183 | ASSERT(instr.conversion.float_src.selector == 0); |
| 177 | case 1: | ||
| 178 | return OperationCode::FCastHalf1; | ||
| 179 | default: | ||
| 180 | UNREACHABLE_MSG("Invalid selector={}", | ||
| 181 | static_cast<u32>(instr.conversion.selector)); | ||
| 182 | return OperationCode::FCastHalf0; | ||
| 183 | } | ||
| 184 | }(); | ||
| 185 | value = Operation(cast, NO_PRECISE, std::move(value)); | ||
| 186 | } | 184 | } |
| 187 | 185 | ||
| 188 | value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a); | 186 | value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a); |