diff options
| author | bunnei <bunneidev@gmail.com> | 2019-09-03 22:35:33 -0400 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-09-03 22:35:33 -0400 | 
| commit | 81fbc5370d8f09a3a167c96556fb3a4bf211673a (patch) | |
| tree | 496c370578de2ef494faab0fe8c5b1e4d93593bf | |
| parent | d4f33b822bbb4ced7d1e23c39f2da1c7d7bb725f (diff) | |
| parent | e3534700d79aedd696f36430ea2a632506f2b1e3 (diff) | |
Merge pull request #2812 from ReinUsesLisp/f2i-selector
shader_ir/conversion: Implement F2I and F2F F16 selector
| -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 {      } iset;      union { -        BitField<41, 2, u64> selector; // i2i and i2f only          BitField<45, 1, u64> negate_a;          BitField<49, 1, u64> abs_a;          BitField<10, 2, Register::Size> src_size; @@ -1046,6 +1045,13 @@ union Instruction {              }          } f2f; +        union { +            BitField<41, 2, u64> selector; +        } int_src; + +        union { +            BitField<41, 1, u64> selector; +        } float_src;      } conversion;      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;  using Tegra::Shader::OpCode;  using Tegra::Shader::Register; +namespace { +constexpr OperationCode GetFloatSelector(u64 selector) { +    return selector == 0 ? OperationCode::FCastHalf0 : OperationCode::FCastHalf1; +} +} // Anonymous namespace +  u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {      const Instruction instr = {program_code[pc]};      const auto opcode = OpCode::Decode(instr); @@ -22,7 +28,7 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {      case OpCode::Id::I2I_R:      case OpCode::Id::I2I_C:      case OpCode::Id::I2I_IMM: { -        UNIMPLEMENTED_IF(instr.conversion.selector); +        UNIMPLEMENTED_IF(instr.conversion.int_src.selector != 0);          UNIMPLEMENTED_IF(instr.conversion.dst_size != Register::Size::Word);          UNIMPLEMENTED_IF(instr.alu.saturate_d); @@ -57,8 +63,8 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {      case OpCode::Id::I2F_R:      case OpCode::Id::I2F_C:      case OpCode::Id::I2F_IMM: { +        UNIMPLEMENTED_IF(instr.conversion.int_src.selector != 0);          UNIMPLEMENTED_IF(instr.conversion.dst_size == Register::Size::Long); -        UNIMPLEMENTED_IF(instr.conversion.selector);          UNIMPLEMENTED_IF_MSG(instr.generates_cc,                               "Condition codes generation in I2F is not implemented"); @@ -113,8 +119,10 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {          }();          if (instr.conversion.src_size == Register::Size::Short) { -            // TODO: figure where extract is sey in the encoding -            value = Operation(OperationCode::FCastHalf0, PRECISE, value); +            value = Operation(GetFloatSelector(instr.conversion.float_src.selector), NO_PRECISE, +                              std::move(value)); +        } else { +            ASSERT(instr.conversion.float_src.selector == 0);          }          value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a); @@ -169,8 +177,10 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {          }();          if (instr.conversion.src_size == Register::Size::Short) { -            // TODO: figure where extract is sey in the encoding -            value = Operation(OperationCode::FCastHalf0, PRECISE, value); +            value = Operation(GetFloatSelector(instr.conversion.float_src.selector), NO_PRECISE, +                              std::move(value)); +        } else { +            ASSERT(instr.conversion.float_src.selector == 0);          }          value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a); | 
