diff options
author | ReinUsesLisp <reinuseslisp@airmail.cc> | 2018-12-21 02:58:33 +0100 |
---|---|---|
committer | ReinUsesLisp <reinuseslisp@airmail.cc> | 2019-01-15 21:54:49 +0100 |
commit | 60f044df566569d00106a7bce28110aaca9fa534 (patch) | |
tree | e3084b477057c9c8d32de5ea0a306bd07f811381 | |
parent | shader_ir: Add integer helpers (diff) | |
download | yuzu-60f044df566569d00106a7bce28110aaca9fa534.tar yuzu-60f044df566569d00106a7bce28110aaca9fa534.tar.gz yuzu-60f044df566569d00106a7bce28110aaca9fa534.tar.bz2 yuzu-60f044df566569d00106a7bce28110aaca9fa534.tar.lz yuzu-60f044df566569d00106a7bce28110aaca9fa534.tar.xz yuzu-60f044df566569d00106a7bce28110aaca9fa534.tar.zst yuzu-60f044df566569d00106a7bce28110aaca9fa534.zip |
-rw-r--r-- | src/video_core/shader/shader_ir.cpp | 37 | ||||
-rw-r--r-- | src/video_core/shader/shader_ir.h | 7 |
2 files changed, 44 insertions, 0 deletions
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp index e4b81040d..5951bdc7b 100644 --- a/src/video_core/shader/shader_ir.cpp +++ b/src/video_core/shader/shader_ir.cpp @@ -175,6 +175,43 @@ Node ShaderIR::GetOperandAbsNegInteger(Node value, bool absolute, bool negate, b return value; } +Node ShaderIR::UnpackHalfImmediate(Instruction instr, bool has_negation) { + const Node value = Immediate(instr.half_imm.PackImmediates()); + if (!has_negation) { + return value; + } + const Node first_negate = GetPredicate(instr.half_imm.first_negate != 0); + const Node second_negate = GetPredicate(instr.half_imm.second_negate != 0); + + return Operation(OperationCode::HNegate, HALF_NO_PRECISE, value, first_negate, second_negate); +} + +Node ShaderIR::HalfMerge(Node dest, Node src, Tegra::Shader::HalfMerge merge) { + switch (merge) { + case Tegra::Shader::HalfMerge::H0_H1: + return src; + case Tegra::Shader::HalfMerge::F32: + return Operation(OperationCode::HMergeF32, src); + case Tegra::Shader::HalfMerge::Mrg_H0: + return Operation(OperationCode::HMergeH0, dest, src); + case Tegra::Shader::HalfMerge::Mrg_H1: + return Operation(OperationCode::HMergeH1, dest, src); + } + UNREACHABLE(); + return src; +} + +Node ShaderIR::GetOperandAbsNegHalf(Node value, bool absolute, bool negate) { + if (absolute) { + value = Operation(OperationCode::HAbsolute, HALF_NO_PRECISE, value); + } + if (negate) { + value = Operation(OperationCode::HNegate, HALF_NO_PRECISE, value, GetPredicate(true), + GetPredicate(true)); + } + 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 84c016da6..f3b17d2eb 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h @@ -653,6 +653,13 @@ private: /// Conditionally absolute/negated integer. Absolute is applied first Node GetOperandAbsNegInteger(Node value, bool absolute, bool negate, bool is_signed); + /// Unpacks a half immediate from an instruction + Node UnpackHalfImmediate(Tegra::Shader::Instruction instr, bool has_negation); + /// Merges a half pair into another value + Node HalfMerge(Node dest, Node src, Tegra::Shader::HalfMerge merge); + /// Conditionally absolute/negated half float pair. Absolute is applied first + Node GetOperandAbsNegHalf(Node value, bool absolute, bool negate); + template <typename... T> inline Node Operation(OperationCode code, const T*... operands) { return StoreNode(OperationNode(code, operands...)); |