diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 8 | ||||
| -rw-r--r-- | src/video_core/shader/decode/conversion.cpp | 22 |
2 files changed, 23 insertions, 7 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index ba28ff51c..c3678b9ea 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -1020,7 +1020,6 @@ union Instruction { | |||
| 1020 | } iset; | 1020 | } iset; |
| 1021 | 1021 | ||
| 1022 | union { | 1022 | union { |
| 1023 | BitField<41, 2, u64> selector; // i2i and i2f only | ||
| 1024 | BitField<45, 1, u64> negate_a; | 1023 | BitField<45, 1, u64> negate_a; |
| 1025 | BitField<49, 1, u64> abs_a; | 1024 | BitField<49, 1, u64> abs_a; |
| 1026 | BitField<10, 2, Register::Size> src_size; | 1025 | BitField<10, 2, Register::Size> src_size; |
| @@ -1046,6 +1045,13 @@ union Instruction { | |||
| 1046 | } | 1045 | } |
| 1047 | } f2f; | 1046 | } f2f; |
| 1048 | 1047 | ||
| 1048 | union { | ||
| 1049 | BitField<41, 2, u64> selector; | ||
| 1050 | } int_src; | ||
| 1051 | |||
| 1052 | union { | ||
| 1053 | BitField<41, 1, u64> selector; | ||
| 1054 | } float_src; | ||
| 1049 | } conversion; | 1055 | } conversion; |
| 1050 | 1056 | ||
| 1051 | union { | 1057 | union { |
diff --git a/src/video_core/shader/decode/conversion.cpp b/src/video_core/shader/decode/conversion.cpp index 8973fbefa..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); | 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,8 +63,8 @@ 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: { |
| 66 | UNIMPLEMENTED_IF(instr.conversion.int_src.selector != 0); | ||
| 60 | UNIMPLEMENTED_IF(instr.conversion.dst_size == Register::Size::Long); | 67 | UNIMPLEMENTED_IF(instr.conversion.dst_size == Register::Size::Long); |
| 61 | UNIMPLEMENTED_IF(instr.conversion.selector); | ||
| 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"); |
| 64 | 70 | ||
| @@ -113,8 +119,10 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) { | |||
| 113 | }(); | 119 | }(); |
| 114 | 120 | ||
| 115 | if (instr.conversion.src_size == Register::Size::Short) { | 121 | if (instr.conversion.src_size == Register::Size::Short) { |
| 116 | // TODO: figure where extract is sey in the encoding | 122 | value = Operation(GetFloatSelector(instr.conversion.float_src.selector), NO_PRECISE, |
| 117 | value = Operation(OperationCode::FCastHalf0, PRECISE, value); | 123 | std::move(value)); |
| 124 | } else { | ||
| 125 | ASSERT(instr.conversion.float_src.selector == 0); | ||
| 118 | } | 126 | } |
| 119 | 127 | ||
| 120 | value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a); | 128 | value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a); |
| @@ -169,8 +177,10 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) { | |||
| 169 | }(); | 177 | }(); |
| 170 | 178 | ||
| 171 | if (instr.conversion.src_size == Register::Size::Short) { | 179 | if (instr.conversion.src_size == Register::Size::Short) { |
| 172 | // TODO: figure where extract is sey in the encoding | 180 | value = Operation(GetFloatSelector(instr.conversion.float_src.selector), NO_PRECISE, |
| 173 | value = Operation(OperationCode::FCastHalf0, PRECISE, value); | 181 | std::move(value)); |
| 182 | } else { | ||
| 183 | ASSERT(instr.conversion.float_src.selector == 0); | ||
| 174 | } | 184 | } |
| 175 | 185 | ||
| 176 | value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a); | 186 | value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a); |