spirv-reader: support more integer builtins
Support: - SAbs - UMax, SMax - UMin, SMin Add tests for operand and result conversion for UClamp. SClamp was already tested. Bug: tint:3 Change-Id: I9b9278843ca5243991b330b27764756137da4ee4 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/35302 Reviewed-by: dan sinclair <dsinclair@chromium.org> Commit-Queue: David Neto <dneto@google.com> Auto-Submit: David Neto <dneto@google.com>
This commit is contained in:
parent
3ca59444cd
commit
287f6f12ef
|
@ -326,6 +326,7 @@ ast::BinaryOp NegatedFloatCompare(SpvOp opcode) {
|
||||||
std::string GetGlslStd450FuncName(uint32_t ext_opcode) {
|
std::string GetGlslStd450FuncName(uint32_t ext_opcode) {
|
||||||
switch (ext_opcode) {
|
switch (ext_opcode) {
|
||||||
case GLSLstd450FAbs:
|
case GLSLstd450FAbs:
|
||||||
|
case GLSLstd450SAbs:
|
||||||
return "abs";
|
return "abs";
|
||||||
case GLSLstd450Acos:
|
case GLSLstd450Acos:
|
||||||
return "acos";
|
return "acos";
|
||||||
|
@ -374,9 +375,13 @@ std::string GetGlslStd450FuncName(uint32_t ext_opcode) {
|
||||||
return "log2";
|
return "log2";
|
||||||
case GLSLstd450NMax:
|
case GLSLstd450NMax:
|
||||||
case GLSLstd450FMax: // FMax is less prescriptive about NaN operands
|
case GLSLstd450FMax: // FMax is less prescriptive about NaN operands
|
||||||
|
case GLSLstd450UMax:
|
||||||
|
case GLSLstd450SMax:
|
||||||
return "max";
|
return "max";
|
||||||
case GLSLstd450NMin:
|
case GLSLstd450NMin:
|
||||||
case GLSLstd450FMin: // FMin is less prescriptive about NaN operands
|
case GLSLstd450FMin: // FMin is less prescriptive about NaN operands
|
||||||
|
case GLSLstd450UMin:
|
||||||
|
case GLSLstd450SMin:
|
||||||
return "min";
|
return "min";
|
||||||
case GLSLstd450FMix:
|
case GLSLstd450FMix:
|
||||||
return "mix";
|
return "mix";
|
||||||
|
@ -411,7 +416,6 @@ std::string GetGlslStd450FuncName(uint32_t ext_opcode) {
|
||||||
// TODO(dneto) - The following are not implemented.
|
// TODO(dneto) - The following are not implemented.
|
||||||
// They are grouped semantically, as in GLSL.std.450.h.
|
// They are grouped semantically, as in GLSL.std.450.h.
|
||||||
case GLSLstd450RoundEven:
|
case GLSLstd450RoundEven:
|
||||||
case GLSLstd450SAbs:
|
|
||||||
case GLSLstd450SSign:
|
case GLSLstd450SSign:
|
||||||
|
|
||||||
case GLSLstd450Radians:
|
case GLSLstd450Radians:
|
||||||
|
@ -425,10 +429,6 @@ std::string GetGlslStd450FuncName(uint32_t ext_opcode) {
|
||||||
|
|
||||||
case GLSLstd450Modf:
|
case GLSLstd450Modf:
|
||||||
case GLSLstd450ModfStruct:
|
case GLSLstd450ModfStruct:
|
||||||
case GLSLstd450UMin:
|
|
||||||
case GLSLstd450SMin:
|
|
||||||
case GLSLstd450UMax:
|
|
||||||
case GLSLstd450SMax:
|
|
||||||
case GLSLstd450IMix:
|
case GLSLstd450IMix:
|
||||||
|
|
||||||
case GLSLstd450Frexp:
|
case GLSLstd450Frexp:
|
||||||
|
|
|
@ -161,8 +161,14 @@ using SpvParserTest_GlslStd450_Floating_FloatingUinting =
|
||||||
using SpvParserTest_GlslStd450_Float3_Float3Float3 =
|
using SpvParserTest_GlslStd450_Float3_Float3Float3 =
|
||||||
SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
|
SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
|
||||||
|
|
||||||
|
using SpvParserTest_GlslStd450_Inting_Inting =
|
||||||
|
SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
|
||||||
|
using SpvParserTest_GlslStd450_Inting_IntingInting =
|
||||||
|
SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
|
||||||
using SpvParserTest_GlslStd450_Inting_IntingIntingInting =
|
using SpvParserTest_GlslStd450_Inting_IntingIntingInting =
|
||||||
SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
|
SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
|
||||||
|
using SpvParserTest_GlslStd450_Uinting_UintingUinting =
|
||||||
|
SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
|
||||||
using SpvParserTest_GlslStd450_Uinting_UintingUintingUinting =
|
using SpvParserTest_GlslStd450_Uinting_UintingUintingUinting =
|
||||||
SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
|
SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
|
||||||
|
|
||||||
|
@ -691,6 +697,128 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
{"FMix", "mix"},
|
{"FMix", "mix"},
|
||||||
{"SmoothStep", "smoothStep"}}));
|
{"SmoothStep", "smoothStep"}}));
|
||||||
|
|
||||||
|
TEST_P(SpvParserTest_GlslStd450_Inting_Inting, Scalar) {
|
||||||
|
const auto assembly = Preamble() + R"(
|
||||||
|
%1 = OpExtInst %int %glsl )" +
|
||||||
|
GetParam().opcode +
|
||||||
|
R"( %i1
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(R"(
|
||||||
|
VariableConst{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
__i32
|
||||||
|
{
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{)" + GetParam().wgsl_func +
|
||||||
|
R"(}
|
||||||
|
(
|
||||||
|
Identifier[not set]{i1}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< ToString(fe.ast_body());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(SpvParserTest_GlslStd450_Inting_Inting, Vector) {
|
||||||
|
const auto assembly = Preamble() + R"(
|
||||||
|
%1 = OpExtInst %v2int %glsl )" +
|
||||||
|
GetParam().opcode +
|
||||||
|
R"( %v2i1
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(R"(
|
||||||
|
VariableConst{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
__vec_2__i32
|
||||||
|
{
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{)" + GetParam().wgsl_func +
|
||||||
|
R"(}
|
||||||
|
(
|
||||||
|
Identifier[not set]{v2i1}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< ToString(fe.ast_body());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(SpvParserTest_GlslStd450_Inting_IntingInting, Scalar) {
|
||||||
|
const auto assembly = Preamble() + R"(
|
||||||
|
%1 = OpExtInst %int %glsl )" +
|
||||||
|
GetParam().opcode +
|
||||||
|
R"( %i1 %i2
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(R"(
|
||||||
|
VariableConst{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
__i32
|
||||||
|
{
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{)" + GetParam().wgsl_func +
|
||||||
|
R"(}
|
||||||
|
(
|
||||||
|
Identifier[not set]{i1}
|
||||||
|
Identifier[not set]{i2}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< ToString(fe.ast_body());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(SpvParserTest_GlslStd450_Inting_IntingInting, Vector) {
|
||||||
|
const auto assembly = Preamble() + R"(
|
||||||
|
%1 = OpExtInst %v2int %glsl )" +
|
||||||
|
GetParam().opcode +
|
||||||
|
R"( %v2i1 %v2i2
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(R"(
|
||||||
|
VariableConst{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
__vec_2__i32
|
||||||
|
{
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{)" + GetParam().wgsl_func +
|
||||||
|
R"(}
|
||||||
|
(
|
||||||
|
Identifier[not set]{v2i1}
|
||||||
|
Identifier[not set]{v2i2}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< ToString(fe.ast_body());
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(SpvParserTest_GlslStd450_Inting_IntingIntingInting, Scalar) {
|
TEST_P(SpvParserTest_GlslStd450_Inting_IntingIntingInting, Scalar) {
|
||||||
const auto assembly = Preamble() + R"(
|
const auto assembly = Preamble() + R"(
|
||||||
%1 = OpExtInst %int %glsl )" +
|
%1 = OpExtInst %int %glsl )" +
|
||||||
|
@ -755,10 +883,80 @@ TEST_P(SpvParserTest_GlslStd450_Inting_IntingIntingInting, Vector) {
|
||||||
<< ToString(fe.ast_body());
|
<< ToString(fe.ast_body());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(Samples,
|
||||||
|
SpvParserTest_GlslStd450_Inting_Inting,
|
||||||
|
::testing::Values(GlslStd450Case{"SAbs", "abs"}));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(Samples,
|
||||||
|
SpvParserTest_GlslStd450_Inting_IntingInting,
|
||||||
|
::testing::Values(GlslStd450Case{"SMax", "max"},
|
||||||
|
GlslStd450Case{"SMin", "min"}));
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(Samples,
|
INSTANTIATE_TEST_SUITE_P(Samples,
|
||||||
SpvParserTest_GlslStd450_Inting_IntingIntingInting,
|
SpvParserTest_GlslStd450_Inting_IntingIntingInting,
|
||||||
::testing::Values(GlslStd450Case{"SClamp", "clamp"}));
|
::testing::Values(GlslStd450Case{"SClamp", "clamp"}));
|
||||||
|
|
||||||
|
TEST_P(SpvParserTest_GlslStd450_Uinting_UintingUinting, Scalar) {
|
||||||
|
const auto assembly = Preamble() + R"(
|
||||||
|
%1 = OpExtInst %uint %glsl )" +
|
||||||
|
GetParam().opcode + R"( %u1 %u2
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(R"(
|
||||||
|
VariableConst{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
__u32
|
||||||
|
{
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{)" + GetParam().wgsl_func +
|
||||||
|
R"(}
|
||||||
|
(
|
||||||
|
Identifier[not set]{u1}
|
||||||
|
Identifier[not set]{u2}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< ToString(fe.ast_body());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(SpvParserTest_GlslStd450_Uinting_UintingUinting, Vector) {
|
||||||
|
const auto assembly = Preamble() + R"(
|
||||||
|
%1 = OpExtInst %v2uint %glsl )" +
|
||||||
|
GetParam().opcode +
|
||||||
|
R"( %v2u1 %v2u2
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(R"(
|
||||||
|
VariableConst{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
__vec_2__u32
|
||||||
|
{
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{)" + GetParam().wgsl_func +
|
||||||
|
R"(}
|
||||||
|
(
|
||||||
|
Identifier[not set]{v2u1}
|
||||||
|
Identifier[not set]{v2u2}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< ToString(fe.ast_body());
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(SpvParserTest_GlslStd450_Uinting_UintingUintingUinting, Scalar) {
|
TEST_P(SpvParserTest_GlslStd450_Uinting_UintingUintingUinting, Scalar) {
|
||||||
const auto assembly = Preamble() + R"(
|
const auto assembly = Preamble() + R"(
|
||||||
%1 = OpExtInst %uint %glsl )" +
|
%1 = OpExtInst %uint %glsl )" +
|
||||||
|
@ -822,11 +1020,187 @@ TEST_P(SpvParserTest_GlslStd450_Uinting_UintingUintingUinting, Vector) {
|
||||||
<< ToString(fe.ast_body());
|
<< ToString(fe.ast_body());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(Samples,
|
||||||
|
SpvParserTest_GlslStd450_Uinting_UintingUinting,
|
||||||
|
::testing::Values(GlslStd450Case{"UMax", "max"},
|
||||||
|
GlslStd450Case{"UMin", "min"}));
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(Samples,
|
INSTANTIATE_TEST_SUITE_P(Samples,
|
||||||
SpvParserTest_GlslStd450_Uinting_UintingUintingUinting,
|
SpvParserTest_GlslStd450_Uinting_UintingUintingUinting,
|
||||||
::testing::Values(GlslStd450Case{"UClamp", "clamp"}));
|
::testing::Values(GlslStd450Case{"UClamp", "clamp"}));
|
||||||
|
|
||||||
TEST_F(SpvParserTest, RectifyOperandsAndResult_GLSLstd450SClamp) {
|
// Check that we convert signedness of operands and result type.
|
||||||
|
// This is needed for each of the integer-based extended instructions.
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, RectifyOperandsAndResult_SAbs) {
|
||||||
|
const auto assembly = Preamble() + R"(
|
||||||
|
%1 = OpExtInst %uint %glsl SAbs %u1
|
||||||
|
%2 = OpExtInst %v2uint %glsl SAbs %v2u1
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
auto body = ToString(fe.ast_body());
|
||||||
|
EXPECT_THAT(body, HasSubstr(R"(
|
||||||
|
VariableConst{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
__u32
|
||||||
|
{
|
||||||
|
Bitcast[not set]<__u32>{
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{abs}
|
||||||
|
(
|
||||||
|
Bitcast[not set]<__i32>{
|
||||||
|
Identifier[not set]{u1}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< body;
|
||||||
|
EXPECT_THAT(body, HasSubstr(R"(
|
||||||
|
VariableConst{
|
||||||
|
x_2
|
||||||
|
none
|
||||||
|
__vec_2__u32
|
||||||
|
{
|
||||||
|
Bitcast[not set]<__vec_2__u32>{
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{abs}
|
||||||
|
(
|
||||||
|
Bitcast[not set]<__vec_2__i32>{
|
||||||
|
Identifier[not set]{v2u1}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< body;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, RectifyOperandsAndResult_SMax) {
|
||||||
|
const auto assembly = Preamble() + R"(
|
||||||
|
%1 = OpExtInst %uint %glsl SMax %u1 %u2
|
||||||
|
%2 = OpExtInst %v2uint %glsl SMax %v2u1 %v2u2
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
auto body = ToString(fe.ast_body());
|
||||||
|
EXPECT_THAT(body, HasSubstr(R"(
|
||||||
|
VariableConst{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
__u32
|
||||||
|
{
|
||||||
|
Bitcast[not set]<__u32>{
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{max}
|
||||||
|
(
|
||||||
|
Bitcast[not set]<__i32>{
|
||||||
|
Identifier[not set]{u1}
|
||||||
|
}
|
||||||
|
Bitcast[not set]<__i32>{
|
||||||
|
Identifier[not set]{u2}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< body;
|
||||||
|
EXPECT_THAT(body, HasSubstr(R"(
|
||||||
|
VariableConst{
|
||||||
|
x_2
|
||||||
|
none
|
||||||
|
__vec_2__u32
|
||||||
|
{
|
||||||
|
Bitcast[not set]<__vec_2__u32>{
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{max}
|
||||||
|
(
|
||||||
|
Bitcast[not set]<__vec_2__i32>{
|
||||||
|
Identifier[not set]{v2u1}
|
||||||
|
}
|
||||||
|
Bitcast[not set]<__vec_2__i32>{
|
||||||
|
Identifier[not set]{v2u2}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< body;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, RectifyOperandsAndResult_SMin) {
|
||||||
|
const auto assembly = Preamble() + R"(
|
||||||
|
%1 = OpExtInst %uint %glsl SMin %u1 %u2
|
||||||
|
%2 = OpExtInst %v2uint %glsl SMin %v2u1 %v2u2
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
auto body = ToString(fe.ast_body());
|
||||||
|
EXPECT_THAT(body, HasSubstr(R"(
|
||||||
|
VariableConst{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
__u32
|
||||||
|
{
|
||||||
|
Bitcast[not set]<__u32>{
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{min}
|
||||||
|
(
|
||||||
|
Bitcast[not set]<__i32>{
|
||||||
|
Identifier[not set]{u1}
|
||||||
|
}
|
||||||
|
Bitcast[not set]<__i32>{
|
||||||
|
Identifier[not set]{u2}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< body;
|
||||||
|
EXPECT_THAT(body, HasSubstr(R"(
|
||||||
|
VariableConst{
|
||||||
|
x_2
|
||||||
|
none
|
||||||
|
__vec_2__u32
|
||||||
|
{
|
||||||
|
Bitcast[not set]<__vec_2__u32>{
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{min}
|
||||||
|
(
|
||||||
|
Bitcast[not set]<__vec_2__i32>{
|
||||||
|
Identifier[not set]{v2u1}
|
||||||
|
}
|
||||||
|
Bitcast[not set]<__vec_2__i32>{
|
||||||
|
Identifier[not set]{v2u2}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< body;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, RectifyOperandsAndResult_SClamp) {
|
||||||
const auto assembly = Preamble() + R"(
|
const auto assembly = Preamble() + R"(
|
||||||
%1 = OpExtInst %uint %glsl SClamp %u1 %i2 %u3
|
%1 = OpExtInst %uint %glsl SClamp %u1 %i2 %u3
|
||||||
%2 = OpExtInst %v2uint %glsl SClamp %v2u1 %v2i2 %v2u3
|
%2 = OpExtInst %v2uint %glsl SClamp %v2u1 %v2i2 %v2u3
|
||||||
|
@ -886,6 +1260,182 @@ TEST_F(SpvParserTest, RectifyOperandsAndResult_GLSLstd450SClamp) {
|
||||||
<< body;
|
<< body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, RectifyOperandsAndResult_UMax) {
|
||||||
|
const auto assembly = Preamble() + R"(
|
||||||
|
%1 = OpExtInst %int %glsl UMax %i1 %i2
|
||||||
|
%2 = OpExtInst %v2int %glsl UMax %v2i1 %v2i2
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
auto body = ToString(fe.ast_body());
|
||||||
|
EXPECT_THAT(body, HasSubstr(R"(
|
||||||
|
VariableConst{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
__i32
|
||||||
|
{
|
||||||
|
Bitcast[not set]<__i32>{
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{max}
|
||||||
|
(
|
||||||
|
Bitcast[not set]<__u32>{
|
||||||
|
Identifier[not set]{i1}
|
||||||
|
}
|
||||||
|
Bitcast[not set]<__u32>{
|
||||||
|
Identifier[not set]{i2}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< body;
|
||||||
|
EXPECT_THAT(body, HasSubstr(R"(
|
||||||
|
VariableConst{
|
||||||
|
x_2
|
||||||
|
none
|
||||||
|
__vec_2__i32
|
||||||
|
{
|
||||||
|
Bitcast[not set]<__vec_2__i32>{
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{max}
|
||||||
|
(
|
||||||
|
Bitcast[not set]<__vec_2__u32>{
|
||||||
|
Identifier[not set]{v2i1}
|
||||||
|
}
|
||||||
|
Bitcast[not set]<__vec_2__u32>{
|
||||||
|
Identifier[not set]{v2i2}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< body;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, RectifyOperandsAndResult_UMin) {
|
||||||
|
const auto assembly = Preamble() + R"(
|
||||||
|
%1 = OpExtInst %int %glsl UMin %i1 %i2
|
||||||
|
%2 = OpExtInst %v2int %glsl UMin %v2i1 %v2i2
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
auto body = ToString(fe.ast_body());
|
||||||
|
EXPECT_THAT(body, HasSubstr(R"(
|
||||||
|
VariableConst{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
__i32
|
||||||
|
{
|
||||||
|
Bitcast[not set]<__i32>{
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{min}
|
||||||
|
(
|
||||||
|
Bitcast[not set]<__u32>{
|
||||||
|
Identifier[not set]{i1}
|
||||||
|
}
|
||||||
|
Bitcast[not set]<__u32>{
|
||||||
|
Identifier[not set]{i2}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< body;
|
||||||
|
EXPECT_THAT(body, HasSubstr(R"(
|
||||||
|
VariableConst{
|
||||||
|
x_2
|
||||||
|
none
|
||||||
|
__vec_2__i32
|
||||||
|
{
|
||||||
|
Bitcast[not set]<__vec_2__i32>{
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{min}
|
||||||
|
(
|
||||||
|
Bitcast[not set]<__vec_2__u32>{
|
||||||
|
Identifier[not set]{v2i1}
|
||||||
|
}
|
||||||
|
Bitcast[not set]<__vec_2__u32>{
|
||||||
|
Identifier[not set]{v2i2}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< body;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, RectifyOperandsAndResult_UClamp) {
|
||||||
|
const auto assembly = Preamble() + R"(
|
||||||
|
%1 = OpExtInst %int %glsl UClamp %i1 %u2 %i3
|
||||||
|
%2 = OpExtInst %v2int %glsl UClamp %v2i1 %v2u2 %v2i3
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
auto body = ToString(fe.ast_body());
|
||||||
|
EXPECT_THAT(body, HasSubstr(R"(
|
||||||
|
VariableConst{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
__i32
|
||||||
|
{
|
||||||
|
Bitcast[not set]<__i32>{
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{clamp}
|
||||||
|
(
|
||||||
|
Bitcast[not set]<__u32>{
|
||||||
|
Identifier[not set]{i1}
|
||||||
|
}
|
||||||
|
Identifier[not set]{u2}
|
||||||
|
Bitcast[not set]<__u32>{
|
||||||
|
Identifier[not set]{i3}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< body;
|
||||||
|
EXPECT_THAT(body, HasSubstr(R"(
|
||||||
|
VariableConst{
|
||||||
|
x_2
|
||||||
|
none
|
||||||
|
__vec_2__i32
|
||||||
|
{
|
||||||
|
Bitcast[not set]<__vec_2__i32>{
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{clamp}
|
||||||
|
(
|
||||||
|
Bitcast[not set]<__vec_2__u32>{
|
||||||
|
Identifier[not set]{v2i1}
|
||||||
|
}
|
||||||
|
Identifier[not set]{v2u2}
|
||||||
|
Bitcast[not set]<__vec_2__u32>{
|
||||||
|
Identifier[not set]{v2i3}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< body;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace spirv
|
} // namespace spirv
|
||||||
} // namespace reader
|
} // namespace reader
|
||||||
|
|
Loading…
Reference in New Issue