aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/shader/decode/conversion.cpp
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2019-12-18 00:05:08 -0300
committerReinUsesLisp <reinuseslisp@airmail.cc>2019-12-18 00:41:22 -0300
commit034809d729714bce0a5bc9f0612905f600f86b9f (patch)
treedff1cc935df383973b83e1d4ffe2975b54aab86d /src/video_core/shader/decode/conversion.cpp
parentc54d8affb9ac0616c82c0d1ad6e2ab5485b598a6 (diff)
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/video_core/shader/decode/conversion.cpp')
-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 32facd6bae..0eeb755593 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) {
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_MSG(instr.generates_cc,
"Condition codes generation in I2F is not implemented");
- Node value = [&]() {
+ Node value = [&] {
switch (opcode->get().GetId()) {
case OpCode::Id::I2F_R:
return GetRegister(instr.gpr20);
@@ -81,7 +80,19 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
return Immediate(0);
}
}();
+
const bool input_signed = instr.conversion.is_input_signed;
+
+ if (instr.conversion.src_size == Register::Size::Byte) {
+ const u32 offset = static_cast<u32>(instr.conversion.int_src.selector) * 8;
+ if (offset > 0) {
+ value = SignedOperation(OperationCode::ILogicalShiftRight, input_signed,
+ std::move(value), Immediate(offset));
+ }
+ } else {
+ UNIMPLEMENTED_IF(instr.conversion.int_src.selector != 0);
+ }
+
value = ConvertIntegerSize(value, instr.conversion.src_size, input_signed);
value = GetOperandAbsNegInteger(value, instr.conversion.abs_a, false, input_signed);
value = SignedOperation(OperationCode::FCastInteger, input_signed, PRECISE, value);