summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2019-12-18 00:05:08 -0300
committerGravatar ReinUsesLisp2019-12-18 00:41:22 -0300
commita7d6bd1ef1cdd2ca406e2ded31f872dda4da0db3 (patch)
treedff1cc935df383973b83e1d4ffe2975b54aab86d /src
parentMerge pull request #3173 from yuzu-emu/bunnei-spscqueue (diff)
downloadyuzu-a7d6bd1ef1cdd2ca406e2ded31f872dda4da0db3.tar.gz
yuzu-a7d6bd1ef1cdd2ca406e2ded31f872dda4da0db3.tar.xz
yuzu-a7d6bd1ef1cdd2ca406e2ded31f872dda4da0db3.zip
shader/conversion: Implement byte selector in I2F
I2F's byte selector is used to choose what bytes to convert to float. e.g. if the input is 0xaabbccdd and the selector is ".B3" it will convert 0xaa. The default (when it's not shown in nvdisasm) is ".B0", in that example the default would convert 0xdd to float.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/shader/decode/conversion.cpp15
1 files changed, 13 insertions, 2 deletions
diff --git a/src/video_core/shader/decode/conversion.cpp b/src/video_core/shader/decode/conversion.cpp
index 32facd6ba..0eeb75559 100644
--- a/src/video_core/shader/decode/conversion.cpp
+++ b/src/video_core/shader/decode/conversion.cpp
@@ -63,12 +63,11 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
63 case OpCode::Id::I2F_R: 63 case OpCode::Id::I2F_R:
64 case OpCode::Id::I2F_C: 64 case OpCode::Id::I2F_C:
65 case OpCode::Id::I2F_IMM: { 65 case OpCode::Id::I2F_IMM: {
66 UNIMPLEMENTED_IF(instr.conversion.int_src.selector != 0);
67 UNIMPLEMENTED_IF(instr.conversion.dst_size == Register::Size::Long); 66 UNIMPLEMENTED_IF(instr.conversion.dst_size == Register::Size::Long);
68 UNIMPLEMENTED_IF_MSG(instr.generates_cc, 67 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
69 "Condition codes generation in I2F is not implemented"); 68 "Condition codes generation in I2F is not implemented");
70 69
71 Node value = [&]() { 70 Node value = [&] {
72 switch (opcode->get().GetId()) { 71 switch (opcode->get().GetId()) {
73 case OpCode::Id::I2F_R: 72 case OpCode::Id::I2F_R:
74 return GetRegister(instr.gpr20); 73 return GetRegister(instr.gpr20);
@@ -81,7 +80,19 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
81 return Immediate(0); 80 return Immediate(0);
82 } 81 }
83 }(); 82 }();
83
84 const bool input_signed = instr.conversion.is_input_signed; 84 const bool input_signed = instr.conversion.is_input_signed;
85
86 if (instr.conversion.src_size == Register::Size::Byte) {
87 const u32 offset = static_cast<u32>(instr.conversion.int_src.selector) * 8;
88 if (offset > 0) {
89 value = SignedOperation(OperationCode::ILogicalShiftRight, input_signed,
90 std::move(value), Immediate(offset));
91 }
92 } else {
93 UNIMPLEMENTED_IF(instr.conversion.int_src.selector != 0);
94 }
95
85 value = ConvertIntegerSize(value, instr.conversion.src_size, input_signed); 96 value = ConvertIntegerSize(value, instr.conversion.src_size, input_signed);
86 value = GetOperandAbsNegInteger(value, instr.conversion.abs_a, false, input_signed); 97 value = GetOperandAbsNegInteger(value, instr.conversion.abs_a, false, input_signed);
87 value = SignedOperation(OperationCode::FCastInteger, input_signed, PRECISE, value); 98 value = SignedOperation(OperationCode::FCastInteger, input_signed, PRECISE, value);