261 lines
6.6 KiB
HLSL
261 lines
6.6 KiB
HLSL
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#if COMPILER_SUPPORTS_HLSL2021
|
|
|
|
#define DECLARE_VEC_VEC_OP(DFOperation) \
|
|
FDFType DFOperation(FDFType Lhs, FDFType Rhs); \
|
|
FDFType DFOperation(FDFType Lhs, FFloatType Rhs); \
|
|
FDFType DFOperation(FDFType Lhs, FDFScalar Rhs); \
|
|
FDFType DFOperation(FDFType Lhs, float Rhs);
|
|
|
|
struct FDFType;
|
|
FDFType DFBroadcastFunc(FDFScalar V);
|
|
FFloatType DFBroadcastFunc(float V);
|
|
FDFScalar DFGetComponent(FDFType V, int C);
|
|
FDFType DFNegate(FDFType In);
|
|
DECLARE_VEC_VEC_OP(DFAdd);
|
|
DECLARE_VEC_VEC_OP(DFSubtract);
|
|
DECLARE_VEC_VEC_OP(DFMultiply);
|
|
DECLARE_VEC_VEC_OP(DFDivide);
|
|
FBoolType DFGreater(FDFType Lhs, FFloatType Rhs);
|
|
FBoolType DFLess(FDFType Lhs, FFloatType Rhs);
|
|
FFloatType DFDemote(FDFType In);
|
|
|
|
#undef DECLARE_VEC_VEC_OP
|
|
|
|
#endif
|
|
|
|
struct FDFType
|
|
{
|
|
FFloatType High;
|
|
FFloatType Low;
|
|
|
|
#if COMPILER_SUPPORTS_HLSL2021
|
|
|
|
#define DECLARE_VEC_VEC_OP(Operator, DFOperation) \
|
|
FDFType Operator(FDFType Rhs) { return DFOperation(this, Rhs); } \
|
|
FDFType Operator(FFloatType Rhs) { return DFOperation(this, Rhs); } \
|
|
FDFType Operator(FDFScalar Rhs) { return DFOperation(this, Rhs); } \
|
|
FDFType Operator(float Rhs) { return DFOperation(this, Rhs); }
|
|
|
|
//Commented out until supported by HlslParser
|
|
//FDFScalar operator[](int idx) { return DFGetComponent(this, idx); }
|
|
//FDFType operator-() { return DFNegate(this); }
|
|
////DECLARE_VEC_VEC_OP(operator+, DFAdd)
|
|
////DECLARE_VEC_VEC_OP(operator-, DFSubtract)
|
|
////DECLARE_VEC_VEC_OP(operator*, DFMultiply)
|
|
////DECLARE_VEC_VEC_OP(operator/, DFDivide)
|
|
//FBoolType operator>(FFloatType Rhs) { return DFGreater(this, Rhs); }
|
|
//FBoolType operator<(FFloatType Rhs) { return DFLess(this, Rhs); }
|
|
|
|
FFloatType Demote() { return DFDemote(this); }
|
|
|
|
#undef DECLARE_VEC_VEC_OP
|
|
|
|
#endif
|
|
};
|
|
|
|
FDFScalar DFGetComponent(FDFType V, int C) { return MakeDFScalar(V.High[C], V.Low[C]); }
|
|
|
|
#include "DoubleFloatOperations.ush"
|
|
|
|
FDFType DFBroadcastFunc(FDFScalar V)
|
|
{
|
|
const FFloatType High = V.High;
|
|
const FFloatType Low = V.Low;
|
|
return DFConstructor(High, Low);
|
|
}
|
|
|
|
FFloatType DFBroadcastFunc(float V)
|
|
{
|
|
const FFloatType Single = V;
|
|
return Single;
|
|
}
|
|
|
|
#define DEFINE_BROADCASTED_OP(FReturnType, DFOperation) \
|
|
FReturnType DFOperation(FDFScalar Lhs, FDFType Rhs) { return DFOperation(DFBroadcastFunc(Lhs), Rhs); } \
|
|
FReturnType DFOperation(float Lhs, FDFType Rhs) { return DFOperation(DFBroadcastFunc(Lhs), Rhs); } \
|
|
FReturnType DFOperation(FDFScalar Lhs, FFloatType Rhs) { return DFOperation(DFBroadcastFunc(Lhs), Rhs); } \
|
|
FReturnType DFOperation(float Lhs, FFloatType Rhs) { return DFOperation(DFBroadcastFunc(Lhs), Rhs); } \
|
|
FReturnType DFOperation(FDFType Lhs, FDFScalar Rhs) { return DFOperation(Lhs, DFBroadcastFunc(Rhs)); } \
|
|
FReturnType DFOperation(FDFType Lhs, float Rhs) { return DFOperation(Lhs, DFBroadcastFunc(Rhs)); } \
|
|
FReturnType DFOperation(FFloatType Lhs, FDFScalar Rhs) { return DFOperation(Lhs, DFBroadcastFunc(Rhs)); } \
|
|
FReturnType DFOperation(FFloatType Lhs, float Rhs) { return DFOperation(Lhs, DFBroadcastFunc(Rhs)); }
|
|
|
|
DEFINE_BROADCASTED_OP(FDFType , DFAdd)
|
|
DEFINE_BROADCASTED_OP(FFloatType, DFAddDemote)
|
|
DEFINE_BROADCASTED_OP(FDFType , DFFastAdd)
|
|
DEFINE_BROADCASTED_OP(FFloatType, DFFastAddDemote)
|
|
DEFINE_BROADCASTED_OP(FDFType , DFSubtract)
|
|
DEFINE_BROADCASTED_OP(FFloatType, DFSubtractDemote)
|
|
DEFINE_BROADCASTED_OP(FDFType , DFFastSubtract)
|
|
DEFINE_BROADCASTED_OP(FFloatType, DFFastSubtractDemote)
|
|
DEFINE_BROADCASTED_OP(FDFType , DFMultiply)
|
|
DEFINE_BROADCASTED_OP(FFloatType, DFMultiplyDemote)
|
|
DEFINE_BROADCASTED_OP(FDFType , DFDivide)
|
|
DEFINE_BROADCASTED_OP(FDFType , DFFastDivide)
|
|
DEFINE_BROADCASTED_OP(FFloatType, DFFastDivideDemote)
|
|
|
|
|
|
#undef DEFINE_BROADCASTED_OP
|
|
|
|
FDFType DFDivideByPow2(FDFType Lhs, float Rhs)
|
|
{
|
|
FFloatType RhsVect = Rhs;
|
|
return DFDivideByPow2(Lhs, RhsVect);
|
|
}
|
|
|
|
FDFScalar DFVectorSum(FDFType V)
|
|
{
|
|
#if UE_DF_FORCE_FP32_OPS
|
|
float Result = V.High[0] + V.High[1];
|
|
[unroll]
|
|
for (int i = 2; i < GNumComponents; ++i)
|
|
{
|
|
Result = Result + V.High[i];
|
|
}
|
|
return DFPromote(Result);
|
|
#else
|
|
FDFScalar Result = DFAdd(DFGetComponent(V, 0), DFGetComponent(V, 1));
|
|
[unroll]
|
|
for (int i = 2; i < GNumComponents; ++i)
|
|
{
|
|
Result = DFAdd(Result, DFGetComponent(V, i));
|
|
}
|
|
return Result;
|
|
#endif
|
|
}
|
|
|
|
FDFScalar DFFastVectorSum(FDFType V)
|
|
{
|
|
#if UE_DF_FORCE_FP32_OPS
|
|
return DFVectorSum(V);
|
|
#else
|
|
FDFScalar Result = DFFastAdd(DFGetComponent(V, 0), DFGetComponent(V, 1));
|
|
[unroll]
|
|
for (int i = 2; i < GNumComponents; ++i)
|
|
{
|
|
Result = DFFastAdd(Result, DFGetComponent(V, i));
|
|
}
|
|
return Result;
|
|
#endif
|
|
}
|
|
|
|
FDFScalar DFDot(FDFType Lhs, FFloatType Rhs)
|
|
{
|
|
#if UE_DF_FORCE_FP32_OPS
|
|
return DFPromote(dot(Lhs.High, Rhs));
|
|
#else
|
|
return DFFastVectorSum(DFMultiply(Lhs, Rhs));
|
|
#endif
|
|
}
|
|
FDFScalar DFDot(FFloatType Lhs, FDFType Rhs) { return DFDot(Rhs, Lhs); }
|
|
FDFScalar DFDot(FDFType Lhs, FDFType Rhs)
|
|
{
|
|
#if UE_DF_FORCE_FP32_OPS
|
|
return DFPromote(dot(Lhs.High, Rhs.High));
|
|
#else
|
|
return DFFastVectorSum(DFMultiply(Lhs, Rhs));
|
|
#endif
|
|
}
|
|
|
|
FFloatType DFDotDemote(FDFType Lhs, FFloatType Rhs)
|
|
{
|
|
#if UE_DF_FORCE_FP32_OPS
|
|
return dot(Lhs.High, Rhs);
|
|
#else
|
|
return DFDemote(DFFastVectorSum(DFMultiply(Lhs, Rhs)));
|
|
#endif
|
|
}
|
|
FFloatType DFDotDemote(FFloatType Lhs, FDFType Rhs) { return DFDotDemote(Rhs, Lhs); }
|
|
FFloatType DFDotDemote(FDFType Lhs, FDFType Rhs)
|
|
{
|
|
#if UE_DF_FORCE_FP32_OPS
|
|
return dot(Lhs.High, Rhs.High);
|
|
#else
|
|
return DFDemote(DFFastVectorSum(DFMultiply(Lhs, Rhs)));
|
|
#endif
|
|
}
|
|
|
|
FDFScalar DFLengthSqr(FFloatType V)
|
|
{
|
|
#if UE_DF_FORCE_FP32_OPS
|
|
return DFPromote(dot(V, V));
|
|
#else
|
|
return DFFastVectorSum(DFSqr(V));
|
|
#endif
|
|
}
|
|
|
|
FDFScalar DFLength(FFloatType V)
|
|
{
|
|
#if UE_DF_FORCE_FP32_OPS
|
|
return DFPromote(length(V));
|
|
#else
|
|
return DFSqrt(DFLengthSqr(V));
|
|
#endif
|
|
}
|
|
|
|
// DF_TODO: test potential precision issues
|
|
|
|
FDFScalar DFLengthSqr(FDFType V)
|
|
{
|
|
#if UE_DF_FORCE_FP32_OPS
|
|
return DFPromote(dot(V.High, V.High));
|
|
#else
|
|
return DFFastVectorSum(DFSqr(V));
|
|
#endif
|
|
}
|
|
FDFScalar DFLength(FDFType V)
|
|
{
|
|
#if UE_DF_FORCE_FP32_OPS
|
|
return DFPromote(length(V.High));
|
|
#else
|
|
return DFSqrt(DFLengthSqr(V));
|
|
#endif
|
|
}
|
|
|
|
float DFLengthDemote(FDFType V)
|
|
{
|
|
#if UE_DF_FORCE_FP32_OPS
|
|
return length(V.High);
|
|
#else
|
|
return DFSqrtDemote(DFLengthSqr(V));
|
|
#endif
|
|
}
|
|
|
|
float DFRcpLengthDemote(FDFType V)
|
|
{
|
|
#if UE_DF_FORCE_FP32_OPS
|
|
return rcp(length(V.High));
|
|
#else
|
|
return DFRsqrtDemote(DFLengthSqr(V));
|
|
#endif
|
|
}
|
|
|
|
FDFType DFNormalize(FFloatType V)
|
|
{
|
|
#if UE_DF_FORCE_FP32_OPS
|
|
return DFPromote(normalize(V));
|
|
#else
|
|
return DFDivide(V, DFBroadcastFunc(DFLength(V)));
|
|
#endif
|
|
}
|
|
|
|
FDFType DFNormalize(FDFType V)
|
|
{
|
|
#if UE_DF_FORCE_FP32_OPS
|
|
return DFPromote(normalize(V.High));
|
|
#else
|
|
return DFFastDivide(V, DFLength(V));
|
|
#endif
|
|
}
|
|
|
|
FFloatType DFNormalizeDemote(FDFType V)
|
|
{
|
|
#if UE_DF_FORCE_FP32_OPS
|
|
return normalize(V.High);
|
|
#else
|
|
return V.High / length(V.High);
|
|
#endif
|
|
}
|