Files
UnrealEngine/Engine/Shaders/Private/DoubleFloatVectorDefinition.ush
2025-05-18 13:04:45 +08:00

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
}