summaryrefslogtreecommitdiffstats
path: root/src/video_core/shader
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2019-04-09 23:41:41 +0200
committerReinUsesLisp <reinuseslisp@airmail.cc>2019-04-16 02:16:10 +0200
commit64613db6052dfe0c056ce3d6ead21ae9a32f03ae (patch)
tree9fa4a632c8fc050b6176ebbca727c27757f95662 /src/video_core/shader
parentshader_ir/decode: Reduce severity of unimplemented half-float FTZ (diff)
downloadyuzu-64613db6052dfe0c056ce3d6ead21ae9a32f03ae.tar
yuzu-64613db6052dfe0c056ce3d6ead21ae9a32f03ae.tar.gz
yuzu-64613db6052dfe0c056ce3d6ead21ae9a32f03ae.tar.bz2
yuzu-64613db6052dfe0c056ce3d6ead21ae9a32f03ae.tar.lz
yuzu-64613db6052dfe0c056ce3d6ead21ae9a32f03ae.tar.xz
yuzu-64613db6052dfe0c056ce3d6ead21ae9a32f03ae.tar.zst
yuzu-64613db6052dfe0c056ce3d6ead21ae9a32f03ae.zip
Diffstat (limited to '')
-rw-r--r--src/video_core/shader/decode/arithmetic_half_immediate.cpp6
-rw-r--r--src/video_core/shader/shader_ir.cpp9
-rw-r--r--src/video_core/shader/shader_ir.h3
3 files changed, 14 insertions, 4 deletions
diff --git a/src/video_core/shader/decode/arithmetic_half_immediate.cpp b/src/video_core/shader/decode/arithmetic_half_immediate.cpp
index 4a5b0620e..cf4bc0432 100644
--- a/src/video_core/shader/decode/arithmetic_half_immediate.cpp
+++ b/src/video_core/shader/decode/arithmetic_half_immediate.cpp
@@ -23,8 +23,6 @@ u32 ShaderIR::DecodeArithmeticHalfImmediate(NodeBlock& bb, u32 pc) {
} else {
UNIMPLEMENTED_IF(instr.alu_half_imm.precision != Tegra::Shader::HalfPrecision::None);
}
- UNIMPLEMENTED_IF_MSG(instr.alu_half_imm.saturate != 0,
- "Half float immediate saturation not implemented");
Node op_a = GetRegister(instr.gpr8);
op_a = GetOperandAbsNegHalf(op_a, instr.alu_half_imm.abs_a, instr.alu_half_imm.negate_a);
@@ -43,10 +41,10 @@ u32 ShaderIR::DecodeArithmeticHalfImmediate(NodeBlock& bb, u32 pc) {
return Immediate(0);
}
}();
- value = HalfMerge(GetRegister(instr.gpr0), value, instr.alu_half_imm.merge);
+ value = GetSaturatedHalfFloat(value, instr.alu_half_imm.saturate);
+ value = HalfMerge(GetRegister(instr.gpr0), value, instr.alu_half_imm.merge);
SetRegister(bb, instr.gpr0, value);
-
return pc;
}
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp
index 5c1c591f8..d158b4bfd 100644
--- a/src/video_core/shader/shader_ir.cpp
+++ b/src/video_core/shader/shader_ir.cpp
@@ -218,6 +218,15 @@ Node ShaderIR::GetOperandAbsNegHalf(Node value, bool absolute, bool negate) {
return value;
}
+Node ShaderIR::GetSaturatedHalfFloat(Node value, bool saturate) {
+ if (!saturate) {
+ return value;
+ }
+ const Node positive_zero = Immediate(std::copysignf(0, 1));
+ const Node positive_one = Immediate(1.0f);
+ return Operation(OperationCode::HClamp, HALF_NO_PRECISE, value, positive_zero, positive_one);
+}
+
Node ShaderIR::GetPredicateComparisonFloat(PredCondition condition, Node op_a, Node op_b) {
const std::unordered_map<PredCondition, OperationCode> PredicateComparisonTable = {
{PredCondition::LessThan, OperationCode::LogicalFLessThan},
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index 0ae51389b..d329da58d 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -114,6 +114,7 @@ enum class OperationCode {
HFma, /// (MetaHalfArithmetic, f16vec2 a, f16vec2 b, f16vec2 c) -> f16vec2
HAbsolute, /// (f16vec2 a) -> f16vec2
HNegate, /// (f16vec2 a, bool first, bool second) -> f16vec2
+ HClamp, /// (f16vec2 src, float min, float max) -> f16vec2
HMergeF32, /// (f16vec2 src) -> float
HMergeH0, /// (f16vec2 dest, f16vec2 src) -> f16vec2
HMergeH1, /// (f16vec2 dest, f16vec2 src) -> f16vec2
@@ -716,6 +717,8 @@ private:
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);
+ /// Conditionally saturates a half float pair
+ Node GetSaturatedHalfFloat(Node value, bool saturate = true);
/// Returns a predicate comparing two floats
Node GetPredicateComparisonFloat(Tegra::Shader::PredCondition condition, Node op_a, Node op_b);