mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 05:46:56 +01:00
shader: add FP64 min, max and rounding
Co-authored-by: Çağatay Güçlü <33038942+defektu@users.noreply.github.com>
This commit is contained in:
@@ -30,6 +30,28 @@ uint32_t CompareEqual64(EmitterState& state, uint32_t lhs_value, uint32_t rhs_va
|
||||
return Unary(state, not_equal ? spv::OpAny : spv::OpAll, TypeBool(state), compare);
|
||||
}
|
||||
|
||||
uint32_t EmitMinMaxF64(EmitterState& state, uint32_t lhs, uint32_t rhs, bool max_value) {
|
||||
const auto bits_type = TypeU64(state);
|
||||
const auto lhs_bits = Unary(state, spv::OpBitcast, bits_type, lhs);
|
||||
const auto rhs_bits = Unary(state, spv::OpBitcast, bits_type, rhs);
|
||||
const auto ordered = Binary(state, max_value ? spv::OpFOrdGreaterThan : spv::OpFOrdLessThan,
|
||||
TypeBool(state), lhs, rhs);
|
||||
auto result = Select(state, TypeF64(state), ordered, lhs, rhs);
|
||||
|
||||
// Equal values have identical bits except signed zero: min chooses -0, max chooses +0.
|
||||
const auto equal = Binary(state, spv::OpFOrdEqual, TypeBool(state), lhs, rhs);
|
||||
const auto equal_bits = Binary(state, max_value ? spv::OpBitwiseAnd : spv::OpBitwiseOr,
|
||||
bits_type, lhs_bits, rhs_bits);
|
||||
result = Select(state, TypeF64(state), equal,
|
||||
Unary(state, spv::OpBitcast, TypeF64(state), equal_bits), result);
|
||||
|
||||
// Non-IEEE mode selects the other operand for NaN, including rhs when both are NaN.
|
||||
result = Select(state, TypeF64(state), Unary(state, spv::OpIsNan, TypeBool(state), rhs),
|
||||
lhs, result);
|
||||
return Select(state, TypeF64(state), Unary(state, spv::OpIsNan, TypeBool(state), lhs),
|
||||
rhs, result);
|
||||
}
|
||||
|
||||
uint32_t CompareOrdered64(EmitterState& state, uint32_t lhs_value, uint32_t rhs_value,
|
||||
spv::Op high_compare, spv::Op low_compare) {
|
||||
const auto lhs = ExtractPair(state, lhs_value);
|
||||
@@ -468,6 +490,14 @@ uint32_t EmitFPMax32(EmitterState& state, uint32_t arg0, uint32_t arg1) {
|
||||
return EmitMinMaxF32Value(state, arg0, arg1, true);
|
||||
}
|
||||
|
||||
uint32_t EmitFPMin64(EmitterState& state, uint32_t arg0, uint32_t arg1) {
|
||||
return EmitMinMaxF64(state, arg0, arg1, false);
|
||||
}
|
||||
|
||||
uint32_t EmitFPMax64(EmitterState& state, uint32_t arg0, uint32_t arg1) {
|
||||
return EmitMinMaxF64(state, arg0, arg1, true);
|
||||
}
|
||||
|
||||
uint32_t EmitFPMinTri32(EmitterState& state, uint32_t arg0, uint32_t arg1, uint32_t arg2) {
|
||||
return EmitFMinMax3(state, arg0, arg1, arg2, false);
|
||||
}
|
||||
|
||||
@@ -164,6 +164,8 @@ inline constexpr auto EmitFPFma32 =
|
||||
EmitGlsl<GLSLstd450Fma, IR::Type::F32, uint32_t, uint32_t, uint32_t>;
|
||||
uint32_t EmitFPMin32(EmitterState& state, uint32_t arg0, uint32_t arg1);
|
||||
uint32_t EmitFPMax32(EmitterState& state, uint32_t arg0, uint32_t arg1);
|
||||
uint32_t EmitFPMin64(EmitterState& state, uint32_t arg0, uint32_t arg1);
|
||||
uint32_t EmitFPMax64(EmitterState& state, uint32_t arg0, uint32_t arg1);
|
||||
uint32_t EmitFPMinTri32(EmitterState& state, uint32_t arg0, uint32_t arg1, uint32_t arg2);
|
||||
uint32_t EmitFPMaxTri32(EmitterState& state, uint32_t arg0, uint32_t arg1, uint32_t arg2);
|
||||
uint32_t EmitFPMedTri32(EmitterState& state, uint32_t arg0, uint32_t arg1, uint32_t arg2);
|
||||
@@ -178,6 +180,9 @@ inline constexpr auto EmitFPRoundEven32 = EmitGlsl<GLSLstd450RoundEven, IR::Type
|
||||
inline constexpr auto EmitFPFloor32 = EmitGlsl<GLSLstd450Floor, IR::Type::F32, uint32_t>;
|
||||
inline constexpr auto EmitFPCeil32 = EmitGlsl<GLSLstd450Ceil, IR::Type::F32, uint32_t>;
|
||||
inline constexpr auto EmitFPTrunc32 = EmitGlsl<GLSLstd450Trunc, IR::Type::F32, uint32_t>;
|
||||
inline constexpr auto EmitFPFloor64 = EmitGlsl<GLSLstd450Floor, IR::Type::F64, uint32_t>;
|
||||
inline constexpr auto EmitFPCeil64 = EmitGlsl<GLSLstd450Ceil, IR::Type::F64, uint32_t>;
|
||||
inline constexpr auto EmitFPTrunc64 = EmitGlsl<GLSLstd450Trunc, IR::Type::F64, uint32_t>;
|
||||
inline constexpr auto EmitFPFract32 = EmitGlsl<GLSLstd450Fract, IR::Type::F32, uint32_t>;
|
||||
inline constexpr auto EmitFPFract64 = EmitGlsl<GLSLstd450Fract, IR::Type::F64, uint32_t>;
|
||||
uint32_t EmitFPSin(EmitterState& state, uint32_t arg0);
|
||||
|
||||
Reference in New Issue
Block a user