Skip to content

Commit b5c78af

Browse files
committed
adding macro
1 parent cfebdfd commit b5c78af

1 file changed

Lines changed: 41 additions & 71 deletions

File tree

tools/clang/unittests/HLSLExec/LongVectors.cpp

Lines changed: 41 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#include <DirectXPackedVector.h>
2-
#include <cmath>
31
#ifndef NOMINMAX
42
#define NOMINMAX 1
53
#endif
@@ -105,6 +103,21 @@ static constexpr Operation Operations[] = {
105103
#include "LongVectorOps.def"
106104
};
107105

106+
#define OP_WITH_OUT_PARAM(OPERATION, TYPE, IMPL) \
107+
template <> struct ExpectedBuilder<OpType::OPERATION, TYPE> { \
108+
static std::vector<TYPE> buildExpected(Op<OpType::OPERATION, TYPE, 1>, \
109+
const InputSets<TYPE> &Inputs) { \
110+
DXASSERT_NOMSG(Inputs.size() == 1); \
111+
size_t VectorSize = Inputs[0].size(); \
112+
std::vector<TYPE> Expected; \
113+
Expected.resize(VectorSize * 2); \
114+
for (size_t I = 0; I < VectorSize; ++I) { \
115+
IMPL \
116+
} \
117+
return Expected; \
118+
} \
119+
};
120+
108121
constexpr const Operation &getOperation(OpType Op) {
109122
if (Op < OpType::NumOpTypes)
110123
return Operations[unsigned(Op)];
@@ -1017,41 +1030,21 @@ DEFAULT_OP_1(OpType::Log2, (std::log2(A)));
10171030
// with special logic. Frexp is only supported for fp32 values.
10181031
template <> struct Op<OpType::Frexp, float, 1> : DefaultValidation<float> {};
10191032

1020-
template <> struct ExpectedBuilder<OpType::Frexp, float> {
1021-
static std::vector<float> buildExpected(Op<OpType::Frexp, float, 1> &,
1022-
const InputSets<float> &Inputs) {
1023-
DXASSERT_NOMSG(Inputs.size() == 1);
1024-
1025-
// Expected values size is doubled. In the first half we store the
1026-
// Mantissas and in the second half we store the Exponents. This way we
1027-
// can leverage the existing logic which verify expected values in a
1028-
// single vector. We just need to make sure that we organize the output in
1029-
// the same way in the shader and when we read it back.
1030-
1031-
size_t VectorSize = Inputs[0].size();
1032-
1033-
std::vector<float> Expected;
1034-
Expected.resize(VectorSize * 2);
1035-
1036-
for (size_t I = 0; I < VectorSize; ++I) {
1037-
int Exp = 0;
1038-
float Man = std::frexp(Inputs[0][I], &Exp);
1033+
OP_WITH_OUT_PARAM(Frexp, float, {
1034+
int Exp = 0;
1035+
float Man = std::frexp(Inputs[0][I], &Exp);
10391036

1040-
// std::frexp returns a signed mantissa. But the HLSL implmentation
1041-
// returns an unsigned mantissa.
1042-
Man = std::abs(Man);
1037+
// std::frexp returns a signed mantissa. But the HLSL implmentation
1038+
// returns an unsigned mantissa.
1039+
Man = std::abs(Man);
10431040

1044-
Expected[I] = Man;
1041+
Expected[I] = Man;
10451042

1046-
// std::frexp returns the exponent as an int, but HLSL stores it as a
1047-
// float. However, the HLSL exponents fractional component is always 0.
1048-
// So it can conversion between float and int is safe.
1049-
Expected[I + VectorSize] = static_cast<float>(Exp);
1050-
}
1051-
1052-
return Expected;
1053-
}
1054-
};
1043+
// std::frexp returns the exponent as an int, but HLSL stores it as a
1044+
// float. However, the HLSL exponents fractional component is always 0.
1045+
// So it can conversion between float and int is safe.
1046+
Expected[I + VectorSize] = static_cast<float>(Exp);
1047+
});
10551048

10561049
//
10571050
// Binary Comparison
@@ -1240,43 +1233,20 @@ FLOAT_SPECIAL_OP(OpType::IsNan, (std::isnan(A)));
12401233

12411234
template <typename T> struct Op<OpType::ModF, T, 1> : DefaultValidation<T> {};
12421235

1243-
template <> struct ExpectedBuilder<OpType::ModF, float> {
1244-
static std::vector<float> buildExpected(Op<OpType::ModF, float, 1>,
1245-
const InputSets<float> &Inputs) {
1246-
DXASSERT_NOMSG(Inputs.size() == 1);
1247-
size_t VectorSize = Inputs[0].size();
1248-
std::vector<float> Expected;
1249-
Expected.resize(VectorSize * 2);
1250-
for (size_t I = 0; I < VectorSize; ++I) {
1251-
float Exp = 0;
1252-
float Man = std::modf(Inputs[0][I], &Exp);
1253-
Expected[I] = Man;
1254-
Expected[I + VectorSize] = static_cast<float>(Exp);
1255-
}
1256-
1257-
return Expected;
1258-
}
1259-
};
1260-
1261-
template <> struct ExpectedBuilder<OpType::ModF, HLSLHalf_t> {
1262-
static std::vector<HLSLHalf_t> buildExpected(Op<OpType::ModF, HLSLHalf_t, 1>,
1263-
const InputSets<HLSLHalf_t> &Inputs) {
1264-
DXASSERT_NOMSG(Inputs.size() == 1);
1265-
size_t VectorSize = Inputs[0].size();
1266-
std::vector<HLSLHalf_t> Expected;
1267-
Expected.resize(VectorSize * 2);
1268-
for (size_t I = 0; I < VectorSize; ++I) {
1269-
float Exp = 0.0f;
1270-
float Inp = float(Inputs[0][I]);
1271-
float Man = std::modf(Inp, &Exp);
1272-
Expected[I] = HLSLHalf_t(Man);
1273-
Expected[I + VectorSize] = HLSLHalf_t(Exp);
1274-
}
1275-
1276-
return Expected;
1277-
}
1278-
};
1279-
1236+
OP_WITH_OUT_PARAM(ModF, float, {
1237+
float Exp = 0.0f;
1238+
float Man = std::modf(Inputs[0][I], &Exp);
1239+
Expected[I] = Man;
1240+
Expected[I + VectorSize] = Exp;
1241+
});
1242+
1243+
OP_WITH_OUT_PARAM(ModF, HLSLHalf_t, {
1244+
float Exp = 0.0f;
1245+
float Inp = float(Inputs[0][I]);
1246+
float Man = std::modf(Inp, &Exp);
1247+
Expected[I] = HLSLHalf_t(Man);
1248+
Expected[I + VectorSize] = HLSLHalf_t(Exp);
1249+
});
12801250

12811251
//
12821252
// dispatchTest

0 commit comments

Comments
 (0)