summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/video_core/shader/shader_ir.cpp35
-rw-r--r--src/video_core/shader/shader_ir.h5
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...));