diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 3 | ||||
| -rw-r--r-- | src/video_core/shader/decode/conversion.cpp | 20 |
2 files changed, 17 insertions, 6 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index aaa1acea9..35201c8be 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -1006,7 +1006,7 @@ union Instruction { | |||
| 1006 | } iset; | 1006 | } iset; |
| 1007 | 1007 | ||
| 1008 | union { | 1008 | union { |
| 1009 | BitField<41, 2, u64> selector; // i2i and i2f only | 1009 | BitField<41, 2, u64> selector; |
| 1010 | BitField<45, 1, u64> negate_a; | 1010 | BitField<45, 1, u64> negate_a; |
| 1011 | BitField<49, 1, u64> abs_a; | 1011 | BitField<49, 1, u64> abs_a; |
| 1012 | BitField<10, 2, Register::Size> src_size; | 1012 | BitField<10, 2, Register::Size> src_size; |
| @@ -1031,7 +1031,6 @@ union Instruction { | |||
| 1031 | return static_cast<F2fRoundingOp>(rounding.Value() & rounding_mask); | 1031 | return static_cast<F2fRoundingOp>(rounding.Value() & rounding_mask); |
| 1032 | } | 1032 | } |
| 1033 | } f2f; | 1033 | } f2f; |
| 1034 | |||
| 1035 | } conversion; | 1034 | } conversion; |
| 1036 | 1035 | ||
| 1037 | union { | 1036 | union { |
diff --git a/src/video_core/shader/decode/conversion.cpp b/src/video_core/shader/decode/conversion.cpp index 8973fbefa..cf328aff8 100644 --- a/src/video_core/shader/decode/conversion.cpp +++ b/src/video_core/shader/decode/conversion.cpp | |||
| @@ -22,7 +22,7 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) { | |||
| 22 | case OpCode::Id::I2I_R: | 22 | case OpCode::Id::I2I_R: |
| 23 | case OpCode::Id::I2I_C: | 23 | case OpCode::Id::I2I_C: |
| 24 | case OpCode::Id::I2I_IMM: { | 24 | case OpCode::Id::I2I_IMM: { |
| 25 | UNIMPLEMENTED_IF(instr.conversion.selector); | 25 | UNIMPLEMENTED_IF(instr.conversion.selector.Value()); |
| 26 | UNIMPLEMENTED_IF(instr.conversion.dst_size != Register::Size::Word); | 26 | UNIMPLEMENTED_IF(instr.conversion.dst_size != Register::Size::Word); |
| 27 | UNIMPLEMENTED_IF(instr.alu.saturate_d); | 27 | UNIMPLEMENTED_IF(instr.alu.saturate_d); |
| 28 | 28 | ||
| @@ -57,8 +57,8 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) { | |||
| 57 | case OpCode::Id::I2F_R: | 57 | case OpCode::Id::I2F_R: |
| 58 | case OpCode::Id::I2F_C: | 58 | case OpCode::Id::I2F_C: |
| 59 | case OpCode::Id::I2F_IMM: { | 59 | case OpCode::Id::I2F_IMM: { |
| 60 | UNIMPLEMENTED_IF(instr.conversion.selector.Value()); | ||
| 60 | UNIMPLEMENTED_IF(instr.conversion.dst_size == Register::Size::Long); | 61 | UNIMPLEMENTED_IF(instr.conversion.dst_size == Register::Size::Long); |
| 61 | UNIMPLEMENTED_IF(instr.conversion.selector); | ||
| 62 | UNIMPLEMENTED_IF_MSG(instr.generates_cc, | 62 | UNIMPLEMENTED_IF_MSG(instr.generates_cc, |
| 63 | "Condition codes generation in I2F is not implemented"); | 63 | "Condition codes generation in I2F is not implemented"); |
| 64 | 64 | ||
| @@ -93,6 +93,7 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) { | |||
| 93 | case OpCode::Id::F2F_R: | 93 | case OpCode::Id::F2F_R: |
| 94 | case OpCode::Id::F2F_C: | 94 | case OpCode::Id::F2F_C: |
| 95 | case OpCode::Id::F2F_IMM: { | 95 | case OpCode::Id::F2F_IMM: { |
| 96 | UNIMPLEMENTED_IF(instr.conversion.selector.Value()); | ||
| 96 | UNIMPLEMENTED_IF(instr.conversion.dst_size == Register::Size::Long); | 97 | UNIMPLEMENTED_IF(instr.conversion.dst_size == Register::Size::Long); |
| 97 | UNIMPLEMENTED_IF(instr.conversion.src_size == Register::Size::Long); | 98 | UNIMPLEMENTED_IF(instr.conversion.src_size == Register::Size::Long); |
| 98 | UNIMPLEMENTED_IF_MSG(instr.generates_cc, | 99 | UNIMPLEMENTED_IF_MSG(instr.generates_cc, |
| @@ -169,8 +170,19 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) { | |||
| 169 | }(); | 170 | }(); |
| 170 | 171 | ||
| 171 | if (instr.conversion.src_size == Register::Size::Short) { | 172 | if (instr.conversion.src_size == Register::Size::Short) { |
| 172 | // TODO: figure where extract is sey in the encoding | 173 | const OperationCode cast = [instr] { |
| 173 | value = Operation(OperationCode::FCastHalf0, PRECISE, value); | 174 | switch (instr.conversion.selector) { |
| 175 | case 0: | ||
| 176 | return OperationCode::FCastHalf0; | ||
| 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)); | ||
| 174 | } | 186 | } |
| 175 | 187 | ||
| 176 | value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a); | 188 | value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a); |