Half tests (#911)
- Adding half tests for unary,binary,tertiary math operations - Add 'exec-future' option for hcttest
This commit is contained in:
Родитель
1d4509f35d
Коммит
ecf0307963
|
@ -563,6 +563,18 @@ public:
|
|||
TEST_METHOD_PROPERTY(L"DataSource", L"Table:ShaderOpArithTable.xml#TertiaryFloatOpTable")
|
||||
END_TEST_METHOD()
|
||||
|
||||
BEGIN_TEST_METHOD(UnaryHalfOpTest)
|
||||
TEST_METHOD_PROPERTY(L"DataSource", L"Table:ShaderOpArithTable.xml#UnaryHalfOpTable")
|
||||
TEST_METHOD_PROPERTY(L"Priority", L"2") // Remove this line once warp supports this feature in Shader Model 6.2
|
||||
END_TEST_METHOD()
|
||||
BEGIN_TEST_METHOD(BinaryHalfOpTest)
|
||||
TEST_METHOD_PROPERTY(L"DataSource", L"Table:ShaderOpArithTable.xml#BinaryHalfOpTable")
|
||||
TEST_METHOD_PROPERTY(L"Priority", L"2") // Remove this line once warp supports this feature in Shader Model 6.2
|
||||
END_TEST_METHOD()
|
||||
BEGIN_TEST_METHOD(TertiaryHalfOpTest)
|
||||
TEST_METHOD_PROPERTY(L"DataSource", L"Table:ShaderOpArithTable.xml#TertiaryHalfOpTable")
|
||||
TEST_METHOD_PROPERTY(L"Priority", L"2") // Remove this line once warp supports this feature in Shader Model 6.2
|
||||
END_TEST_METHOD()
|
||||
BEGIN_TEST_METHOD(UnaryIntOpTest)
|
||||
TEST_METHOD_PROPERTY(L"DataSource", L"Table:ShaderOpArithTable.xml#UnaryIntOpTable")
|
||||
END_TEST_METHOD()
|
||||
|
@ -2495,6 +2507,25 @@ struct STertiaryFPOp {
|
|||
float output;
|
||||
};
|
||||
|
||||
struct SUnaryHalfOp {
|
||||
uint16_t input;
|
||||
uint16_t output;
|
||||
};
|
||||
|
||||
struct SBinaryHalfOp {
|
||||
uint16_t input1;
|
||||
uint16_t input2;
|
||||
uint16_t output1;
|
||||
uint16_t output2;
|
||||
};
|
||||
|
||||
struct STertiaryHalfOp {
|
||||
uint16_t input1;
|
||||
uint16_t input2;
|
||||
uint16_t input3;
|
||||
uint16_t output;
|
||||
};
|
||||
|
||||
struct SUnaryIntOp {
|
||||
int input;
|
||||
int output;
|
||||
|
@ -2548,7 +2579,6 @@ struct SMsad4 {
|
|||
XMUINT4 accum;
|
||||
XMUINT4 result;
|
||||
};
|
||||
|
||||
// Parameter representation for taef data-driven tests
|
||||
struct TableParameter {
|
||||
LPCWSTR m_name;
|
||||
|
@ -2719,8 +2749,8 @@ public:
|
|||
static TableParameter UnaryFPOpParameters[] = {
|
||||
{ L"ShaderOp.Target", TableParameter::STRING, true },
|
||||
{ L"ShaderOp.Text", TableParameter::STRING, true },
|
||||
{ L"Validation.Input1", TableParameter::STRING_TABLE, true },
|
||||
{ L"Validation.Expected1", TableParameter::STRING_TABLE, true },
|
||||
{ L"Validation.Input1", TableParameter::FLOAT_TABLE, true },
|
||||
{ L"Validation.Expected1", TableParameter::FLOAT_TABLE, true },
|
||||
{ L"Validation.Type", TableParameter::STRING, true },
|
||||
{ L"Validation.Tolerance", TableParameter::DOUBLE, true },
|
||||
{ L"Warp.Version", TableParameter::UINT, false }
|
||||
|
@ -2729,10 +2759,10 @@ static TableParameter UnaryFPOpParameters[] = {
|
|||
static TableParameter BinaryFPOpParameters[] = {
|
||||
{ L"ShaderOp.Target", TableParameter::STRING, true },
|
||||
{ L"ShaderOp.Text", TableParameter::STRING, true },
|
||||
{ L"Validation.Input1", TableParameter::STRING_TABLE, true },
|
||||
{ L"Validation.Input2", TableParameter::STRING_TABLE, true },
|
||||
{ L"Validation.Expected1", TableParameter::STRING_TABLE, true },
|
||||
{ L"Validation.Expected2", TableParameter::STRING_TABLE, false },
|
||||
{ L"Validation.Input1", TableParameter::FLOAT_TABLE, true },
|
||||
{ L"Validation.Input2", TableParameter::FLOAT_TABLE, true },
|
||||
{ L"Validation.Expected1", TableParameter::FLOAT_TABLE, true },
|
||||
{ L"Validation.Expected2", TableParameter::FLOAT_TABLE, false },
|
||||
{ L"Validation.Type", TableParameter::STRING, true },
|
||||
{ L"Validation.Tolerance", TableParameter::DOUBLE, true },
|
||||
};
|
||||
|
@ -2740,10 +2770,42 @@ static TableParameter BinaryFPOpParameters[] = {
|
|||
static TableParameter TertiaryFPOpParameters[] = {
|
||||
{ L"ShaderOp.Target", TableParameter::STRING, true },
|
||||
{ L"ShaderOp.Text", TableParameter::STRING, true },
|
||||
{ L"Validation.Input1", TableParameter::STRING_TABLE, true },
|
||||
{ L"Validation.Input2", TableParameter::STRING_TABLE, true },
|
||||
{ L"Validation.Input3", TableParameter::STRING_TABLE, true },
|
||||
{ L"Validation.Expected1", TableParameter::STRING_TABLE, true },
|
||||
{ L"Validation.Input1", TableParameter::FLOAT_TABLE, true },
|
||||
{ L"Validation.Input2", TableParameter::FLOAT_TABLE, true },
|
||||
{ L"Validation.Input3", TableParameter::FLOAT_TABLE, true },
|
||||
{ L"Validation.Expected1", TableParameter::FLOAT_TABLE, true },
|
||||
{ L"Validation.Type", TableParameter::STRING, true },
|
||||
{ L"Validation.Tolerance", TableParameter::DOUBLE, true },
|
||||
};
|
||||
|
||||
static TableParameter UnaryHalfOpParameters[] = {
|
||||
{ L"ShaderOp.Target", TableParameter::STRING, true },
|
||||
{ L"ShaderOp.Text", TableParameter::STRING, true },
|
||||
{ L"Validation.Input1", TableParameter::HALF_TABLE, true },
|
||||
{ L"Validation.Expected1", TableParameter::HALF_TABLE, true },
|
||||
{ L"Validation.Type", TableParameter::STRING, true },
|
||||
{ L"Validation.Tolerance", TableParameter::DOUBLE, true },
|
||||
{ L"Warp.Version", TableParameter::UINT, false }
|
||||
};
|
||||
|
||||
static TableParameter BinaryHalfOpParameters[] = {
|
||||
{ L"ShaderOp.Target", TableParameter::STRING, true },
|
||||
{ L"ShaderOp.Text", TableParameter::STRING, true },
|
||||
{ L"Validation.Input1", TableParameter::HALF_TABLE, true },
|
||||
{ L"Validation.Input2", TableParameter::HALF_TABLE, true },
|
||||
{ L"Validation.Expected1", TableParameter::HALF_TABLE, true },
|
||||
{ L"Validation.Expected2", TableParameter::HALF_TABLE, false },
|
||||
{ L"Validation.Type", TableParameter::STRING, true },
|
||||
{ L"Validation.Tolerance", TableParameter::DOUBLE, true },
|
||||
};
|
||||
|
||||
static TableParameter TertiaryHalfOpParameters[] = {
|
||||
{ L"ShaderOp.Target", TableParameter::STRING, true },
|
||||
{ L"ShaderOp.Text", TableParameter::STRING, true },
|
||||
{ L"Validation.Input1", TableParameter::HALF_TABLE, true },
|
||||
{ L"Validation.Input2", TableParameter::HALF_TABLE, true },
|
||||
{ L"Validation.Input3", TableParameter::HALF_TABLE, true },
|
||||
{ L"Validation.Expected1", TableParameter::HALF_TABLE, true },
|
||||
{ L"Validation.Type", TableParameter::STRING, true },
|
||||
{ L"Validation.Tolerance", TableParameter::DOUBLE, true },
|
||||
};
|
||||
|
@ -3146,7 +3208,10 @@ static HRESULT ParseTableRow(TableParameter *table, unsigned int size) {
|
|||
for (size_t j = 0, end = tempTable.GetSize(); j != end; ++j) {
|
||||
float val;
|
||||
ParseDataToFloat(tempTable[j], val);
|
||||
table[i].m_halfTable[j] = st::ConvertFloat32ToFloat16(val);
|
||||
if (isdenorm(val))
|
||||
table[i].m_halfTable[j] = signbit(val) ? Float16NegDenorm : Float16PosDenorm;
|
||||
else
|
||||
table[i].m_halfTable[j] = ConvertFloat32ToFloat16(val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -3221,6 +3286,22 @@ static void VerifyOutputWithExpectedValueFloat(
|
|||
}
|
||||
}
|
||||
|
||||
static void VerifyOutputWithExpectedValueHalf(
|
||||
uint16_t output, uint16_t ref, LPCWSTR type, double tolerance) {
|
||||
if (_wcsicmp(type, L"Relative") == 0) {
|
||||
VERIFY_IS_TRUE(CompareHalfRelativeEpsilon(output, ref, tolerance));
|
||||
}
|
||||
else if (_wcsicmp(type, L"Epsilon") == 0) {
|
||||
VERIFY_IS_TRUE(CompareHalfEpsilon(output, ref, tolerance));
|
||||
}
|
||||
else if (_wcsicmp(type, L"ULP") == 0) {
|
||||
VERIFY_IS_TRUE(CompareHalfULP(output, ref, (int)tolerance));
|
||||
}
|
||||
else {
|
||||
LogErrorFmt(L"Failed to read comparison type %S", type);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ExecutionTest, UnaryFloatOpTest) {
|
||||
WEX::TestExecution::SetVerifyOutput verifySettings(
|
||||
WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures);
|
||||
|
@ -3245,10 +3326,10 @@ TEST_F(ExecutionTest, UnaryFloatOpTest) {
|
|||
return;
|
||||
}
|
||||
|
||||
std::vector<WEX::Common::String> *Validation_Input =
|
||||
&(handler.GetTableParamByName(L"Validation.Input1")->m_StringTable);
|
||||
std::vector<WEX::Common::String> *Validation_Expected =
|
||||
&(handler.GetTableParamByName(L"Validation.Expected1")->m_StringTable);
|
||||
std::vector<float> *Validation_Input =
|
||||
&(handler.GetTableParamByName(L"Validation.Input1")->m_floatTable);
|
||||
std::vector<float> *Validation_Expected =
|
||||
&(handler.GetTableParamByName(L"Validation.Expected1")->m_floatTable);
|
||||
|
||||
LPCWSTR Validation_Type = handler.GetTableParamByName(L"Validation.Type")->m_str;
|
||||
double Validation_Tolerance = handler.GetTableParamByName(L"Validation.Tolerance")->m_double;
|
||||
|
@ -3266,10 +3347,7 @@ TEST_F(ExecutionTest, UnaryFloatOpTest) {
|
|||
SUnaryFPOp *pPrimitives = (SUnaryFPOp *)Data.data();
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
SUnaryFPOp *p = &pPrimitives[i];
|
||||
PCWSTR str = (*Validation_Input)[i % Validation_Input->size()];
|
||||
float val;
|
||||
VERIFY_SUCCEEDED(ParseDataToFloat(str, val));
|
||||
p->input = val;
|
||||
p->input = (*Validation_Input)[i % Validation_Input->size()];
|
||||
}
|
||||
// use shader from data table
|
||||
pShaderOp->Shaders.at(0).Target = Target.m_psz;
|
||||
|
@ -3283,9 +3361,7 @@ TEST_F(ExecutionTest, UnaryFloatOpTest) {
|
|||
WEX::TestExecution::DisableVerifyExceptions dve;
|
||||
for (unsigned i = 0; i < count; ++i) {
|
||||
SUnaryFPOp *p = &pPrimitives[i];
|
||||
LPCWSTR str = (*Validation_Expected)[i % Validation_Expected->size()];
|
||||
float val;
|
||||
VERIFY_SUCCEEDED(ParseDataToFloat(str, val));
|
||||
float val = (*Validation_Expected)[i % Validation_Expected->size()];
|
||||
LogCommentFmt(
|
||||
L"element #%u, input = %6.8f, output = %6.8f, expected = %6.8f", i,
|
||||
p->input, p->output, val);
|
||||
|
@ -3312,16 +3388,16 @@ TEST_F(ExecutionTest, BinaryFloatOpTest) {
|
|||
CW2A Target(handler.GetTableParamByName(L"ShaderOp.Target")->m_str);
|
||||
CW2A Text(handler.GetTableParamByName(L"ShaderOp.Text")->m_str);
|
||||
|
||||
std::vector<WEX::Common::String> *Validation_Input1 =
|
||||
&(handler.GetTableParamByName(L"Validation.Input1")->m_StringTable);
|
||||
std::vector<WEX::Common::String> *Validation_Input2 =
|
||||
&(handler.GetTableParamByName(L"Validation.Input2")->m_StringTable);
|
||||
std::vector<float> *Validation_Input1 =
|
||||
&(handler.GetTableParamByName(L"Validation.Input1")->m_floatTable);
|
||||
std::vector<float> *Validation_Input2 =
|
||||
&(handler.GetTableParamByName(L"Validation.Input2")->m_floatTable);
|
||||
|
||||
std::vector<WEX::Common::String> *Validation_Expected1 =
|
||||
&(handler.GetTableParamByName(L"Validation.Expected1")->m_StringTable);
|
||||
std::vector<float> *Validation_Expected1 =
|
||||
&(handler.GetTableParamByName(L"Validation.Expected1")->m_floatTable);
|
||||
|
||||
std::vector<WEX::Common::String> *Validation_Expected2 =
|
||||
&(handler.GetTableParamByName(L"Validation.Expected2")->m_StringTable);
|
||||
std::vector<float> *Validation_Expected2 =
|
||||
&(handler.GetTableParamByName(L"Validation.Expected2")->m_floatTable);
|
||||
|
||||
LPCWSTR Validation_Type = handler.GetTableParamByName(L"Validation.Type")->m_str;
|
||||
double Validation_Tolerance = handler.GetTableParamByName(L"Validation.Tolerance")->m_double;
|
||||
|
@ -3338,13 +3414,8 @@ TEST_F(ExecutionTest, BinaryFloatOpTest) {
|
|||
SBinaryFPOp *pPrimitives = (SBinaryFPOp *)Data.data();
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
SBinaryFPOp *p = &pPrimitives[i];
|
||||
PCWSTR str1 = (*Validation_Input1)[i % Validation_Input1->size()];
|
||||
PCWSTR str2 = (*Validation_Input2)[i % Validation_Input2->size()];
|
||||
float val1, val2;
|
||||
VERIFY_SUCCEEDED(ParseDataToFloat(str1, val1));
|
||||
VERIFY_SUCCEEDED(ParseDataToFloat(str2, val2));
|
||||
p->input1 = val1;
|
||||
p->input2 = val2;
|
||||
p->input1 = (*Validation_Input1)[i % Validation_Input1->size()];
|
||||
p->input2 = (*Validation_Input2)[i % Validation_Input2->size()];
|
||||
}
|
||||
|
||||
// use shader from data table
|
||||
|
@ -3361,11 +3432,8 @@ TEST_F(ExecutionTest, BinaryFloatOpTest) {
|
|||
if (numExpected == 2) {
|
||||
for (unsigned i = 0; i < count; ++i) {
|
||||
SBinaryFPOp *p = &pPrimitives[i];
|
||||
LPCWSTR str1 = (*Validation_Expected1)[i % Validation_Expected1->size()];
|
||||
LPCWSTR str2 = (*Validation_Expected2)[i % Validation_Expected2->size()];
|
||||
float val1, val2;
|
||||
VERIFY_SUCCEEDED(ParseDataToFloat(str1, val1));
|
||||
VERIFY_SUCCEEDED(ParseDataToFloat(str2, val2));
|
||||
float val1 = (*Validation_Expected1)[i % Validation_Expected1->size()];
|
||||
float val2 = (*Validation_Expected2)[i % Validation_Expected2->size()];
|
||||
LogCommentFmt(L"element #%u, input1 = %6.8f, input2 = %6.8f, output1 = "
|
||||
L"%6.8f, expected1 = %6.8f, output2 = %6.8f, expected2 = %6.8f",
|
||||
i, p->input1, p->input2, p->output1, val1, p->output2,
|
||||
|
@ -3379,9 +3447,7 @@ TEST_F(ExecutionTest, BinaryFloatOpTest) {
|
|||
else if (numExpected == 1) {
|
||||
for (unsigned i = 0; i < count; ++i) {
|
||||
SBinaryFPOp *p = &pPrimitives[i];
|
||||
LPCWSTR str1 = (*Validation_Expected1)[i % Validation_Expected1->size()];
|
||||
float val1;
|
||||
VERIFY_SUCCEEDED(ParseDataToFloat(str1, val1));
|
||||
float val1 = (*Validation_Expected1)[i % Validation_Expected1->size()];
|
||||
LogCommentFmt(L"element #%u, input1 = %6.8f, input2 = %6.8f, output1 = "
|
||||
L"%6.8f, expected1 = %6.8f",
|
||||
i, p->input1, p->input2, p->output1, val1);
|
||||
|
@ -3414,15 +3480,15 @@ TEST_F(ExecutionTest, TertiaryFloatOpTest) {
|
|||
CW2A Target(handler.GetTableParamByName(L"ShaderOp.Target")->m_str);
|
||||
CW2A Text(handler.GetTableParamByName(L"ShaderOp.Text")->m_str);
|
||||
|
||||
std::vector<WEX::Common::String> *Validation_Input1 =
|
||||
&(handler.GetTableParamByName(L"Validation.Input1")->m_StringTable);
|
||||
std::vector<WEX::Common::String> *Validation_Input2 =
|
||||
&(handler.GetTableParamByName(L"Validation.Input2")->m_StringTable);
|
||||
std::vector<WEX::Common::String> *Validation_Input3 =
|
||||
&(handler.GetTableParamByName(L"Validation.Input3")->m_StringTable);
|
||||
std::vector<float> *Validation_Input1 =
|
||||
&(handler.GetTableParamByName(L"Validation.Input1")->m_floatTable);
|
||||
std::vector<float> *Validation_Input2 =
|
||||
&(handler.GetTableParamByName(L"Validation.Input2")->m_floatTable);
|
||||
std::vector<float> *Validation_Input3 =
|
||||
&(handler.GetTableParamByName(L"Validation.Input3")->m_floatTable);
|
||||
|
||||
std::vector<WEX::Common::String> *Validation_Expected =
|
||||
&(handler.GetTableParamByName(L"Validation.Expected1")->m_StringTable);
|
||||
std::vector<float> *Validation_Expected =
|
||||
&(handler.GetTableParamByName(L"Validation.Expected1")->m_floatTable);
|
||||
|
||||
LPCWSTR Validation_Type = handler.GetTableParamByName(L"Validation.Type")->m_str;
|
||||
double Validation_Tolerance = handler.GetTableParamByName(L"Validation.Tolerance")->m_double;
|
||||
|
@ -3439,16 +3505,9 @@ TEST_F(ExecutionTest, TertiaryFloatOpTest) {
|
|||
STertiaryFPOp *pPrimitives = (STertiaryFPOp *)Data.data();
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
STertiaryFPOp *p = &pPrimitives[i];
|
||||
PCWSTR str1 = (*Validation_Input1)[i % Validation_Input1->size()];
|
||||
PCWSTR str2 = (*Validation_Input2)[i % Validation_Input2->size()];
|
||||
PCWSTR str3 = (*Validation_Input3)[i % Validation_Input3->size()];
|
||||
float val1, val2, val3;
|
||||
VERIFY_SUCCEEDED(ParseDataToFloat(str1, val1));
|
||||
VERIFY_SUCCEEDED(ParseDataToFloat(str2, val2));
|
||||
VERIFY_SUCCEEDED(ParseDataToFloat(str3, val3));
|
||||
p->input1 = val1;
|
||||
p->input2 = val2;
|
||||
p->input3 = val3;
|
||||
p->input1 = (*Validation_Input1)[i % Validation_Input1->size()];
|
||||
p->input2 = (*Validation_Input2)[i % Validation_Input2->size()];
|
||||
p->input3 = (*Validation_Input3)[i % Validation_Input3->size()];
|
||||
}
|
||||
|
||||
// use shader from data table
|
||||
|
@ -3464,9 +3523,7 @@ TEST_F(ExecutionTest, TertiaryFloatOpTest) {
|
|||
|
||||
for (unsigned i = 0; i < count; ++i) {
|
||||
STertiaryFPOp *p = &pPrimitives[i];
|
||||
LPCWSTR str = (*Validation_Expected)[i % Validation_Expected->size()];
|
||||
float val;
|
||||
VERIFY_SUCCEEDED(ParseDataToFloat(str, val));
|
||||
float val = (*Validation_Expected)[i % Validation_Expected->size()];
|
||||
LogCommentFmt(L"element #%u, input1 = %6.8f, input2 = %6.8f, input3 = %6.8f, output1 = "
|
||||
L"%6.8f, expected = %6.8f",
|
||||
i, p->input1, p->input2, p->input3, p->output, val);
|
||||
|
@ -3475,6 +3532,244 @@ TEST_F(ExecutionTest, TertiaryFloatOpTest) {
|
|||
}
|
||||
}
|
||||
|
||||
TEST_F(ExecutionTest, UnaryHalfOpTest) {
|
||||
WEX::TestExecution::SetVerifyOutput verifySettings(
|
||||
WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures);
|
||||
CComPtr<IStream> pStream;
|
||||
ReadHlslDataIntoNewStream(L"ShaderOpArith.xml", &pStream);
|
||||
|
||||
CComPtr<ID3D12Device> pDevice;
|
||||
if (!CreateDevice(&pDevice)) {
|
||||
return;
|
||||
}
|
||||
// Read data from the table
|
||||
int tableSize = sizeof(UnaryHalfOpParameters) / sizeof(TableParameter);
|
||||
TableParameterHandler handler(UnaryHalfOpParameters, tableSize);
|
||||
handler.clearTableParameter();
|
||||
VERIFY_SUCCEEDED(ParseTableRow(UnaryHalfOpParameters, tableSize));
|
||||
|
||||
CW2A Target(handler.GetTableParamByName(L"ShaderOp.Target")->m_str);
|
||||
CW2A Text(handler.GetTableParamByName(L"ShaderOp.Text")->m_str);
|
||||
|
||||
unsigned int WarpVersion = handler.GetTableParamByName(L"Warp.Version")->m_uint;
|
||||
if (GetTestParamUseWARP(true) && !IsValidWarpDllVersion(WarpVersion)) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<uint16_t> *Validation_Input =
|
||||
&(handler.GetTableParamByName(L"Validation.Input1")->m_halfTable);
|
||||
std::vector<uint16_t> *Validation_Expected =
|
||||
&(handler.GetTableParamByName(L"Validation.Expected1")->m_halfTable);
|
||||
|
||||
LPCWSTR Validation_Type = handler.GetTableParamByName(L"Validation.Type")->m_str;
|
||||
double Validation_Tolerance = handler.GetTableParamByName(L"Validation.Tolerance")->m_double;
|
||||
|
||||
size_t count = Validation_Input->size();
|
||||
|
||||
std::shared_ptr<ShaderOpTestResult> test = RunShaderOpTest(
|
||||
pDevice, m_support, pStream, "UnaryFPOp",
|
||||
// this callbacked is called when the test
|
||||
// is creating the resource to run the test
|
||||
[&](LPCSTR Name, std::vector<BYTE> &Data, st::ShaderOp *pShaderOp) {
|
||||
VERIFY_IS_TRUE(0 == _stricmp(Name, "SUnaryFPOp"));
|
||||
size_t size = sizeof(SUnaryHalfOp) * count;
|
||||
Data.resize(size);
|
||||
SUnaryHalfOp *pPrimitives = (SUnaryHalfOp *)Data.data();
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
SUnaryHalfOp *p = &pPrimitives[i];
|
||||
p->input = (*Validation_Input)[i % Validation_Input->size()];
|
||||
}
|
||||
// use shader from data table
|
||||
pShaderOp->Shaders.at(0).Target = Target.m_psz;
|
||||
pShaderOp->Shaders.at(0).Text = Text.m_psz;
|
||||
});
|
||||
|
||||
MappedData data;
|
||||
test->Test->GetReadBackData("SUnaryFPOp", &data);
|
||||
|
||||
SUnaryHalfOp *pPrimitives = (SUnaryHalfOp*)data.data();
|
||||
WEX::TestExecution::DisableVerifyExceptions dve;
|
||||
for (unsigned i = 0; i < count; ++i) {
|
||||
SUnaryHalfOp *p = &pPrimitives[i];
|
||||
uint16_t expected = (*Validation_Expected)[i % Validation_Input->size()];
|
||||
LogCommentFmt(L"element #%u, input = %6.8f(0x%04x), output = "
|
||||
L"%6.8f(0x%04x), expected = %6.8f(0x%04x)",
|
||||
i, ConvertFloat16ToFloat32(p->input), p->input,
|
||||
ConvertFloat16ToFloat32(p->output), p->output,
|
||||
ConvertFloat16ToFloat32(expected), expected);
|
||||
VerifyOutputWithExpectedValueHalf(p->output, expected, Validation_Type, Validation_Tolerance);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ExecutionTest, BinaryHalfOpTest) {
|
||||
WEX::TestExecution::SetVerifyOutput verifySettings(
|
||||
WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures);
|
||||
CComPtr<IStream> pStream;
|
||||
ReadHlslDataIntoNewStream(L"ShaderOpArith.xml", &pStream);
|
||||
|
||||
CComPtr<ID3D12Device> pDevice;
|
||||
if (!CreateDevice(&pDevice)) {
|
||||
return;
|
||||
}
|
||||
// Read data from the table
|
||||
int tableSize = sizeof(BinaryHalfOpParameters) / sizeof(TableParameter);
|
||||
TableParameterHandler handler(BinaryHalfOpParameters, tableSize);
|
||||
handler.clearTableParameter();
|
||||
VERIFY_SUCCEEDED(ParseTableRow(BinaryHalfOpParameters, tableSize));
|
||||
|
||||
CW2A Target(handler.GetTableParamByName(L"ShaderOp.Target")->m_str);
|
||||
CW2A Text(handler.GetTableParamByName(L"ShaderOp.Text")->m_str);
|
||||
|
||||
std::vector<uint16_t> *Validation_Input1 =
|
||||
&(handler.GetTableParamByName(L"Validation.Input1")->m_halfTable);
|
||||
std::vector<uint16_t> *Validation_Input2 =
|
||||
&(handler.GetTableParamByName(L"Validation.Input2")->m_halfTable);
|
||||
|
||||
std::vector<uint16_t> *Validation_Expected1 =
|
||||
&(handler.GetTableParamByName(L"Validation.Expected1")->m_halfTable);
|
||||
|
||||
std::vector<uint16_t> *Validation_Expected2 =
|
||||
&(handler.GetTableParamByName(L"Validation.Expected2")->m_halfTable);
|
||||
|
||||
LPCWSTR Validation_Type = handler.GetTableParamByName(L"Validation.Type")->m_str;
|
||||
double Validation_Tolerance = handler.GetTableParamByName(L"Validation.Tolerance")->m_double;
|
||||
size_t count = Validation_Input1->size();
|
||||
|
||||
std::shared_ptr<ShaderOpTestResult> test = RunShaderOpTest(
|
||||
pDevice, m_support, pStream, "BinaryFPOp",
|
||||
// this callbacked is called when the test
|
||||
// is creating the resource to run the test
|
||||
[&](LPCSTR Name, std::vector<BYTE> &Data, st::ShaderOp *pShaderOp) {
|
||||
VERIFY_IS_TRUE(0 == _stricmp(Name, "SBinaryFPOp"));
|
||||
size_t size = sizeof(SBinaryHalfOp) * count;
|
||||
Data.resize(size);
|
||||
SBinaryHalfOp *pPrimitives = (SBinaryHalfOp *)Data.data();
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
SBinaryHalfOp *p = &pPrimitives[i];
|
||||
p->input1 = (*Validation_Input1)[i % Validation_Input1->size()];
|
||||
p->input2 = (*Validation_Input1)[i % Validation_Input1->size()];
|
||||
}
|
||||
|
||||
// use shader from data table
|
||||
pShaderOp->Shaders.at(0).Target = Target.m_psz;
|
||||
pShaderOp->Shaders.at(0).Text = Text.m_psz;
|
||||
});
|
||||
|
||||
MappedData data;
|
||||
test->Test->GetReadBackData("SBinaryFPOp", &data);
|
||||
|
||||
SBinaryHalfOp *pPrimitives = (SBinaryHalfOp *)data.data();
|
||||
WEX::TestExecution::DisableVerifyExceptions dve;
|
||||
unsigned numExpected = Validation_Expected2->size() == 0 ? 1 : 2;
|
||||
if (numExpected == 2) {
|
||||
for (unsigned i = 0; i < count; ++i) {
|
||||
SBinaryHalfOp *p = &pPrimitives[i];
|
||||
uint16_t expected1 = (*Validation_Expected1)[i % Validation_Input1->size()];
|
||||
uint16_t expected2 = (*Validation_Expected2)[i % Validation_Input2->size()];
|
||||
LogCommentFmt(L"element #%u, input1 = %6.8f(0x%04x), input2 = %6.8f(0x%04x), output1 = "
|
||||
L"%6.8f(0x%04x), expected1 = %6.8f(0x%04x), output2 = %6.8f(0x%04x), expected2 = %6.8f(0x%04x)",
|
||||
i, ConvertFloat16ToFloat32(p->input1), p->input1,
|
||||
ConvertFloat16ToFloat32(p->input2), p->input2,
|
||||
ConvertFloat16ToFloat32(p->output1), p->output1,
|
||||
ConvertFloat16ToFloat32(p->output2), p->output2,
|
||||
ConvertFloat16ToFloat32(expected1), expected1,
|
||||
ConvertFloat16ToFloat32(expected2), expected2);
|
||||
VerifyOutputWithExpectedValueHalf(p->output1, expected1, Validation_Type, Validation_Tolerance);
|
||||
VerifyOutputWithExpectedValueHalf(p->output2, expected2, Validation_Type, Validation_Tolerance);
|
||||
}
|
||||
}
|
||||
else if (numExpected == 1) {
|
||||
for (unsigned i = 0; i < count; ++i) {
|
||||
uint16_t expected = (*Validation_Expected1)[i % Validation_Input1->size()];
|
||||
SBinaryHalfOp *p = &pPrimitives[i];
|
||||
LogCommentFmt(L"element #%u, input = %6.8f(0x%04x), output = "
|
||||
L"%6.8f(0x%04x), expected = %6.8f(0x%04x)",
|
||||
i, ConvertFloat16ToFloat32(p->input1), p->input1,
|
||||
ConvertFloat16ToFloat32(p->output1), p->output1,
|
||||
ConvertFloat16ToFloat32(expected), expected);
|
||||
VerifyOutputWithExpectedValueHalf(p->output1, expected, Validation_Type, Validation_Tolerance);
|
||||
}
|
||||
}
|
||||
else {
|
||||
LogErrorFmt(L"Unexpected number of expected values for operation %i", numExpected);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ExecutionTest, TertiaryHalfOpTest) {
|
||||
WEX::TestExecution::SetVerifyOutput verifySettings(
|
||||
WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures);
|
||||
CComPtr<IStream> pStream;
|
||||
ReadHlslDataIntoNewStream(L"ShaderOpArith.xml", &pStream);
|
||||
|
||||
CComPtr<ID3D12Device> pDevice;
|
||||
if (!CreateDevice(&pDevice)) {
|
||||
return;
|
||||
}
|
||||
// Read data from the table
|
||||
|
||||
int tableSize = sizeof(TertiaryHalfOpParameters) / sizeof(TableParameter);
|
||||
TableParameterHandler handler(TertiaryHalfOpParameters, tableSize);
|
||||
handler.clearTableParameter();
|
||||
VERIFY_SUCCEEDED(ParseTableRow(TertiaryHalfOpParameters, tableSize));
|
||||
|
||||
CW2A Target(handler.GetTableParamByName(L"ShaderOp.Target")->m_str);
|
||||
CW2A Text(handler.GetTableParamByName(L"ShaderOp.Text")->m_str);
|
||||
|
||||
std::vector<uint16_t> *Validation_Input1 =
|
||||
&(handler.GetTableParamByName(L"Validation.Input1")->m_halfTable);
|
||||
std::vector<uint16_t> *Validation_Input2 =
|
||||
&(handler.GetTableParamByName(L"Validation.Input2")->m_halfTable);
|
||||
std::vector<uint16_t> *Validation_Input3 =
|
||||
&(handler.GetTableParamByName(L"Validation.Input3")->m_halfTable);
|
||||
|
||||
std::vector<uint16_t> *Validation_Expected =
|
||||
&(handler.GetTableParamByName(L"Validation.Expected1")->m_halfTable);
|
||||
|
||||
LPCWSTR Validation_Type = handler.GetTableParamByName(L"Validation.Type")->m_str;
|
||||
double Validation_Tolerance = handler.GetTableParamByName(L"Validation.Tolerance")->m_double;
|
||||
size_t count = Validation_Input1->size();
|
||||
|
||||
std::shared_ptr<ShaderOpTestResult> test = RunShaderOpTest(
|
||||
pDevice, m_support, pStream, "TertiaryFPOp",
|
||||
// this callbacked is called when the test
|
||||
// is creating the resource to run the test
|
||||
[&](LPCSTR Name, std::vector<BYTE> &Data, st::ShaderOp *pShaderOp) {
|
||||
VERIFY_IS_TRUE(0 == _stricmp(Name, "STertiaryFPOp"));
|
||||
size_t size = sizeof(STertiaryHalfOp) * count;
|
||||
Data.resize(size);
|
||||
STertiaryHalfOp *pPrimitives = (STertiaryHalfOp *)Data.data();
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
STertiaryHalfOp *p = &pPrimitives[i];
|
||||
p->input1 = (*Validation_Input1)[i % Validation_Input1->size()];
|
||||
p->input2 = (*Validation_Input2)[i % Validation_Input2->size()];
|
||||
p->input3 = (*Validation_Input3)[i % Validation_Input3->size()];
|
||||
}
|
||||
|
||||
// use shader from data table
|
||||
pShaderOp->Shaders.at(0).Target = Target.m_psz;
|
||||
pShaderOp->Shaders.at(0).Text = Text.m_psz;
|
||||
});
|
||||
|
||||
MappedData data;
|
||||
test->Test->GetReadBackData("STertiaryFPOp", &data);
|
||||
|
||||
STertiaryHalfOp *pPrimitives = (STertiaryHalfOp *)data.data();
|
||||
WEX::TestExecution::DisableVerifyExceptions dve;
|
||||
|
||||
for (unsigned i = 0; i < count; ++i) {
|
||||
STertiaryHalfOp *p = &pPrimitives[i];
|
||||
uint16_t expected = (*Validation_Expected)[i % Validation_Expected->size()];
|
||||
LogCommentFmt(L"element #%u, input1 = %6.8f(0x%04x), input2 = %6.8f(0x%04x), input3 = %6.8f(0x%04x), output = "
|
||||
L"%6.8f(0x%04x), expected = %6.8f(0x%04x)",
|
||||
i, ConvertFloat16ToFloat32(p->input1), p->input1,
|
||||
ConvertFloat16ToFloat32(p->input2), p->input2,
|
||||
ConvertFloat16ToFloat32(p->input3), p->input3,
|
||||
ConvertFloat16ToFloat32(p->output), p->output,
|
||||
ConvertFloat16ToFloat32(expected), expected);
|
||||
VerifyOutputWithExpectedValueHalf(p->output, expected, Validation_Type, Validation_Tolerance);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ExecutionTest, UnaryIntOpTest) {
|
||||
WEX::TestExecution::SetVerifyOutput verifySettings(
|
||||
WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures);
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
// Provides utility functions for HLSL tests. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
|
@ -204,18 +203,137 @@ inline bool ifdenorm_flushf_eq_or_nans(float a, float b) {
|
|||
return ifdenorm_flushf(a) == ifdenorm_flushf(b);
|
||||
}
|
||||
|
||||
using namespace hlsl::DXIL;
|
||||
static const uint16_t Float16NaN = 0xff80;
|
||||
static const uint16_t Float16PosInf = 0x7c00;
|
||||
static const uint16_t Float16NegInf = 0xfc00;
|
||||
static const uint16_t Float16PosDenorm = 0x0008;
|
||||
static const uint16_t Float16NegDenorm = 0x8008;
|
||||
static const uint16_t Float16PosZero = 0x0000;
|
||||
static const uint16_t Float16NegZero = 0x8000;
|
||||
|
||||
inline bool GetSign(float x) {
|
||||
return std::signbit(x);
|
||||
}
|
||||
|
||||
inline int GetMantissa(float x) {
|
||||
int bits = reinterpret_cast<int &>(x);
|
||||
return bits & 0x7fffff;
|
||||
}
|
||||
|
||||
inline int GetExponent(float x) {
|
||||
int bits = reinterpret_cast<int &>(x);
|
||||
return (bits >> 23) & 0xff;
|
||||
}
|
||||
|
||||
#define FLOAT16_BIT_SIGN 0x8000
|
||||
#define FLOAT16_BIT_EXP 0x7c00
|
||||
#define FLOAT16_BIT_MANTISSA 0x03ff
|
||||
#define FLOAT16_BIGGEST_DENORM FLOAT16_BIT_MANTISSA
|
||||
#define FLOAT16_BIGGEST_NORMAL 0x7bff
|
||||
|
||||
inline bool isnanFloat16(uint16_t val) {
|
||||
return (val & FLOAT16_BIT_EXP) == FLOAT16_BIT_EXP &&
|
||||
(val & FLOAT16_BIT_MANTISSA) != 0;
|
||||
}
|
||||
|
||||
inline uint16_t ConvertFloat32ToFloat16(float val) {
|
||||
union Bits {
|
||||
uint32_t u_bits;
|
||||
float f_bits;
|
||||
};
|
||||
|
||||
static const uint32_t SignMask = 0x8000;
|
||||
|
||||
// Maximum f32 value representable in f16 format
|
||||
static const uint32_t Max16in32 = 0x477fe000;
|
||||
|
||||
// Minimum f32 value representable in f16 format without denormalizing
|
||||
static const uint32_t Min16in32 = 0x38800000;
|
||||
|
||||
// Maximum f32 value (next to infinity)
|
||||
static const uint32_t Max32 = 0x7f7FFFFF;
|
||||
|
||||
// Mask for f32 mantissa
|
||||
static const uint32_t Fraction32Mask = 0x007FFFFF;
|
||||
|
||||
// pow(2,24)
|
||||
static const uint32_t DenormalRatio = 0x4B800000;
|
||||
|
||||
static const uint32_t NormalDelta = 0x38000000;
|
||||
|
||||
Bits bits;
|
||||
bits.f_bits = val;
|
||||
uint32_t sign = bits.u_bits & (SignMask << 16);
|
||||
Bits Abs;
|
||||
Abs.u_bits = bits.u_bits ^ sign;
|
||||
|
||||
bool isLessThanNormal = Abs.f_bits < *(float*)&Min16in32;
|
||||
bool isInfOrNaN = Abs.u_bits > Max32;
|
||||
|
||||
if (isLessThanNormal) {
|
||||
// Compute Denormal result
|
||||
return (uint16_t)(Abs.f_bits * *(float*)(&DenormalRatio)) | sign;
|
||||
}
|
||||
else if (isInfOrNaN) {
|
||||
// Compute Inf or Nan result
|
||||
uint32_t Fraction = Abs.u_bits & Fraction32Mask;
|
||||
uint16_t IsNaN = Fraction == 0 ? 0 : 0xffff;
|
||||
return (IsNaN & FLOAT16_BIT_MANTISSA) | FLOAT16_BIT_EXP | (sign >> 16);
|
||||
}
|
||||
else {
|
||||
// Compute Normal result
|
||||
return (uint16_t)((Abs.u_bits - NormalDelta) >> 13) | (sign >> 16);
|
||||
}
|
||||
}
|
||||
|
||||
inline float ConvertFloat16ToFloat32(uint16_t x) {
|
||||
union Bits {
|
||||
float f_bits;
|
||||
uint32_t u_bits;
|
||||
};
|
||||
|
||||
uint32_t Sign = (x & FLOAT16_BIT_SIGN) << 16;
|
||||
|
||||
// nan -> exponent all set and mantisa is non zero
|
||||
// +/-inf -> exponent all set and mantissa is zero
|
||||
// denorm -> exponent zero and significand nonzero
|
||||
uint32_t Abs = (x & 0x7fff);
|
||||
uint32_t IsNormal = Abs > FLOAT16_BIGGEST_DENORM;
|
||||
uint32_t IsInfOrNaN = Abs > FLOAT16_BIGGEST_NORMAL;
|
||||
|
||||
// Signless Result for normals
|
||||
uint32_t DenormRatio = 0x33800000;
|
||||
float DenormResult = Abs * (*(float*)&DenormRatio);
|
||||
|
||||
uint32_t AbsShifted = Abs << 13;
|
||||
// Signless Result for normals
|
||||
uint32_t NormalResult = AbsShifted + 0x38000000;
|
||||
// Signless Result for int & nans
|
||||
uint32_t InfResult = AbsShifted + 0x70000000;
|
||||
|
||||
Bits bits;
|
||||
bits.u_bits = 0;
|
||||
if (IsInfOrNaN)
|
||||
bits.u_bits |= InfResult;
|
||||
else if (IsNormal)
|
||||
bits.u_bits |= NormalResult;
|
||||
else
|
||||
bits.f_bits = DenormResult;
|
||||
bits.u_bits |= Sign;
|
||||
return bits.f_bits;
|
||||
}
|
||||
uint16_t ConvertFloat32ToFloat16(float val);
|
||||
float ConvertFloat16ToFloat32(uint16_t val);
|
||||
inline bool CompareFloatULP(const float &fsrc, const float &fref,
|
||||
int ULPTolerance,
|
||||
Float32DenormMode mode = Float32DenormMode::Any) {
|
||||
hlsl::DXIL::Float32DenormMode mode = hlsl::DXIL::Float32DenormMode::Any) {
|
||||
if (fsrc == fref) {
|
||||
return true;
|
||||
}
|
||||
if (isnan(fsrc)) {
|
||||
return isnan(fref);
|
||||
}
|
||||
if (mode == Float32DenormMode::Any) {
|
||||
if (mode == hlsl::DXIL::Float32DenormMode::Any) {
|
||||
// If denorm expected, output can be sign preserved zero. Otherwise output
|
||||
// should pass the regular ulp testing.
|
||||
if (isdenorm(fref) && fsrc == 0 && signbit(fsrc) == signbit(fref))
|
||||
|
@ -230,14 +348,14 @@ inline bool CompareFloatULP(const float &fsrc, const float &fref,
|
|||
|
||||
inline bool
|
||||
CompareFloatEpsilon(const float &fsrc, const float &fref, float epsilon,
|
||||
Float32DenormMode mode = Float32DenormMode::Any) {
|
||||
hlsl::DXIL::Float32DenormMode mode = hlsl::DXIL::Float32DenormMode::Any) {
|
||||
if (fsrc == fref) {
|
||||
return true;
|
||||
}
|
||||
if (isnan(fsrc)) {
|
||||
return isnan(fref);
|
||||
}
|
||||
if (mode == Float32DenormMode::Any) {
|
||||
if (mode == hlsl::DXIL::Float32DenormMode::Any) {
|
||||
// If denorm expected, output can be sign preserved zero. Otherwise output
|
||||
// should pass the regular epsilon testing.
|
||||
if (isdenorm(fref) && fsrc == 0 && signbit(fsrc) == signbit(fref))
|
||||
|
@ -252,10 +370,37 @@ CompareFloatEpsilon(const float &fsrc, const float &fref, float epsilon,
|
|||
inline bool
|
||||
CompareFloatRelativeEpsilon(const float &fsrc, const float &fref,
|
||||
int nRelativeExp,
|
||||
Float32DenormMode mode = Float32DenormMode::Any) {
|
||||
hlsl::DXIL::Float32DenormMode mode = hlsl::DXIL::Float32DenormMode::Any) {
|
||||
return CompareFloatULP(fsrc, fref, 23 - nRelativeExp, mode);
|
||||
}
|
||||
|
||||
inline bool CompareHalfULP(const uint16_t &fsrc, const uint16_t &fref, float ULPTolerance) {
|
||||
if (fsrc == fref)
|
||||
return true;
|
||||
if (isnanFloat16(fsrc))
|
||||
return isnanFloat16(fref);
|
||||
// 16-bit floating point numbers must preserve denorms
|
||||
int diff = *((DWORD *)&fsrc) - *((DWORD *)&fref);
|
||||
unsigned int uDiff = diff < 0 ? -diff : diff;
|
||||
return uDiff <= (unsigned int)ULPTolerance;
|
||||
}
|
||||
|
||||
inline bool CompareHalfEpsilon(const uint16_t &fsrc, const uint16_t &fref, float epsilon) {
|
||||
if (fsrc == fref)
|
||||
return true;
|
||||
if (isnanFloat16(fsrc))
|
||||
return isnanFloat16(fref);
|
||||
float src_f32 = ConvertFloat16ToFloat32(fsrc);
|
||||
float ref_f32 = ConvertFloat16ToFloat32(fref);
|
||||
return abs(src_f32-ref_f32) < epsilon;
|
||||
}
|
||||
|
||||
inline bool
|
||||
CompareHalfRelativeEpsilon(const uint16_t &fsrc, const uint16_t &fref,
|
||||
int nRelativeExp) {
|
||||
return CompareHalfULP(fsrc, fref, 10 - nRelativeExp);
|
||||
}
|
||||
|
||||
// returns the number of bytes per pixel for a given dxgi format
|
||||
// add more cases if different format needed to copy back resources
|
||||
inline UINT GetByteSizeForFormat(DXGI_FORMAT value) {
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1880,45 +1880,6 @@ DXIL::ComponentType GetCompType(LPCWSTR pText, LPCWSTR pEnd) {
|
|||
}
|
||||
}
|
||||
|
||||
bool GetSign(float x) {
|
||||
return std::signbit(x);
|
||||
}
|
||||
|
||||
int GetMantissa(float x) {
|
||||
int bits = reinterpret_cast<int &>(x);
|
||||
return bits & 0x7fffff;
|
||||
}
|
||||
|
||||
int GetExponent(float x) {
|
||||
int bits = reinterpret_cast<int &>(x);
|
||||
return (bits >> 23) & 0xff;
|
||||
}
|
||||
|
||||
|
||||
// Note: This is not a precise float32 to float16 conversion.
|
||||
// This function should be used to convert float values read from ShaderOp data that were intended to be used for halves.
|
||||
// So special values (nan, denorm, inf) for float32 will map to their corresponding bits in float16,
|
||||
// and it will not handle true conversions that spans float16 denorms and float32 non-denorms.
|
||||
uint16_t ConvertFloat32ToFloat16(float x) {
|
||||
bool isNeg = GetSign(x);
|
||||
int exp = GetExponent(x);
|
||||
int mantissa = GetMantissa(x);
|
||||
if (isnan(x)) return Float16NaN;
|
||||
if (isinf(x) || exp - 127 > 15) {
|
||||
return isNeg ? Float16NegInf : Float16PosInf;
|
||||
}
|
||||
if (isdenorm(x)) return isNeg ? Float16NegDenorm : Float16PosDenorm;
|
||||
if (exp == 0 && mantissa == 0) return isNeg ? Float16NegZero : Float16PosZero;
|
||||
else {
|
||||
DXASSERT(exp - 127 <= 15, "else invalid float conversion");
|
||||
uint16_t val = 0;
|
||||
val |= isNeg ? 0x8000 : 0;
|
||||
val |= (exp - 127 + 15) << 10; // subtract from float32 exponent bias and add float16 exponent bias
|
||||
val |= mantissa >> 13; // only first 10 significands taken
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
void ParseDataFromText(LPCWSTR pText, LPCWSTR pEnd, DXIL::ComponentType compType, std::vector<BYTE> &V) {
|
||||
BYTE *pB;
|
||||
if (compType == DXIL::ComponentType::F16 || compType == DXIL::ComponentType::F32) {
|
||||
|
|
|
@ -298,22 +298,6 @@ void ParseShaderOpSetFromStream(IStream *pStream, ShaderOpSet *pShaderOpSet);
|
|||
// Deserialize a ShaderOpSet from an IXmlReader instance.
|
||||
void ParseShaderOpSetFromXml(IXmlReader *pReader, ShaderOpSet *pShaderOpSet);
|
||||
|
||||
static const uint16_t Float16NaN = 0xff80;
|
||||
static const uint16_t Float16PosInf = 0x7c00;
|
||||
static const uint16_t Float16NegInf = 0xfc00;
|
||||
static const uint16_t Float16PosDenorm = 0x0001;
|
||||
static const uint16_t Float16NegDenorm = 0x8001;
|
||||
static const uint16_t Float16PosZero = 0x0000;
|
||||
static const uint16_t Float16NegZero = 0x8000;
|
||||
|
||||
bool GetSign(float x);
|
||||
|
||||
int GetMantissa(float x);
|
||||
|
||||
int GetExponent(float x);
|
||||
|
||||
uint16_t ConvertFloat32ToFloat16(float x);
|
||||
|
||||
} // namespace st
|
||||
|
||||
#endif __SHADEROPTEST_H__
|
||||
|
|
|
@ -73,6 +73,21 @@ def add_test_case(test_name, inst_names, validation_type, validation_tolerance,
|
|||
for inst_name in inst_names:
|
||||
g_instruction_nodes[inst_name].test_cases += [case]
|
||||
|
||||
def add_test_case_float_half(test_name, inst_names, validation_type, validation_tolerance,
|
||||
float_input_lists, float_output_lists, shader_key, shader_op_name, **kwargs):
|
||||
add_test_case(test_name, inst_names, validation_type, validation_tolerance,
|
||||
float_input_lists, float_output_lists, "cs_6_0", get_shader_text(shader_key, shader_op_name), **kwargs)
|
||||
# if half test cases are different from float input lists, use those lists instead for half testings
|
||||
half_input_lists, half_output_lists = float_input_lists, float_output_lists
|
||||
if "half_inputs" in kwargs:
|
||||
half_input_lists = kwargs["half_inputs"]
|
||||
if "half_outputs" in kwargs:
|
||||
half_output_lists = kwargs["half_outputs"]
|
||||
# skip relative error test check for half for now
|
||||
if validation_type != "Relative":
|
||||
add_test_case(test_name + "Half", inst_names, validation_type, validation_tolerance,
|
||||
half_input_lists, half_output_lists, "cs_6_2", get_shader_text(shader_key.replace("float","half"), shader_op_name), **kwargs)
|
||||
|
||||
def add_test_case_denorm(test_name, inst_names, validation_type, validation_tolerance, input_lists, output_lists_ftz, output_lists_preserve, shader_target, shader_text, **kwargs):
|
||||
add_test_case(test_name + "FTZ", inst_names, validation_type, validation_tolerance, input_lists,
|
||||
output_lists_ftz, shader_target, shader_text, shader_arguments="-denorm ftz")
|
||||
|
@ -134,6 +149,34 @@ g_shader_texts = {
|
|||
l.output = 0;
|
||||
g_buf[GI] = l;
|
||||
};''',
|
||||
|
||||
"unary half": ''' struct SUnaryFPOp {
|
||||
half input;
|
||||
half output;
|
||||
};
|
||||
RWStructuredBuffer<SUnaryFPOp> g_buf : register(u0);
|
||||
[numthreads(8,8,1)]
|
||||
void main(uint GI : SV_GroupIndex) {
|
||||
SUnaryFPOp l = g_buf[GI];
|
||||
l.output = %s(l.input);
|
||||
g_buf[GI] = l;
|
||||
};''',
|
||||
|
||||
"unary half bool": ''' struct SUnaryFPOp {
|
||||
half input;
|
||||
half output;
|
||||
};
|
||||
RWStructuredBuffer<SUnaryFPOp> g_buf : register(u0);
|
||||
[numthreads(8,8,1)]
|
||||
void main(uint GI : SV_GroupIndex) {
|
||||
SUnaryFPOp l = g_buf[GI];
|
||||
if (%s(l.input))
|
||||
l.output = 1;
|
||||
else
|
||||
l.output = 0;
|
||||
g_buf[GI] = l;
|
||||
};''',
|
||||
|
||||
"binary int": ''' struct SBinaryIntOp {
|
||||
int input1;
|
||||
int input2;
|
||||
|
@ -176,7 +219,6 @@ g_shader_texts = {
|
|||
g_buf[GI] = l;
|
||||
};''',
|
||||
|
||||
|
||||
"binary uint call": ''' struct SBinaryUintOp {
|
||||
uint input1;
|
||||
uint input2;
|
||||
|
@ -219,6 +261,34 @@ g_shader_texts = {
|
|||
g_buf[GI] = l;
|
||||
};''',
|
||||
|
||||
"binary half": ''' struct SBinaryFPOp {
|
||||
half input1;
|
||||
half input2;
|
||||
half output1;
|
||||
half output2;
|
||||
};
|
||||
RWStructuredBuffer<SBinaryFPOp> g_buf : register(u0);
|
||||
[numthreads(8,8,1)]
|
||||
void main(uint GI : SV_GroupIndex) {
|
||||
SBinaryFPOp l = g_buf[GI];
|
||||
l.output1 = l.input1 %s l.input2;
|
||||
g_buf[GI] = l;
|
||||
};''',
|
||||
|
||||
"binary half call": ''' struct SBinaryFPOp {
|
||||
half input1;
|
||||
half input2;
|
||||
half output1;
|
||||
half output2;
|
||||
};
|
||||
RWStructuredBuffer<SBinaryFPOp> g_buf : register(u0);
|
||||
[numthreads(8,8,1)]
|
||||
void main(uint GI : SV_GroupIndex) {
|
||||
SBinaryFPOp l = g_buf[GI];
|
||||
l.output1 = %s(l.input1,l.input2);
|
||||
g_buf[GI] = l;
|
||||
};''',
|
||||
|
||||
"tertiary int": ''' struct STertiaryIntOp {
|
||||
int input1;
|
||||
int input2;
|
||||
|
@ -260,6 +330,19 @@ g_shader_texts = {
|
|||
l.output = %s(l.input1, l.input2, l.input3);
|
||||
g_buf[GI] = l;
|
||||
};''',
|
||||
'tertiary half': ''' struct STertiaryHalfOp {
|
||||
half input1;
|
||||
half input2;
|
||||
half input3;
|
||||
half output;
|
||||
};
|
||||
RWStructuredBuffer<STertiaryHalfOp> g_buf : register(u0);
|
||||
[numthreads(8,8,1)]
|
||||
void main(uint GI : SV_GroupIndex) {
|
||||
STertiaryHalfOp l = g_buf[GI];
|
||||
l.output = %s(l.input1, l.input2, l.input3);
|
||||
g_buf[GI] = l;
|
||||
};''',
|
||||
"wave op int" :''' struct PerThreadData {
|
||||
uint firstLaneId;
|
||||
uint laneIndex;
|
||||
|
@ -350,142 +433,164 @@ def add_test_cases():
|
|||
p_denorm = float('1e-38')
|
||||
n_denorm = float('-1e-38')
|
||||
# Unary Float
|
||||
add_test_case('Sin', ['Sin'], 'Epsilon', 0.0008, [[
|
||||
add_test_case_float_half('Sin', ['Sin'], 'Epsilon', 0.0008, [[
|
||||
'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '-314.16',
|
||||
'314.16'
|
||||
]], [[
|
||||
'NaN', 'NaN', '-0', '-0', '0', '0', 'NaN', '-0.0007346401',
|
||||
'0.0007346401'
|
||||
]], 'cs_6_0', get_shader_text("unary float", "sin"))
|
||||
add_test_case('Cos', ['Cos'], 'Epsilon', 0.0008, [[
|
||||
]], "unary float", "sin", half_inputs=[[
|
||||
'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '-314',
|
||||
'314'
|
||||
]], half_outputs=[[
|
||||
'NaN', 'NaN', '-0', '-0', '0', '0', 'NaN', '-0.1585929',
|
||||
'0.1585929'
|
||||
]])
|
||||
add_test_case_float_half('Cos', ['Cos'], 'Epsilon', 0.0008, [[
|
||||
'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '-314.16',
|
||||
'314.16'
|
||||
]], [[
|
||||
'NaN', 'NaN', '1.0', '1.0', '1.0', '1.0', 'NaN', '0.99999973015',
|
||||
'0.99999973015'
|
||||
]], 'cs_6_0', get_shader_text("unary float", "cos"))
|
||||
add_test_case('Tan', ['Tan'], 'Epsilon', 0.0008, [[
|
||||
]], "unary float", "cos", half_inputs=[[
|
||||
'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '-314',
|
||||
'314'
|
||||
]], half_outputs=[[
|
||||
'NaN', 'NaN', '-0', '-0', '0', '0', 'NaN', '0.987344',
|
||||
'0.987344'
|
||||
]])
|
||||
add_test_case_float_half('Tan', ['Tan'], 'Epsilon', 0.0008, [[
|
||||
'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '-314.16',
|
||||
'314.16'
|
||||
]], [[
|
||||
'NaN', 'NaN', '-0.0', '-0.0', '0.0', '0.0', 'NaN', '-0.000735',
|
||||
'0.000735'
|
||||
]], 'cs_6_0', get_shader_text("unary float", "tan"))
|
||||
add_test_case('Hcos', ['Hcos'], 'Epsilon', 0.0008,
|
||||
]], "unary float", "tan", half_inputs=[[
|
||||
'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '-314',
|
||||
'314'
|
||||
]], half_outputs=[[
|
||||
'NaN', 'NaN', '-0', '-0', '0', '0', 'NaN', '0.1606257',
|
||||
'-0.1606257'
|
||||
]])
|
||||
add_test_case_float_half('Hcos', ['Hcos'], 'Epsilon', 0.0008,
|
||||
[['NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '1', '-1']], [[
|
||||
'NaN', 'Inf', '1.0', '1.0', '1.0', '1.0', 'Inf', '1.543081',
|
||||
'1.543081'
|
||||
]], 'cs_6_0', get_shader_text("unary float", "cosh"))
|
||||
add_test_case('Hsin', ['Hsin'], 'Epsilon', 0.0008,
|
||||
]], "unary float", "cosh")
|
||||
add_test_case_float_half('Hsin', ['Hsin'], 'Epsilon', 0.0008,
|
||||
[['NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '1', '-1']], [[
|
||||
'NaN', '-Inf', '0.0', '0.0', '0.0', '0.0', 'Inf', '1.175201',
|
||||
'-1.175201'
|
||||
]], 'cs_6_0', get_shader_text("unary float", "sinh"))
|
||||
add_test_case('Htan', ['Htan'], 'Epsilon', 0.0008,
|
||||
]], "unary float", "sinh")
|
||||
add_test_case_float_half('Htan', ['Htan'], 'Epsilon', 0.0008,
|
||||
[['NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '1', '-1']], [[
|
||||
'NaN', '-1', '-0.0', '-0.0', '0.0', '0.0', '1', '0.761594',
|
||||
'-0.761594'
|
||||
]], 'cs_6_0', get_shader_text("unary float", "tanh"), warp_version=16202)
|
||||
add_test_case('Acos', ['Acos'], 'Epsilon', 0.0008, [[
|
||||
]], "unary float", "tanh", warp_version=16202)
|
||||
add_test_case_float_half('Acos', ['Acos'], 'Epsilon', 0.0008, [[
|
||||
'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '1', '-1', '1.5',
|
||||
'-1.5'
|
||||
]], [[
|
||||
'NaN', 'NaN', '1.570796', '1.570796', '1.570796', '1.570796', 'NaN',
|
||||
'0', '3.1415926', 'NaN', 'NaN'
|
||||
]], 'cs_6_0', get_shader_text("unary float", "acos"))
|
||||
add_test_case('Asin', ['Asin'], 'Epsilon', 0.0008, [[
|
||||
]], "unary float", "acos")
|
||||
add_test_case_float_half('Asin', ['Asin'], 'Epsilon', 0.0008, [[
|
||||
'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '1', '-1', '1.5',
|
||||
'-1.5'
|
||||
]], [[
|
||||
'NaN', 'NaN', '0.0', '0.0', '0.0', '0.0', 'NaN', '1.570796',
|
||||
'-1.570796', 'NaN', 'NaN'
|
||||
]], 'cs_6_0', get_shader_text("unary float", "asin"))
|
||||
add_test_case('Atan', ['Atan'], 'Epsilon', 0.0008,
|
||||
]], "unary float", "asin")
|
||||
add_test_case_float_half('Atan', ['Atan'], 'Epsilon', 0.0008,
|
||||
[['NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '1', '-1']], [[
|
||||
'NaN', '-1.570796', '0.0', '0.0', '0.0', '0.0', '1.570796',
|
||||
'0.785398163', '-0.785398163'
|
||||
]], 'cs_6_0', get_shader_text("unary float", "atan"), warp_version=16202)
|
||||
add_test_case('Exp', ['Exp'], 'Relative', 21,
|
||||
]], "unary float", "atan", warp_version=16202)
|
||||
add_test_case_float_half('Exp', ['Exp'], 'Relative', 21,
|
||||
[['NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '-1', '10']],
|
||||
[['NaN', '0', '1', '1', '1', '1', 'Inf', '0.367879441', '22026.46579']
|
||||
], 'cs_6_0', get_shader_text("unary float", "exp"))
|
||||
add_test_case('Frc', ['Frc'], 'Epsilon', 0.0008, [[
|
||||
], "unary float", "exp")
|
||||
add_test_case_float_half('Frc', ['Frc'], 'Epsilon', 0.0008, [[
|
||||
'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '-1', '2.718280',
|
||||
'1000.599976', '-7.389'
|
||||
]], [[
|
||||
'NaN', 'NaN', '0', '0', '0', '0', 'NaN', '0', '0.718280', '0.599976',
|
||||
'0.611'
|
||||
]], 'cs_6_0', get_shader_text("unary float", "frac"))
|
||||
add_test_case('Log', ['Log'], 'Relative', 21, [[
|
||||
]], "unary float", "frac",
|
||||
half_inputs=[['NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '-1', '2.719',
|
||||
'1000.5', '-7.39']],
|
||||
half_outputs=[[
|
||||
'NaN', 'NaN', '0', '0', '0', '0', 'NaN', '0', '0.719', '0.5',
|
||||
'0.61']])
|
||||
add_test_case_float_half('Log', ['Log'], 'Relative', 21, [[
|
||||
'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '-1',
|
||||
'2.718281828', '7.389056', '100'
|
||||
]], [[
|
||||
'NaN', 'NaN', '-Inf', '-Inf', '-Inf', '-Inf', 'Inf', 'NaN', '1.0',
|
||||
'1.99999998', '4.6051701'
|
||||
]], 'cs_6_0', get_shader_text("unary float", "log"))
|
||||
add_test_case('Sqrt', ['Sqrt'], 'ulp', 1, [[
|
||||
]],"unary float", "log", half_inputs=[[
|
||||
'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '-1',
|
||||
'2.719', '7.39', '100'
|
||||
]], half_outputs=[[
|
||||
'NaN', 'NaN', '-Inf', '-Inf', '-Inf', '-Inf', 'Inf', 'NaN', '1.0',
|
||||
'2', '4.605'
|
||||
]])
|
||||
add_test_case_float_half('Sqrt', ['Sqrt'], 'ulp', 1, [[
|
||||
'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '-1', '2',
|
||||
'16.0', '256.0'
|
||||
]], [[
|
||||
'NaN', 'NaN', '-0', '-0', '0', '0', 'Inf', 'NaN', '1.41421356237',
|
||||
'4.0', '16.0'
|
||||
]], 'cs_6_0', get_shader_text("unary float", "sqrt"))
|
||||
add_test_case('Rsqrt', ['Rsqrt'], 'ulp', 1, [[
|
||||
]], "unary float", "sqrt")
|
||||
add_test_case_float_half('Rsqrt', ['Rsqrt'], 'ulp', 1, [[
|
||||
'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '-1', '16.0',
|
||||
'256.0', '65536.0'
|
||||
]], [[
|
||||
'NaN', 'NaN', '-Inf', '-Inf', 'Inf', 'Inf', '0', 'NaN', '0.25',
|
||||
'0.0625', '0.00390625'
|
||||
]], 'cs_6_0', get_shader_text("unary float", "rsqrt"))
|
||||
add_test_case('Rsqrt', ['Rsqrt'], 'ulp', 1, [[
|
||||
]], "unary float", "rsqrt", half_inputs=[[
|
||||
'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '-1', '16.0',
|
||||
'256.0', '65536.0'
|
||||
]], [[
|
||||
'256.0', '65500'
|
||||
]], half_outputs=[[
|
||||
'NaN', 'NaN', '-Inf', '-Inf', 'Inf', 'Inf', '0', 'NaN', '0.25',
|
||||
'0.0625', '0.00390625'
|
||||
]], 'cs_6_0', get_shader_text("unary float", "rsqrt"))
|
||||
add_test_case('Round_ne', ['Round_ne'], 'Epsilon', 0, [[
|
||||
'0.0625', '0.00001526'
|
||||
]])
|
||||
add_test_case_float_half('Round_ne', ['Round_ne'], 'Epsilon', 0, [[
|
||||
'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '10.0', '10.4',
|
||||
'10.5', '10.6', '11.5', '-10.0', '-10.4', '-10.5', '-10.6'
|
||||
]], [[
|
||||
'NaN', '-Inf', '-0', '-0', '0', '0', 'Inf', '10.0', '10.0', '10.0',
|
||||
'11.0', '12.0', '-10.0', '-10.0', '-10.0', '-11.0'
|
||||
]], 'cs_6_0', get_shader_text("unary float", "round"))
|
||||
add_test_case('Round_ni', ['Round_ni'], 'Epsilon', 0, [[
|
||||
]], "unary float", "round")
|
||||
add_test_case_float_half('Round_ni', ['Round_ni'], 'Epsilon', 0, [[
|
||||
'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '10.0', '10.4',
|
||||
'10.5', '10.6', '-10.0', '-10.4', '-10.5', '-10.6'
|
||||
]], [[
|
||||
'NaN', '-Inf', '-0', '-0', '0', '0', 'Inf', '10.0', '10.0', '10.0',
|
||||
'10.0', '-10.0', '-11.0', '-11.0', '-11.0'
|
||||
]], 'cs_6_0', get_shader_text("unary float", "floor"))
|
||||
add_test_case('Round_pi', ['Round_pi'], 'Epsilon', 0,
|
||||
]], "unary float", "floor")
|
||||
add_test_case_float_half('Round_pi', ['Round_pi'], 'Epsilon', 0,
|
||||
[['NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '10.0', '10.4',
|
||||
'10.5', '10.6', '-10.0', '-10.4', '-10.5', '-10.6']],
|
||||
[['NaN', '-Inf', '-0', '-0', '0', '0', 'Inf', '10.0', '11.0', '11.0',
|
||||
'11.0', '-10.0', '-10.0', '-10.0', '-10.0']], 'cs_6_0',
|
||||
get_shader_text("unary float", "ceil"))
|
||||
add_test_case('Round_z', ['Round_z'], 'Epsilon', 0,
|
||||
'11.0', '-10.0', '-10.0', '-10.0', '-10.0']], "unary float", "ceil")
|
||||
add_test_case_float_half('Round_z', ['Round_z'], 'Epsilon', 0,
|
||||
[['NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '10.0', '10.4',
|
||||
'10.5', '10.6', '-10.0', '-10.4', '-10.5', '-10.6']],
|
||||
[['NaN', '-Inf', '-0', '-0', '0', '0', 'Inf', '10.0', '10.0', '10.0',
|
||||
'10.0', '-10.0', '-10.0', '-10.0', '-10.0']],'cs_6_0',
|
||||
get_shader_text("unary float", "trunc"))
|
||||
add_test_case('IsNaN', ['IsNaN'], 'Epsilon', 0,
|
||||
'10.0', '-10.0', '-10.0', '-10.0', '-10.0']], "unary float", "trunc")
|
||||
add_test_case_float_half('IsNaN', ['IsNaN'], 'Epsilon', 0,
|
||||
[['NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '1.0', '-1.0']
|
||||
], [['1', '0', '0', '0', '0', '0', '0', '0', '0']], 'cs_6_0',
|
||||
get_shader_text("unary float bool", "isnan"))
|
||||
add_test_case('IsInf', ['IsInf'], 'Epsilon', 0,
|
||||
], [['1', '0', '0', '0', '0', '0', '0', '0', '0']], "unary float bool", "isnan")
|
||||
add_test_case_float_half('IsInf', ['IsInf'], 'Epsilon', 0,
|
||||
[['NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '1.0', '-1.0']
|
||||
], [['0', '1', '0', '0', '0', '0', '1', '0', '0']], 'cs_6_0',
|
||||
get_shader_text("unary float bool", "isinf"))
|
||||
add_test_case('IsFinite', ['IsFinite'], 'Epsilon', 0,
|
||||
], [['0', '1', '0', '0', '0', '0', '1', '0', '0']], "unary float bool", "isinf")
|
||||
add_test_case_float_half('IsFinite', ['IsFinite'], 'Epsilon', 0,
|
||||
[['NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '1.0', '-1.0']
|
||||
], [['0', '0', '1', '1', '1', '1', '0', '1', '1']], 'cs_6_0',
|
||||
get_shader_text("unary float bool", "isfinite"), warp_version=16202)
|
||||
add_test_case('FAbs', ['FAbs'], 'Epsilon', 0,
|
||||
], [['0', '0', '1', '1', '1', '1', '0', '1', '1']], "unary float bool", "isfinite", warp_version=16202)
|
||||
add_test_case_float_half('FAbs', ['FAbs'], 'Epsilon', 0,
|
||||
[['NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '1.0', '-1.0']
|
||||
], [['NaN', 'Inf', 'denorm', '0', '0', 'denorm', 'Inf', '1', '1']],
|
||||
'cs_6_0', get_shader_text("unary float", "abs"))
|
||||
], [['NaN', 'Inf', 'denorm', '0', '0', 'denorm', 'Inf', '1', '1']], "unary float", "abs")
|
||||
# Binary Float
|
||||
add_test_case('FMin', ['FMin','FMax'], 'epsilon', 0, [[
|
||||
'-inf', '-inf', '-inf', '-inf', 'inf', 'inf', 'inf', 'inf', 'NaN',
|
||||
|
@ -513,14 +618,40 @@ def add_test_cases():
|
|||
l.output2 = max(l.input1, l.input2);
|
||||
g_buf[GI] = l;
|
||||
};''')
|
||||
add_test_case('FAdd', ['FAdd'], 'ulp', 1, [['-1.0', '1.0', '32.5', '1.0000001000'],['4', '5.5', '334.7', '0.5000001000']], [['3.0', '6.5', '367.2', '1.5000002000']],
|
||||
'cs_6_0', get_shader_text("binary float", "+"))
|
||||
add_test_case('FSub', ['FSub'], 'ulp', 1, [['-1.0', '5.5', '32.5', '1.0000001000'],['4', '1.25', '334.7', '0.5000001000']], [['-5', '4.25', '-302.2', '0.5000']],
|
||||
'cs_6_0', get_shader_text("binary float", "-"))
|
||||
add_test_case('FMul', ['FMul'], 'ulp', 1, [['-1.0', '5.5', '1.0000001'],['4', '1.25', '2.0']], [['-4.0', '6.875', '2.0000002']],
|
||||
'cs_6_0', get_shader_text("binary float", "*"))
|
||||
add_test_case('FDiv', ['FDiv'], 'ulp', 1, [['-1.0', '5.5', '1.0000001'],['4', '1.25', '2.0']], [['-0.25', '4.4', '0.50000006']],
|
||||
'cs_6_0', get_shader_text("binary float", "/"))
|
||||
add_test_case('FMinHalf', ['FMin','FMax'], 'epsilon', 0, [[
|
||||
'-inf', '-inf', '-inf', '-inf', 'inf', 'inf', 'inf', 'inf', 'NaN',
|
||||
'NaN', 'NaN', 'NaN', '1.0', '1.0', '-1.0', '-1.0', '1.0'
|
||||
], [
|
||||
'-inf', 'inf', '1.0', 'NaN', '-inf', 'inf', '1.0', 'NaN', '-inf',
|
||||
'inf', '1.0', 'NaN', '-inf', 'inf', '1.0', 'NaN', '-1.0'
|
||||
]], [[
|
||||
'-inf', '-inf', '-inf', '-inf', '-inf', 'inf', '1.0', 'inf', '-inf',
|
||||
'inf', '1.0', 'NaN', '-inf', '1.0', '-1.0', '-1.0', '-1.0'
|
||||
], [
|
||||
'-inf', 'inf', '1.0', '-inf', 'inf', 'inf', 'inf', 'inf', '-inf',
|
||||
'inf', '1.0', 'NaN', '1.0', 'inf', '1.0', '-1.0', '1.0'
|
||||
]], 'cs_6_0', ''' struct SBinaryHalfOp {
|
||||
half input1;
|
||||
half input2;
|
||||
half output1;
|
||||
half output2;
|
||||
};
|
||||
RWStructuredBuffer<SBinaryHalfOp> g_buf : register(u0);
|
||||
[numthreads(8,8,1)]
|
||||
void main(uint GI : SV_GroupIndex) {
|
||||
SBinaryHalfOp l = g_buf[GI];
|
||||
l.output1 = min(l.input1, l.input2);
|
||||
l.output2 = max(l.input1, l.input2);
|
||||
g_buf[GI] = l;
|
||||
};''')
|
||||
add_test_case_float_half('FAdd', ['FAdd'], 'ulp', 1, [['-1.0', '1.0', '32.5', '1.0000001000'],['4', '5.5', '334.7', '0.5000001000']], [['3.0', '6.5', '367.2', '1.5000002000']],
|
||||
"binary float", "+")
|
||||
add_test_case_float_half('FSub', ['FSub'], 'ulp', 1, [['-1.0', '5.5', '32.5', '1.0000001000'],['4', '1.25', '334.7', '0.5000001000']], [['-5', '4.25', '-302.2', '0.5000']],
|
||||
"binary float", "-")
|
||||
add_test_case_float_half('FMul', ['FMul'], 'ulp', 1, [['-1.0', '5.5', '1.0000001'],['4', '1.25', '2.0']], [['-4.0', '6.875', '2.0000002']],
|
||||
"binary float", "*")
|
||||
add_test_case_float_half('FDiv', ['FDiv'], 'ulp', 1, [['-1.0', '5.5', '1.0000001'],['4', '1.25', '2.0']], [['-0.25', '4.4', '0.50000006']],
|
||||
"binary float", "/")
|
||||
|
||||
# Denorm Binary Float
|
||||
add_test_case_denorm('FAddDenorm', ['FAdd'], 'ulp', 1,
|
||||
|
@ -544,7 +675,7 @@ def add_test_cases():
|
|||
[['0x00018000','0x007F0000', '0', '0x01960000', '0x32400000']],
|
||||
'cs_6_2', get_shader_text("binary float", "*"))
|
||||
# Tertiary Float
|
||||
add_test_case('FMad', ['FMad'], 'ulp', 1, [[
|
||||
add_test_case_float_half('FMad', ['FMad'], 'ulp', 1, [[
|
||||
'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '1.0', '-1.0',
|
||||
'0', '1', '1.5'
|
||||
], [
|
||||
|
@ -554,7 +685,7 @@ def add_test_cases():
|
|||
'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '1.0', '-1.0',
|
||||
'1', '0', '-5.5'
|
||||
]], [['NaN', 'NaN', '0', '0', '0', '0', 'Inf', '2', '0', '1', '1', '9.5']],
|
||||
'cs_6_0', get_shader_text("tertiary float", "mad"))
|
||||
"tertiary float", "mad")
|
||||
|
||||
# Denorm Tertiary Float
|
||||
add_test_case_denorm('FMadDenorm', ['FMad'], 'ulp', 1,
|
||||
|
@ -1085,10 +1216,21 @@ def generate_table_for_taef():
|
|||
"Id": "BinaryFloatOpTable"
|
||||
}), 2, 2)
|
||||
generate_parameter_types(
|
||||
ET.SubElement(
|
||||
root, "Table", attrib={
|
||||
ET.SubElement(root, "Table", attrib={
|
||||
"Id": "TertiaryFloatOpTable"
|
||||
}), 3, 1)
|
||||
generate_parameter_types(
|
||||
ET.SubElement(root, "Table", attrib={
|
||||
"Id": "UnaryHalfOpTable"
|
||||
}), 1, 1, True)
|
||||
generate_parameter_types(
|
||||
ET.SubElement(root, "Table", attrib={
|
||||
"Id": "BinaryHalfOpTable"
|
||||
}), 2, 2)
|
||||
generate_parameter_types(
|
||||
ET.SubElement(root, "Table", attrib={
|
||||
"Id": "TertiaryHalfOpTable"
|
||||
}), 3, 1)
|
||||
generate_parameter_types(
|
||||
ET.SubElement(root, "Table", attrib={
|
||||
"Id": "UnaryIntOpTable"
|
||||
|
@ -1155,10 +1297,12 @@ def generate_table_for_taef():
|
|||
for case in g_test_cases.values():
|
||||
cur_inst = case.insts[0]
|
||||
if cur_inst.is_cast or cur_inst.category.startswith("Unary"):
|
||||
if "f" in cur_inst.oload_types:
|
||||
if "f" in cur_inst.oload_types and not "Half" in case.test_name:
|
||||
generate_row(
|
||||
root.find("./Table[@Id='UnaryFloatOpTable']"),
|
||||
case)
|
||||
if "h" in cur_inst.oload_types and "Half" in case.test_name:
|
||||
generate_row(root.find("./Table[@Id='UnaryHalfOpTable']"),case)
|
||||
if "i" in cur_inst.oload_types:
|
||||
if cur_inst.category.startswith("Unary int"):
|
||||
generate_row(
|
||||
|
@ -1173,7 +1317,7 @@ def generate_table_for_taef():
|
|||
print(cur_inst.dxil_class)
|
||||
elif cur_inst.is_binary or cur_inst.category.startswith(
|
||||
"Binary"):
|
||||
if "f" in cur_inst.oload_types:
|
||||
if "f" in cur_inst.oload_types and not "Half" in case.test_name:
|
||||
if case.test_name in g_denorm_tests: # for denorm tests
|
||||
generate_row(
|
||||
root.find("./Table[@Id='DenormBinaryFloatOpTable']"),
|
||||
|
@ -1182,7 +1326,9 @@ def generate_table_for_taef():
|
|||
generate_row(
|
||||
root.find("./Table[@Id='BinaryFloatOpTable']"),
|
||||
case)
|
||||
elif "i" in cur_inst.oload_types:
|
||||
if "h" in cur_inst.oload_types and "Half" in case.test_name:
|
||||
generate_row(root.find("./Table[@Id='BinaryHalfOpTable']"),case)
|
||||
if "i" in cur_inst.oload_types:
|
||||
if cur_inst.category.startswith("Binary int"):
|
||||
if case.test_name in ['UAdd', 'USub', 'UMul']: # Add, Sub, Mul use same operations for int and uint.
|
||||
generate_row(
|
||||
|
@ -1201,16 +1347,16 @@ def generate_table_for_taef():
|
|||
print(cur_inst.dxil_class)
|
||||
|
||||
elif cur_inst.category.startswith("Tertiary"):
|
||||
if "f" in cur_inst.oload_types:
|
||||
if "f" in cur_inst.oload_types and not "Half" in case.test_name:
|
||||
if case.test_name in g_denorm_tests: # for denorm tests
|
||||
generate_row(
|
||||
root.find("./Table[@Id='DenormTertiaryFloatOpTable']"),
|
||||
case)
|
||||
root.find("./Table[@Id='DenormTertiaryFloatOpTable']"),case)
|
||||
else:
|
||||
generate_row(
|
||||
root.find("./Table[@Id='TertiaryFloatOpTable']"),
|
||||
case)
|
||||
elif "i" in cur_inst.oload_types:
|
||||
root.find("./Table[@Id='TertiaryFloatOpTable']"),case)
|
||||
if "h" in cur_inst.oload_types and "Half" in case.test_name:
|
||||
generate_row(root.find("./Table[@Id='TertiaryHalfOpTable']"),case)
|
||||
if "i" in cur_inst.oload_types:
|
||||
if cur_inst.category.startswith("Tertiary int"):
|
||||
generate_row(
|
||||
root.find("./Table[@Id='TertiaryIntOpTable']"),
|
||||
|
@ -1223,9 +1369,6 @@ def generate_table_for_taef():
|
|||
else:
|
||||
print("unknown op: " + cur_inst.name)
|
||||
print(cur_inst.dxil_class)
|
||||
else:
|
||||
print("unknown op: " + cur_inst.name)
|
||||
print(cur_inst.dxil_class)
|
||||
elif cur_inst.category.startswith("Quaternary"):
|
||||
if cur_inst.name == "Bfi":
|
||||
generate_row(
|
||||
|
|
|
@ -12,6 +12,7 @@ set TEST_ALL=1
|
|||
set TEST_CLANG=0
|
||||
set TEST_CMD=0
|
||||
set TEST_EXEC=0
|
||||
set TEST_EXEC_FUTURE=0
|
||||
set TEST_EXTRAS=0
|
||||
set TEST_EXEC_REQUIRED=0
|
||||
set TEST_CLANG_FILTER= /select: "@Priority<1"
|
||||
|
@ -110,6 +111,18 @@ if "%1"=="-clean" (
|
|||
set TEST_EXEC_FILTER=ExecutionTest::%2
|
||||
set TEST_EXEC_REQUIRED=1
|
||||
shift /1
|
||||
) else if "%1"=="exec-future" (
|
||||
set TEST_ALL=0
|
||||
set TEST_EXEC=1
|
||||
set TEST_EXEC_FUTURE=1
|
||||
set TEST_EXEC_REQUIRED=1
|
||||
) else if "%1"=="exec-future-filter" (
|
||||
set TEST_ALL=0
|
||||
set TEST_EXEC=1
|
||||
set TEST_EXEC_FUTURE=1
|
||||
set TEST_EXEC_FILTER=ExecutionTest::%2
|
||||
set TEST_EXEC_REQUIRED=1
|
||||
shift /1
|
||||
) else if "%1"=="extras" (
|
||||
set TEST_ALL=0
|
||||
set TEST_EXTRAS=1
|
||||
|
@ -247,7 +260,11 @@ if "%TEST_EXEC%"=="1" (
|
|||
)
|
||||
|
||||
if "%TEST_EXEC%"=="1" (
|
||||
if "%TEST_EXEC_FUTURE%"=="1" (
|
||||
call :runte clang-hlsl-tests.dll /p:"HlslDataDir=%HLSL_SRC_DIR%\tools\clang\test\HLSL" /select:"@Name='%TEST_EXEC_FILTER%' AND @Priority=2" /runIgnoredTests /p:"ExperimentalShaders=*" %TEST_ADAPTER% %ADDITIONAL_OPTS%
|
||||
) else (
|
||||
call :runte clang-hlsl-tests.dll /p:"HlslDataDir=%HLSL_SRC_DIR%\tools\clang\test\HLSL" /select:"@Name='%TEST_EXEC_FILTER%' AND @Priority<2" /runIgnoredTests /p:"ExperimentalShaders=*" %TEST_ADAPTER% %ADDITIONAL_OPTS%
|
||||
)
|
||||
set RES_EXEC=!ERRORLEVEL!
|
||||
)
|
||||
|
||||
|
@ -331,12 +348,14 @@ echo - hcttest compat-suite "..\CodeGenHLSL\shader-compat-suite\l
|
|||
echo cmd - run command line tool tests.
|
||||
echo v - run the subset of clang tests that are verified-based.
|
||||
echo exec - run execution tests.
|
||||
echo exec-future - run execution tests for future releases.
|
||||
echo extras - run hcttest-extras tests.
|
||||
echo noexec - all except exec and extras tests.
|
||||
echo.
|
||||
echo Select clang or exec targets with filter by test name:
|
||||
echo clang-filter Name
|
||||
echo exec-filter Name
|
||||
echo exec-exp-filter Name
|
||||
echo.
|
||||
echo Use the HCT_EXTRAS environment variable to add hcttest-before and hcttest-after hooks.
|
||||
echo.
|
||||
|
|
Загрузка…
Ссылка в новой задаче