diff options
author | ReinUsesLisp <reinuseslisp@airmail.cc> | 2018-12-21 02:57:16 +0100 |
---|---|---|
committer | ReinUsesLisp <reinuseslisp@airmail.cc> | 2019-01-15 21:54:49 +0100 |
commit | e3c55e31d7d15066d565e6cd728d12526e91d8e2 (patch) | |
tree | daebd7803451465e47d96c712f945312fcec75d7 /src | |
parent | shader_ir: Add float helpers (diff) | |
download | yuzu-e3c55e31d7d15066d565e6cd728d12526e91d8e2.tar yuzu-e3c55e31d7d15066d565e6cd728d12526e91d8e2.tar.gz yuzu-e3c55e31d7d15066d565e6cd728d12526e91d8e2.tar.bz2 yuzu-e3c55e31d7d15066d565e6cd728d12526e91d8e2.tar.lz yuzu-e3c55e31d7d15066d565e6cd728d12526e91d8e2.tar.xz yuzu-e3c55e31d7d15066d565e6cd728d12526e91d8e2.tar.zst yuzu-e3c55e31d7d15066d565e6cd728d12526e91d8e2.zip |
Diffstat (limited to 'src')
-rw-r--r-- | src/video_core/shader/shader_ir.cpp | 35 | ||||
-rw-r--r-- | src/video_core/shader/shader_ir.h | 5 |
2 files changed, 40 insertions, 0 deletions
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp index af95e54ef..e4b81040d 100644 --- a/src/video_core/shader/shader_ir.cpp +++ b/src/video_core/shader/shader_ir.cpp @@ -140,6 +140,41 @@ Node ShaderIR::GetSaturatedFloat(Node value, bool saturate) { return Operation(OperationCode::FClamp, NO_PRECISE, value, positive_zero, positive_one); } +Node ShaderIR::ConvertIntegerSize(Node value, Tegra::Shader::Register::Size size, bool is_signed) { + switch (size) { + case Register::Size::Byte: + value = SignedOperation(OperationCode::ILogicalShiftLeft, is_signed, NO_PRECISE, value, + Immediate(24)); + value = SignedOperation(OperationCode::IArithmeticShiftRight, is_signed, NO_PRECISE, value, + Immediate(24)); + return value; + case Register::Size::Short: + value = SignedOperation(OperationCode::ILogicalShiftLeft, is_signed, NO_PRECISE, value, + Immediate(16)); + value = SignedOperation(OperationCode::IArithmeticShiftRight, is_signed, NO_PRECISE, value, + Immediate(16)); + case Register::Size::Word: + // Default - do nothing + return value; + default: + UNREACHABLE_MSG("Unimplemented conversion size: {}", static_cast<u32>(size)); + } +} + +Node ShaderIR::GetOperandAbsNegInteger(Node value, bool absolute, bool negate, bool is_signed) { + if (!is_signed) { + // Absolute or negate on an unsigned is pointless + return value; + } + if (absolute) { + value = Operation(OperationCode::IAbsolute, NO_PRECISE, value); + } + if (negate) { + value = Operation(OperationCode::INegate, NO_PRECISE, value); + } + return value; +} + void ShaderIR::SetRegister(BasicBlock& bb, Register dest, Node src) { bb.push_back(Operation(OperationCode::Assign, GetRegister(dest), src)); } diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index 93455412f..84c016da6 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h @@ -648,6 +648,11 @@ private: /// Conditionally saturates a float Node GetSaturatedFloat(Node value, bool saturate = true); + /// Converts an integer to different sizes. + Node ConvertIntegerSize(Node value, Tegra::Shader::Register::Size size, bool is_signed); + /// Conditionally absolute/negated integer. Absolute is applied first + Node GetOperandAbsNegInteger(Node value, bool absolute, bool negate, bool is_signed); + template <typename... T> inline Node Operation(OperationCode code, const T*... operands) { return StoreNode(OperationNode(code, operands...)); |