spirv-reader: Make SPIR-V unit tests valid for WebGPU

- Add missing DescriptorSet and Binding decorations.
- Add missing Phi inbound edge
- Add a preamble with an OpMemoryModel instruction
- Add a preamble and an empty entry point that is not involved with the
  test (sometimes)
- Disable dumping of test with known bad output (tint:863, tint:98)
- Fix storage classes on variables

Bug: tint:863, tint:98
Change-Id: I56b92e8951f5749e094424f8e2da1a2396b5c10c
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/53261
Auto-Submit: David Neto <dneto@google.com>
Commit-Queue: James Price <jrprice@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: James Price <jrprice@google.com>
This commit is contained in:
David Neto 2021-06-07 20:40:04 +00:00 committed by Tint LUCI CQ
parent 9566742f2a
commit edb644c821
10 changed files with 344 additions and 168 deletions

View File

@ -25,8 +25,16 @@ namespace {
using ::testing::Eq; using ::testing::Eq;
using ::testing::HasSubstr; using ::testing::HasSubstr;
std::string Preamble() {
return R"(
OpCapability Shader
OpMemoryModel Logical Simple
OpEntryPoint Vertex %100 "x_100"
)";
}
TEST_F(SpvParserTest, EmitStatement_VoidCallNoParams) { TEST_F(SpvParserTest, EmitStatement_VoidCallNoParams) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%void = OpTypeVoid %void = OpTypeVoid
%voidfn = OpTypeFunction %void %voidfn = OpTypeFunction %void
@ -50,6 +58,7 @@ TEST_F(SpvParserTest, EmitStatement_VoidCallNoParams) {
Return{} Return{}
} }
Function $2 -> __void Function $2 -> __void
StageDecoration{vertex}
() ()
{ {
Call[not set]{ Call[not set]{
@ -65,7 +74,7 @@ TEST_F(SpvParserTest, EmitStatement_VoidCallNoParams) {
} }
TEST_F(SpvParserTest, EmitStatement_ScalarCallNoParams) { TEST_F(SpvParserTest, EmitStatement_ScalarCallNoParams) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%void = OpTypeVoid %void = OpTypeVoid
%voidfn = OpTypeFunction %void %voidfn = OpTypeFunction %void
%uint = OpTypeInt 32 0 %uint = OpTypeInt 32 0
@ -118,7 +127,7 @@ Return{})"));
} }
TEST_F(SpvParserTest, EmitStatement_ScalarCallNoParamsUsedTwice) { TEST_F(SpvParserTest, EmitStatement_ScalarCallNoParamsUsedTwice) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%void = OpTypeVoid %void = OpTypeVoid
%voidfn = OpTypeFunction %void %voidfn = OpTypeFunction %void
%uint = OpTypeInt 32 0 %uint = OpTypeInt 32 0
@ -190,7 +199,7 @@ Return{})"));
} }
TEST_F(SpvParserTest, EmitStatement_CallWithParams) { TEST_F(SpvParserTest, EmitStatement_CallWithParams) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%void = OpTypeVoid %void = OpTypeVoid
%voidfn = OpTypeFunction %void %voidfn = OpTypeFunction %void
%uint = OpTypeInt 32 0 %uint = OpTypeInt 32 0
@ -243,6 +252,7 @@ TEST_F(SpvParserTest, EmitStatement_CallWithParams) {
} }
} }
Function x_100 -> __void Function x_100 -> __void
StageDecoration{vertex}
() ()
{ {
VariableDeclStatement{ VariableDeclStatement{

View File

@ -25,13 +25,17 @@ namespace {
using ::testing::Eq; using ::testing::Eq;
using ::testing::HasSubstr; using ::testing::HasSubstr;
std::string Preamble() { std::string Caps() {
return R"( return R"(
OpCapability Shader OpCapability Shader
OpMemoryModel Logical Simple OpMemoryModel Logical Simple
OpEntryPoint GLCompute %100 "main" OpEntryPoint GLCompute %100 "main"
OpExecutionMode %100 LocalSize 1 1 1 OpExecutionMode %100 LocalSize 1 1 1
)";
}
std::string CommonTypes() {
return R"(
%void = OpTypeVoid %void = OpTypeVoid
%voidfn = OpTypeFunction %void %voidfn = OpTypeFunction %void
@ -71,6 +75,10 @@ std::string Preamble() {
)"; )";
} }
std::string Preamble() {
return Caps() + CommonTypes();
}
using SpvParserTest_Composite_Construct = SpvParserTest; using SpvParserTest_Composite_Construct = SpvParserTest;
TEST_F(SpvParserTest_Composite_Construct, Vector) { TEST_F(SpvParserTest_Composite_Construct, Vector) {
@ -458,11 +466,11 @@ TEST_F(SpvParserTest_CompositeExtract, Struct) {
} }
TEST_F(SpvParserTest_CompositeExtract, Struct_DifferOnlyInMemberName) { TEST_F(SpvParserTest_CompositeExtract, Struct_DifferOnlyInMemberName) {
const auto assembly = const auto assembly = Caps() +
R"( R"(
OpMemberName %s0 0 "algo" OpMemberName %s0 0 "algo"
OpMemberName %s1 0 "rithm" OpMemberName %s1 0 "rithm"
)" + Preamble() + )" + CommonTypes() +
R"( R"(
%s0 = OpTypeStruct %uint %s0 = OpTypeStruct %uint
%s1 = OpTypeStruct %uint %s1 = OpTypeStruct %uint
@ -513,6 +521,7 @@ TEST_F(SpvParserTest_CompositeExtract, Struct_DifferOnlyInMemberName) {
} }
})")) })"))
<< ToString(p->builder(), got); << ToString(p->builder(), got);
p->SkipDumpingPending("crbug.com/tint/863");
} }
TEST_F(SpvParserTest_CompositeExtract, Struct_IndexTooBigError) { TEST_F(SpvParserTest_CompositeExtract, Struct_IndexTooBigError) {
@ -904,11 +913,11 @@ VariableDeclStatement{
} }
TEST_F(SpvParserTest_CompositeInsert, Struct_DifferOnlyInMemberName) { TEST_F(SpvParserTest_CompositeInsert, Struct_DifferOnlyInMemberName) {
const auto assembly = const auto assembly = Caps() +
R"( R"(
OpMemberName %s0 0 "algo" OpMemberName %s0 0 "algo"
OpMemberName %s1 0 "rithm" OpMemberName %s1 0 "rithm"
)" + Preamble() + )" + CommonTypes() +
R"( R"(
%s0 = OpTypeStruct %uint %s0 = OpTypeStruct %uint
%s1 = OpTypeStruct %uint %s1 = OpTypeStruct %uint
@ -1057,6 +1066,7 @@ VariableDeclStatement{
} }
} }
})")) << body_str; })")) << body_str;
p->SkipDumpingPending("crbug.com/tint/863");
} }
TEST_F(SpvParserTest_CompositeInsert, Struct_IndexTooBigError) { TEST_F(SpvParserTest_CompositeInsert, Struct_IndexTooBigError) {

View File

@ -24,6 +24,14 @@ namespace {
using ::testing::HasSubstr; using ::testing::HasSubstr;
std::string Preamble() {
return R"(
OpCapability Shader
OpMemoryModel Logical Simple
OpEntryPoint Vertex %100 "x_100"
)";
}
/// @returns a SPIR-V assembly segment which assigns debug names /// @returns a SPIR-V assembly segment which assigns debug names
/// to particular IDs. /// to particular IDs.
std::string Names(std::vector<std::string> ids) { std::string Names(std::vector<std::string> ids) {
@ -45,8 +53,17 @@ std::string CommonTypes() {
)"; )";
} }
std::string MainBody() {
return R"(
%100 = OpFunction %void None %voidfn
%entry_100 = OpLabel
OpReturn
OpFunctionEnd
)";
}
TEST_F(SpvParserTest, Emit_VoidFunctionWithoutParams) { TEST_F(SpvParserTest, Emit_VoidFunctionWithoutParams) {
auto p = parser(test::Assemble(CommonTypes() + R"( auto p = parser(test::Assemble(Preamble() + CommonTypes() + R"(
%100 = OpFunction %void None %voidfn %100 = OpFunction %void None %voidfn
%entry = OpLabel %entry = OpLabel
OpReturn OpReturn
@ -68,20 +85,20 @@ TEST_F(SpvParserTest, Emit_VoidFunctionWithoutParams) {
} }
TEST_F(SpvParserTest, Emit_NonVoidResultType) { TEST_F(SpvParserTest, Emit_NonVoidResultType) {
auto p = parser(test::Assemble(CommonTypes() + R"( auto p = parser(test::Assemble(Preamble() + CommonTypes() + R"(
%fn_ret_float = OpTypeFunction %float %fn_ret_float = OpTypeFunction %float
%100 = OpFunction %float None %fn_ret_float %200 = OpFunction %float None %fn_ret_float
%entry = OpLabel %entry = OpLabel
OpReturnValue %float_0 OpReturnValue %float_0
OpFunctionEnd OpFunctionEnd
)")); )" + MainBody()));
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()); ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
auto fe = p->function_emitter(100); auto fe = p->function_emitter(200);
EXPECT_TRUE(fe.Emit()); EXPECT_TRUE(fe.Emit());
auto got = p->program().to_str(); auto got = p->program().to_str();
std::string expect = R"(Module{ std::string expect = R"(Module{
Function x_100 -> __f32 Function x_200 -> __f32
() ()
{ {
Return{ Return{
@ -92,28 +109,29 @@ TEST_F(SpvParserTest, Emit_NonVoidResultType) {
} }
} }
)"; )";
EXPECT_EQ(got, expect); EXPECT_THAT(got, HasSubstr(expect));
} }
TEST_F(SpvParserTest, Emit_MixedParamTypes) { TEST_F(SpvParserTest, Emit_MixedParamTypes) {
auto p = parser(test::Assemble(Names({"a", "b", "c"}) + CommonTypes() + R"( auto p = parser(
%fn_mixed_params = OpTypeFunction %float %uint %float %int test::Assemble(Preamble() + Names({"a", "b", "c"}) + CommonTypes() + R"(
%fn_mixed_params = OpTypeFunction %void %uint %float %int
%100 = OpFunction %void None %fn_mixed_params %200 = OpFunction %void None %fn_mixed_params
%a = OpFunctionParameter %uint %a = OpFunctionParameter %uint
%b = OpFunctionParameter %float %b = OpFunctionParameter %float
%c = OpFunctionParameter %int %c = OpFunctionParameter %int
%mixed_entry = OpLabel %mixed_entry = OpLabel
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
)")); )" + MainBody()));
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()); ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
auto fe = p->function_emitter(100); auto fe = p->function_emitter(200);
EXPECT_TRUE(fe.Emit()); EXPECT_TRUE(fe.Emit());
auto got = p->program().to_str(); auto got = p->program().to_str();
std::string expect = R"(Module{ std::string expect = R"(Module{
Function x_100 -> __void Function x_200 -> __void
( (
VariableConst{ VariableConst{
a a
@ -139,28 +157,28 @@ TEST_F(SpvParserTest, Emit_MixedParamTypes) {
} }
} }
)"; )";
EXPECT_EQ(got, expect); EXPECT_THAT(got, HasSubstr(expect));
} }
TEST_F(SpvParserTest, Emit_GenerateParamNames) { TEST_F(SpvParserTest, Emit_GenerateParamNames) {
auto p = parser(test::Assemble(CommonTypes() + R"( auto p = parser(test::Assemble(Preamble() + CommonTypes() + R"(
%fn_mixed_params = OpTypeFunction %float %uint %float %int %fn_mixed_params = OpTypeFunction %void %uint %float %int
%100 = OpFunction %void None %fn_mixed_params %200 = OpFunction %void None %fn_mixed_params
%14 = OpFunctionParameter %uint %14 = OpFunctionParameter %uint
%15 = OpFunctionParameter %float %15 = OpFunctionParameter %float
%16 = OpFunctionParameter %int %16 = OpFunctionParameter %int
%mixed_entry = OpLabel %mixed_entry = OpLabel
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
)")); )" + MainBody()));
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()); ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
auto fe = p->function_emitter(100); auto fe = p->function_emitter(200);
EXPECT_TRUE(fe.Emit()); EXPECT_TRUE(fe.Emit());
auto got = p->program().to_str(); auto got = p->program().to_str();
std::string expect = R"(Module{ std::string expect = R"(Module{
Function x_100 -> __void Function x_200 -> __void
( (
VariableConst{ VariableConst{
x_14 x_14
@ -186,7 +204,7 @@ TEST_F(SpvParserTest, Emit_GenerateParamNames) {
} }
} }
)"; )";
EXPECT_EQ(got, expect); EXPECT_THAT(got, HasSubstr(expect));
} }
} // namespace } // namespace

View File

@ -306,7 +306,7 @@ TEST_F(SpvParserMemoryTest,
%ptr_wg_ty = OpTypePointer Workgroup %ty %ptr_wg_ty = OpTypePointer Workgroup %ty
%ptr_priv_ty = OpTypePointer Private %ty %ptr_priv_ty = OpTypePointer Private %ty
%1 = OpVariable %ptr_wg_ty Workgroup %1 = OpVariable %ptr_wg_ty Workgroup
%2 = OpVariable %ptr_priv_ty Workgroup %2 = OpVariable %ptr_priv_ty Private
%100 = OpFunction %void None %voidfn %100 = OpFunction %void None %voidfn
%entry = OpLabel %entry = OpLabel
OpCopyMemory %2 %1 OpCopyMemory %2 %1
@ -1048,6 +1048,10 @@ Assignment{
} }
TEST_F(SpvParserMemoryTest, RemapStorageBuffer_ThroughCopyObject_WithHoisting) { TEST_F(SpvParserMemoryTest, RemapStorageBuffer_ThroughCopyObject_WithHoisting) {
// TODO(dneto): Hoisting non-storable values (pointers) is not yet supported.
// It's debatable whether this test should run at all.
// crbug.com/tint/98
// Like the previous test, but the declaration for the copy-object // Like the previous test, but the declaration for the copy-object
// has its declaration hoisted. // has its declaration hoisted.
const auto assembly = OldStorageBufferPreamble() + R"( const auto assembly = OldStorageBufferPreamble() + R"(
@ -1119,6 +1123,7 @@ Assignment{
} }
Return{} Return{}
)") << p->error(); )") << p->error();
p->SkipDumpingPending("crbug.com/tint/98");
} }
TEST_F(SpvParserMemoryTest, DISABLED_RemapStorageBuffer_ThroughFunctionCall) { TEST_F(SpvParserMemoryTest, DISABLED_RemapStorageBuffer_ThroughFunctionCall) {

View File

@ -130,7 +130,7 @@ TEST_F(SpvParserTestMiscInstruction, OpUndef_BeforeFunction_Vector) {
%100 = OpFunction %void None %voidfn %100 = OpFunction %void None %voidfn
%entry = OpLabel %entry = OpLabel
%14 = OpCopyObject %v2uint %4 %14 = OpCopyObject %v2bool %4
%11 = OpCopyObject %v2uint %1 %11 = OpCopyObject %v2uint %1
%12 = OpCopyObject %v2int %2 %12 = OpCopyObject %v2int %2
%13 = OpCopyObject %v2float %3 %13 = OpCopyObject %v2float %3

View File

@ -1951,7 +1951,7 @@ TEST_F(SpvParserFunctionVarTest, EmitStatement_Phi_FromElseAndThen) {
OpBranch %89 OpBranch %89
%89 = OpLabel %89 = OpLabel
%2 = OpPhi %uint %uint_0 %30 %uint_1 %40 %2 = OpPhi %uint %uint_0 %30 %uint_1 %40 %uint_0 %79
OpStore %1 %2 OpStore %1 %2
OpBranch %10 OpBranch %10
@ -2026,6 +2026,10 @@ Loop{
Continue{} Continue{}
} }
} }
Assignment{
Identifier[not set]{x_2_phi}
ScalarConstructor[not set]{0u}
}
continuing { continuing {
VariableDeclStatement{ VariableDeclStatement{
VariableConst{ VariableConst{

View File

@ -23,6 +23,25 @@ namespace {
using ::testing::Eq; using ::testing::Eq;
std::string Preamble() {
return R"(
OpCapability Shader
OpMemoryModel Logical Simple
OpEntryPoint Vertex %main "x_100"
)";
}
std::string MainBody() {
return R"(
%void = OpTypeVoid
%voidfn = OpTypeFunction %void
%main = OpFunction %void None %voidfn
%main_entry = OpLabel
OpReturn
OpFunctionEnd
)";
}
TEST_F(SpvParserTest, ConvertType_PreservesExistingFailure) { TEST_F(SpvParserTest, ConvertType_PreservesExistingFailure) {
auto p = parser(std::vector<uint32_t>{}); auto p = parser(std::vector<uint32_t>{});
p->Fail() << "boing"; p->Fail() << "boing";
@ -41,17 +60,24 @@ TEST_F(SpvParserTest, ConvertType_RequiresInternalRepresntation) {
} }
TEST_F(SpvParserTest, ConvertType_NotAnId) { TEST_F(SpvParserTest, ConvertType_NotAnId) {
auto p = parser(test::Assemble("%1 = OpExtInstImport \"GLSL.std.450\"")); auto assembly = Preamble() + MainBody();
auto p = parser(test::Assemble(assembly));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(10); auto* type = p->ConvertType(900);
EXPECT_EQ(type, nullptr); EXPECT_EQ(type, nullptr);
EXPECT_EQ(nullptr, type); EXPECT_EQ(nullptr, type);
EXPECT_THAT(p->error(), Eq("ID is not a SPIR-V type: 10")); EXPECT_THAT(p->error(), Eq("ID is not a SPIR-V type: 900"));
} }
TEST_F(SpvParserTest, ConvertType_IdExistsButIsNotAType) { TEST_F(SpvParserTest, ConvertType_IdExistsButIsNotAType) {
auto p = parser(test::Assemble("%1 = OpExtInstImport \"GLSL.std.450\"")); auto assembly = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical Simple
OpEntryPoint Vertex %main "x_100"
)" + MainBody();
auto p = parser(test::Assemble(assembly));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(1); auto* type = p->ConvertType(1);
@ -71,7 +97,13 @@ TEST_F(SpvParserTest, ConvertType_UnhandledType) {
} }
TEST_F(SpvParserTest, ConvertType_Void) { TEST_F(SpvParserTest, ConvertType_Void) {
auto p = parser(test::Assemble("%1 = OpTypeVoid")); auto p = parser(test::Assemble(Preamble() + "%1 = OpTypeVoid" + R"(
%voidfn = OpTypeFunction %1
%main = OpFunction %1 None %voidfn
%entry = OpLabel
OpReturn
OpFunctionEnd
)"));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(1); auto* type = p->ConvertType(1);
@ -80,7 +112,8 @@ TEST_F(SpvParserTest, ConvertType_Void) {
} }
TEST_F(SpvParserTest, ConvertType_Bool) { TEST_F(SpvParserTest, ConvertType_Bool) {
auto p = parser(test::Assemble("%100 = OpTypeBool")); auto p =
parser(test::Assemble(Preamble() + "%100 = OpTypeBool" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(100); auto* type = p->ConvertType(100);
@ -89,7 +122,8 @@ TEST_F(SpvParserTest, ConvertType_Bool) {
} }
TEST_F(SpvParserTest, ConvertType_I32) { TEST_F(SpvParserTest, ConvertType_I32) {
auto p = parser(test::Assemble("%2 = OpTypeInt 32 1")); auto p =
parser(test::Assemble(Preamble() + "%2 = OpTypeInt 32 1" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(2); auto* type = p->ConvertType(2);
@ -98,7 +132,8 @@ TEST_F(SpvParserTest, ConvertType_I32) {
} }
TEST_F(SpvParserTest, ConvertType_U32) { TEST_F(SpvParserTest, ConvertType_U32) {
auto p = parser(test::Assemble("%3 = OpTypeInt 32 0")); auto p =
parser(test::Assemble(Preamble() + "%3 = OpTypeInt 32 0" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(3); auto* type = p->ConvertType(3);
@ -107,7 +142,8 @@ TEST_F(SpvParserTest, ConvertType_U32) {
} }
TEST_F(SpvParserTest, ConvertType_F32) { TEST_F(SpvParserTest, ConvertType_F32) {
auto p = parser(test::Assemble("%4 = OpTypeFloat 32")); auto p =
parser(test::Assemble(Preamble() + "%4 = OpTypeFloat 32" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(4); auto* type = p->ConvertType(4);
@ -116,7 +152,8 @@ TEST_F(SpvParserTest, ConvertType_F32) {
} }
TEST_F(SpvParserTest, ConvertType_BadIntWidth) { TEST_F(SpvParserTest, ConvertType_BadIntWidth) {
auto p = parser(test::Assemble("%5 = OpTypeInt 17 1")); auto p =
parser(test::Assemble(Preamble() + "%5 = OpTypeInt 17 1" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(5); auto* type = p->ConvertType(5);
@ -125,7 +162,8 @@ TEST_F(SpvParserTest, ConvertType_BadIntWidth) {
} }
TEST_F(SpvParserTest, ConvertType_BadFloatWidth) { TEST_F(SpvParserTest, ConvertType_BadFloatWidth) {
auto p = parser(test::Assemble("%6 = OpTypeFloat 19")); auto p =
parser(test::Assemble(Preamble() + "%6 = OpTypeFloat 19" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(6); auto* type = p->ConvertType(6);
@ -134,10 +172,10 @@ TEST_F(SpvParserTest, ConvertType_BadFloatWidth) {
} }
TEST_F(SpvParserTest, DISABLED_ConvertType_InvalidVectorElement) { TEST_F(SpvParserTest, DISABLED_ConvertType_InvalidVectorElement) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%5 = OpTypePipe ReadOnly %5 = OpTypePipe ReadOnly
%20 = OpTypeVector %5 2 %20 = OpTypeVector %5 2
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(20); auto* type = p->ConvertType(20);
@ -146,12 +184,12 @@ TEST_F(SpvParserTest, DISABLED_ConvertType_InvalidVectorElement) {
} }
TEST_F(SpvParserTest, ConvertType_VecOverF32) { TEST_F(SpvParserTest, ConvertType_VecOverF32) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%float = OpTypeFloat 32 %float = OpTypeFloat 32
%20 = OpTypeVector %float 2 %20 = OpTypeVector %float 2
%30 = OpTypeVector %float 3 %30 = OpTypeVector %float 3
%40 = OpTypeVector %float 4 %40 = OpTypeVector %float 4
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* v2xf32 = p->ConvertType(20); auto* v2xf32 = p->ConvertType(20);
@ -173,12 +211,12 @@ TEST_F(SpvParserTest, ConvertType_VecOverF32) {
} }
TEST_F(SpvParserTest, ConvertType_VecOverI32) { TEST_F(SpvParserTest, ConvertType_VecOverI32) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%int = OpTypeInt 32 1 %int = OpTypeInt 32 1
%20 = OpTypeVector %int 2 %20 = OpTypeVector %int 2
%30 = OpTypeVector %int 3 %30 = OpTypeVector %int 3
%40 = OpTypeVector %int 4 %40 = OpTypeVector %int 4
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* v2xi32 = p->ConvertType(20); auto* v2xi32 = p->ConvertType(20);
@ -200,12 +238,12 @@ TEST_F(SpvParserTest, ConvertType_VecOverI32) {
} }
TEST_F(SpvParserTest, ConvertType_VecOverU32) { TEST_F(SpvParserTest, ConvertType_VecOverU32) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%uint = OpTypeInt 32 0 %uint = OpTypeInt 32 0
%20 = OpTypeVector %uint 2 %20 = OpTypeVector %uint 2
%30 = OpTypeVector %uint 3 %30 = OpTypeVector %uint 3
%40 = OpTypeVector %uint 4 %40 = OpTypeVector %uint 4
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* v2xu32 = p->ConvertType(20); auto* v2xu32 = p->ConvertType(20);
@ -227,11 +265,11 @@ TEST_F(SpvParserTest, ConvertType_VecOverU32) {
} }
TEST_F(SpvParserTest, DISABLED_ConvertType_InvalidMatrixElement) { TEST_F(SpvParserTest, DISABLED_ConvertType_InvalidMatrixElement) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%5 = OpTypePipe ReadOnly %5 = OpTypePipe ReadOnly
%10 = OpTypeVector %5 2 %10 = OpTypeVector %5 2
%20 = OpTypeMatrix %10 2 %20 = OpTypeMatrix %10 2
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(20); auto* type = p->ConvertType(20);
@ -241,7 +279,7 @@ TEST_F(SpvParserTest, DISABLED_ConvertType_InvalidMatrixElement) {
TEST_F(SpvParserTest, ConvertType_MatrixOverF32) { TEST_F(SpvParserTest, ConvertType_MatrixOverF32) {
// Matrices are only defined over floats. // Matrices are only defined over floats.
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%float = OpTypeFloat 32 %float = OpTypeFloat 32
%v2 = OpTypeVector %float 2 %v2 = OpTypeVector %float 2
%v3 = OpTypeVector %float 3 %v3 = OpTypeVector %float 3
@ -257,7 +295,7 @@ TEST_F(SpvParserTest, ConvertType_MatrixOverF32) {
%42 = OpTypeMatrix %v4 2 %42 = OpTypeMatrix %v4 2
%43 = OpTypeMatrix %v4 3 %43 = OpTypeMatrix %v4 3
%44 = OpTypeMatrix %v4 4 %44 = OpTypeMatrix %v4 4
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* m22 = p->ConvertType(22); auto* m22 = p->ConvertType(22);
@ -318,10 +356,10 @@ TEST_F(SpvParserTest, ConvertType_MatrixOverF32) {
} }
TEST_F(SpvParserTest, ConvertType_RuntimeArray) { TEST_F(SpvParserTest, ConvertType_RuntimeArray) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%uint = OpTypeInt 32 0 %uint = OpTypeInt 32 0
%10 = OpTypeRuntimeArray %uint %10 = OpTypeRuntimeArray %uint
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(10); auto* type = p->ConvertType(10);
@ -338,11 +376,11 @@ TEST_F(SpvParserTest, ConvertType_RuntimeArray) {
} }
TEST_F(SpvParserTest, ConvertType_RuntimeArray_InvalidDecoration) { TEST_F(SpvParserTest, ConvertType_RuntimeArray_InvalidDecoration) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
OpDecorate %10 Block OpDecorate %10 Block
%uint = OpTypeInt 32 0 %uint = OpTypeInt 32 0
%10 = OpTypeRuntimeArray %uint %10 = OpTypeRuntimeArray %uint
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(10); auto* type = p->ConvertType(10);
EXPECT_EQ(type, nullptr); EXPECT_EQ(type, nullptr);
@ -352,11 +390,11 @@ TEST_F(SpvParserTest, ConvertType_RuntimeArray_InvalidDecoration) {
} }
TEST_F(SpvParserTest, ConvertType_RuntimeArray_ArrayStride_Valid) { TEST_F(SpvParserTest, ConvertType_RuntimeArray_ArrayStride_Valid) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
OpDecorate %10 ArrayStride 64 OpDecorate %10 ArrayStride 64
%uint = OpTypeInt 32 0 %uint = OpTypeInt 32 0
%10 = OpTypeRuntimeArray %uint %10 = OpTypeRuntimeArray %uint
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(10); auto* type = p->ConvertType(10);
ASSERT_NE(type, nullptr); ASSERT_NE(type, nullptr);
@ -367,11 +405,11 @@ TEST_F(SpvParserTest, ConvertType_RuntimeArray_ArrayStride_Valid) {
} }
TEST_F(SpvParserTest, ConvertType_RuntimeArray_ArrayStride_ZeroIsError) { TEST_F(SpvParserTest, ConvertType_RuntimeArray_ArrayStride_ZeroIsError) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
OpDecorate %10 ArrayStride 0 OpDecorate %10 ArrayStride 0
%uint = OpTypeInt 32 0 %uint = OpTypeInt 32 0
%10 = OpTypeRuntimeArray %uint %10 = OpTypeRuntimeArray %uint
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(10); auto* type = p->ConvertType(10);
EXPECT_EQ(type, nullptr); EXPECT_EQ(type, nullptr);
@ -381,12 +419,12 @@ TEST_F(SpvParserTest, ConvertType_RuntimeArray_ArrayStride_ZeroIsError) {
TEST_F(SpvParserTest, TEST_F(SpvParserTest,
ConvertType_RuntimeArray_ArrayStride_SpecifiedTwiceIsError) { ConvertType_RuntimeArray_ArrayStride_SpecifiedTwiceIsError) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
OpDecorate %10 ArrayStride 64 OpDecorate %10 ArrayStride 64
OpDecorate %10 ArrayStride 64 OpDecorate %10 ArrayStride 64
%uint = OpTypeInt 32 0 %uint = OpTypeInt 32 0
%10 = OpTypeRuntimeArray %uint %10 = OpTypeRuntimeArray %uint
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(10); auto* type = p->ConvertType(10);
EXPECT_EQ(type, nullptr); EXPECT_EQ(type, nullptr);
@ -395,11 +433,11 @@ TEST_F(SpvParserTest,
} }
TEST_F(SpvParserTest, ConvertType_Array) { TEST_F(SpvParserTest, ConvertType_Array) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%uint = OpTypeInt 32 0 %uint = OpTypeInt 32 0
%uint_42 = OpConstant %uint 42 %uint_42 = OpConstant %uint 42
%10 = OpTypeArray %uint %uint_42 %10 = OpTypeArray %uint %uint_42
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(10); auto* type = p->ConvertType(10);
@ -416,12 +454,12 @@ TEST_F(SpvParserTest, ConvertType_Array) {
} }
TEST_F(SpvParserTest, ConvertType_ArrayBadLengthIsSpecConstantValue) { TEST_F(SpvParserTest, ConvertType_ArrayBadLengthIsSpecConstantValue) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
OpDecorate %uint_42 SpecId 12 OpDecorate %uint_42 SpecId 12
%uint = OpTypeInt 32 0 %uint = OpTypeInt 32 0
%uint_42 = OpSpecConstant %uint 42 %uint_42 = OpSpecConstant %uint 42
%10 = OpTypeArray %uint %uint_42 %10 = OpTypeArray %uint %uint_42
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(10); auto* type = p->ConvertType(10);
@ -431,12 +469,12 @@ TEST_F(SpvParserTest, ConvertType_ArrayBadLengthIsSpecConstantValue) {
} }
TEST_F(SpvParserTest, ConvertType_ArrayBadLengthIsSpecConstantExpr) { TEST_F(SpvParserTest, ConvertType_ArrayBadLengthIsSpecConstantExpr) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%uint = OpTypeInt 32 0 %uint = OpTypeInt 32 0
%uint_42 = OpConstant %uint 42 %uint_42 = OpConstant %uint 42
%sum = OpSpecConstantOp %uint IAdd %uint_42 %uint_42 %sum = OpSpecConstantOp %uint IAdd %uint_42 %uint_42
%10 = OpTypeArray %uint %sum %10 = OpTypeArray %uint %sum
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(10); auto* type = p->ConvertType(10);
@ -450,11 +488,11 @@ TEST_F(SpvParserTest, ConvertType_ArrayBadLengthIsSpecConstantExpr) {
// optimizer representation doesn't handle it and asserts out instead. // optimizer representation doesn't handle it and asserts out instead.
TEST_F(SpvParserTest, ConvertType_ArrayBadTooBig) { TEST_F(SpvParserTest, ConvertType_ArrayBadTooBig) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%uint64 = OpTypeInt 64 0 %uint64 = OpTypeInt 64 0
%uint64_big = OpConstant %uint64 5000000000 %uint64_big = OpConstant %uint64 5000000000
%10 = OpTypeArray %uint64 %uint64_big %10 = OpTypeArray %uint64 %uint64_big
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(10); auto* type = p->ConvertType(10);
@ -465,12 +503,12 @@ TEST_F(SpvParserTest, ConvertType_ArrayBadTooBig) {
} }
TEST_F(SpvParserTest, ConvertType_Array_InvalidDecoration) { TEST_F(SpvParserTest, ConvertType_Array_InvalidDecoration) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
OpDecorate %10 Block OpDecorate %10 Block
%uint = OpTypeInt 32 0 %uint = OpTypeInt 32 0
%uint_5 = OpConstant %uint 5 %uint_5 = OpConstant %uint 5
%10 = OpTypeArray %uint %uint_5 %10 = OpTypeArray %uint %uint_5
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(10); auto* type = p->ConvertType(10);
EXPECT_EQ(type, nullptr); EXPECT_EQ(type, nullptr);
@ -480,12 +518,12 @@ TEST_F(SpvParserTest, ConvertType_Array_InvalidDecoration) {
} }
TEST_F(SpvParserTest, ConvertType_ArrayStride_Valid) { TEST_F(SpvParserTest, ConvertType_ArrayStride_Valid) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
OpDecorate %10 ArrayStride 8 OpDecorate %10 ArrayStride 8
%uint = OpTypeInt 32 0 %uint = OpTypeInt 32 0
%uint_5 = OpConstant %uint 5 %uint_5 = OpConstant %uint 5
%10 = OpTypeArray %uint %uint_5 %10 = OpTypeArray %uint %uint_5
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(10); auto* type = p->ConvertType(10);
@ -498,12 +536,12 @@ TEST_F(SpvParserTest, ConvertType_ArrayStride_Valid) {
} }
TEST_F(SpvParserTest, ConvertType_ArrayStride_ZeroIsError) { TEST_F(SpvParserTest, ConvertType_ArrayStride_ZeroIsError) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
OpDecorate %10 ArrayStride 0 OpDecorate %10 ArrayStride 0
%uint = OpTypeInt 32 0 %uint = OpTypeInt 32 0
%uint_5 = OpConstant %uint 5 %uint_5 = OpConstant %uint 5
%10 = OpTypeArray %uint %uint_5 %10 = OpTypeArray %uint %uint_5
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(10); auto* type = p->ConvertType(10);
@ -513,13 +551,13 @@ TEST_F(SpvParserTest, ConvertType_ArrayStride_ZeroIsError) {
} }
TEST_F(SpvParserTest, ConvertType_ArrayStride_SpecifiedTwiceIsError) { TEST_F(SpvParserTest, ConvertType_ArrayStride_SpecifiedTwiceIsError) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
OpDecorate %10 ArrayStride 4 OpDecorate %10 ArrayStride 4
OpDecorate %10 ArrayStride 4 OpDecorate %10 ArrayStride 4
%uint = OpTypeInt 32 0 %uint = OpTypeInt 32 0
%uint_5 = OpConstant %uint 5 %uint_5 = OpConstant %uint 5
%10 = OpTypeArray %uint %uint_5 %10 = OpTypeArray %uint %uint_5
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(10); auto* type = p->ConvertType(10);
@ -529,11 +567,11 @@ TEST_F(SpvParserTest, ConvertType_ArrayStride_SpecifiedTwiceIsError) {
} }
TEST_F(SpvParserTest, ConvertType_StructTwoMembers) { TEST_F(SpvParserTest, ConvertType_StructTwoMembers) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%uint = OpTypeInt 32 0 %uint = OpTypeInt 32 0
%float = OpTypeFloat 32 %float = OpTypeFloat 32
%10 = OpTypeStruct %uint %float %10 = OpTypeStruct %uint %float
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
EXPECT_TRUE(p->RegisterUserAndStructMemberNames()); EXPECT_TRUE(p->RegisterUserAndStructMemberNames());
@ -547,11 +585,11 @@ TEST_F(SpvParserTest, ConvertType_StructTwoMembers) {
} }
TEST_F(SpvParserTest, ConvertType_StructWithBlockDecoration) { TEST_F(SpvParserTest, ConvertType_StructWithBlockDecoration) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
OpDecorate %10 Block OpDecorate %10 Block
%uint = OpTypeInt 32 0 %uint = OpTypeInt 32 0
%10 = OpTypeStruct %uint %10 = OpTypeStruct %uint
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
EXPECT_TRUE(p->RegisterUserAndStructMemberNames()); EXPECT_TRUE(p->RegisterUserAndStructMemberNames());
@ -565,7 +603,7 @@ TEST_F(SpvParserTest, ConvertType_StructWithBlockDecoration) {
} }
TEST_F(SpvParserTest, ConvertType_StructWithMemberDecorations) { TEST_F(SpvParserTest, ConvertType_StructWithMemberDecorations) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
OpMemberDecorate %10 0 Offset 0 OpMemberDecorate %10 0 Offset 0
OpMemberDecorate %10 1 Offset 8 OpMemberDecorate %10 1 Offset 8
OpMemberDecorate %10 2 Offset 16 OpMemberDecorate %10 2 Offset 16
@ -573,7 +611,7 @@ TEST_F(SpvParserTest, ConvertType_StructWithMemberDecorations) {
%vec = OpTypeVector %float 2 %vec = OpTypeVector %float 2
%mat = OpTypeMatrix %vec 2 %mat = OpTypeMatrix %vec 2
%10 = OpTypeStruct %float %vec %mat %10 = OpTypeStruct %float %vec %mat
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
EXPECT_TRUE(p->RegisterUserAndStructMemberNames()); EXPECT_TRUE(p->RegisterUserAndStructMemberNames());
@ -593,10 +631,16 @@ TEST_F(SpvParserTest, ConvertType_StructWithMemberDecorations) {
TEST_F(SpvParserTest, ConvertType_InvalidPointeetype) { TEST_F(SpvParserTest, ConvertType_InvalidPointeetype) {
// Disallow pointer-to-function // Disallow pointer-to-function
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%void = OpTypeVoid %void = OpTypeVoid
%42 = OpTypeFunction %void %42 = OpTypeFunction %void
%3 = OpTypePointer Input %42 %3 = OpTypePointer Input %42
%voidfn = OpTypeFunction %void
%main = OpFunction %void None %voidfn
%entry = OpLabel
OpReturn
OpFunctionEnd
)")); )"));
EXPECT_TRUE(p->BuildInternalModule()) << p->error(); EXPECT_TRUE(p->BuildInternalModule()) << p->error();
@ -608,19 +652,19 @@ TEST_F(SpvParserTest, ConvertType_InvalidPointeetype) {
TEST_F(SpvParserTest, DISABLED_ConvertType_InvalidStorageClass) { TEST_F(SpvParserTest, DISABLED_ConvertType_InvalidStorageClass) {
// Disallow invalid storage class // Disallow invalid storage class
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%1 = OpTypeFloat 32 %1 = OpTypeFloat 32
%3 = OpTypePointer !999 %1 ; Special syntax to inject 999 as the storage class %3 = OpTypePointer !999 %1 ; Special syntax to inject 999 as the storage class
)")); )" + MainBody()));
// TODO(dneto): I can't get it past module building. // TODO(dneto): I can't get it past module building.
EXPECT_FALSE(p->BuildInternalModule()) << p->error(); EXPECT_FALSE(p->BuildInternalModule()) << p->error();
} }
TEST_F(SpvParserTest, ConvertType_PointerInput) { TEST_F(SpvParserTest, ConvertType_PointerInput) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%float = OpTypeFloat 32 %float = OpTypeFloat 32
%3 = OpTypePointer Input %float %3 = OpTypePointer Input %float
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(3); auto* type = p->ConvertType(3);
@ -633,10 +677,10 @@ TEST_F(SpvParserTest, ConvertType_PointerInput) {
} }
TEST_F(SpvParserTest, ConvertType_PointerOutput) { TEST_F(SpvParserTest, ConvertType_PointerOutput) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%float = OpTypeFloat 32 %float = OpTypeFloat 32
%3 = OpTypePointer Output %float %3 = OpTypePointer Output %float
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(3); auto* type = p->ConvertType(3);
@ -649,10 +693,10 @@ TEST_F(SpvParserTest, ConvertType_PointerOutput) {
} }
TEST_F(SpvParserTest, ConvertType_PointerUniform) { TEST_F(SpvParserTest, ConvertType_PointerUniform) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%float = OpTypeFloat 32 %float = OpTypeFloat 32
%3 = OpTypePointer Uniform %float %3 = OpTypePointer Uniform %float
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(3); auto* type = p->ConvertType(3);
@ -665,10 +709,10 @@ TEST_F(SpvParserTest, ConvertType_PointerUniform) {
} }
TEST_F(SpvParserTest, ConvertType_PointerWorkgroup) { TEST_F(SpvParserTest, ConvertType_PointerWorkgroup) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%float = OpTypeFloat 32 %float = OpTypeFloat 32
%3 = OpTypePointer Workgroup %float %3 = OpTypePointer Workgroup %float
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(3); auto* type = p->ConvertType(3);
@ -681,10 +725,10 @@ TEST_F(SpvParserTest, ConvertType_PointerWorkgroup) {
} }
TEST_F(SpvParserTest, ConvertType_PointerUniformConstant) { TEST_F(SpvParserTest, ConvertType_PointerUniformConstant) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%float = OpTypeFloat 32 %float = OpTypeFloat 32
%3 = OpTypePointer UniformConstant %float %3 = OpTypePointer UniformConstant %float
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(3); auto* type = p->ConvertType(3);
@ -697,10 +741,10 @@ TEST_F(SpvParserTest, ConvertType_PointerUniformConstant) {
} }
TEST_F(SpvParserTest, ConvertType_PointerStorageBuffer) { TEST_F(SpvParserTest, ConvertType_PointerStorageBuffer) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%float = OpTypeFloat 32 %float = OpTypeFloat 32
%3 = OpTypePointer StorageBuffer %float %3 = OpTypePointer StorageBuffer %float
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(3); auto* type = p->ConvertType(3);
@ -713,10 +757,10 @@ TEST_F(SpvParserTest, ConvertType_PointerStorageBuffer) {
} }
TEST_F(SpvParserTest, ConvertType_PointerImage) { TEST_F(SpvParserTest, ConvertType_PointerImage) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%float = OpTypeFloat 32 %float = OpTypeFloat 32
%3 = OpTypePointer Image %float %3 = OpTypePointer Image %float
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(3); auto* type = p->ConvertType(3);
@ -729,10 +773,10 @@ TEST_F(SpvParserTest, ConvertType_PointerImage) {
} }
TEST_F(SpvParserTest, ConvertType_PointerPrivate) { TEST_F(SpvParserTest, ConvertType_PointerPrivate) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%float = OpTypeFloat 32 %float = OpTypeFloat 32
%3 = OpTypePointer Private %float %3 = OpTypePointer Private %float
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(3); auto* type = p->ConvertType(3);
@ -745,10 +789,10 @@ TEST_F(SpvParserTest, ConvertType_PointerPrivate) {
} }
TEST_F(SpvParserTest, ConvertType_PointerFunction) { TEST_F(SpvParserTest, ConvertType_PointerFunction) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%float = OpTypeFloat 32 %float = OpTypeFloat 32
%3 = OpTypePointer Function %float %3 = OpTypePointer Function %float
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(3); auto* type = p->ConvertType(3);
@ -762,11 +806,11 @@ TEST_F(SpvParserTest, ConvertType_PointerFunction) {
TEST_F(SpvParserTest, ConvertType_PointerToPointer) { TEST_F(SpvParserTest, ConvertType_PointerToPointer) {
// FYI: The reader suports pointer-to-pointer even while WebGPU does not. // FYI: The reader suports pointer-to-pointer even while WebGPU does not.
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%float = OpTypeFloat 32 %float = OpTypeFloat 32
%42 = OpTypePointer Output %float %42 = OpTypePointer Output %float
%3 = OpTypePointer Input %42 %3 = OpTypePointer Input %42
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(3); auto* type = p->ConvertType(3);
@ -788,9 +832,9 @@ TEST_F(SpvParserTest, ConvertType_PointerToPointer) {
TEST_F(SpvParserTest, ConvertType_Sampler_PretendVoid) { TEST_F(SpvParserTest, ConvertType_Sampler_PretendVoid) {
// We fake the type suport for samplers, images, and sampled images. // We fake the type suport for samplers, images, and sampled images.
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%1 = OpTypeSampler %1 = OpTypeSampler
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(1); auto* type = p->ConvertType(1);
@ -800,10 +844,10 @@ TEST_F(SpvParserTest, ConvertType_Sampler_PretendVoid) {
TEST_F(SpvParserTest, ConvertType_Image_PretendVoid) { TEST_F(SpvParserTest, ConvertType_Image_PretendVoid) {
// We fake the type suport for samplers, images, and sampled images. // We fake the type suport for samplers, images, and sampled images.
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%float = OpTypeFloat 32 %float = OpTypeFloat 32
%1 = OpTypeImage %float 2D 0 0 0 1 Unknown %1 = OpTypeImage %float 2D 0 0 0 1 Unknown
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(1); auto* type = p->ConvertType(1);
@ -812,11 +856,11 @@ TEST_F(SpvParserTest, ConvertType_Image_PretendVoid) {
} }
TEST_F(SpvParserTest, ConvertType_SampledImage_PretendVoid) { TEST_F(SpvParserTest, ConvertType_SampledImage_PretendVoid) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(Preamble() + R"(
%float = OpTypeFloat 32 %float = OpTypeFloat 32
%im = OpTypeImage %float 2D 0 0 0 1 Unknown %im = OpTypeImage %float 2D 0 0 0 1 Unknown
%1 = OpTypeSampledImage %im %1 = OpTypeSampledImage %im
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());
auto* type = p->ConvertType(1); auto* type = p->ConvertType(1);

View File

@ -23,6 +23,28 @@ namespace {
using ::testing::HasSubstr; using ::testing::HasSubstr;
std::string Caps() {
return R"(
OpCapability Shader
OpMemoryModel Logical Simple
)";
}
std::string Preamble() {
return Caps() + R"(
OpEntryPoint Vertex %main "x_100"
)";
}
std::string MainBody() {
return R"(
%main = OpFunction %void None %voidfn
%main_entry = OpLabel
OpReturn
OpFunctionEnd
)";
}
/// @returns a SPIR-V assembly segment which assigns debug names /// @returns a SPIR-V assembly segment which assigns debug names
/// to particular IDs. /// to particular IDs.
std::string Names(std::vector<std::string> ids) { std::string Names(std::vector<std::string> ids) {
@ -45,16 +67,22 @@ std::string CommonTypes() {
} }
TEST_F(SpvParserTest, EmitFunctions_NoFunctions) { TEST_F(SpvParserTest, EmitFunctions_NoFunctions) {
auto p = parser(test::Assemble(CommonTypes())); auto p = parser(test::Assemble(
R"(
OpCapability Shader
OpMemoryModel Logical Simple
)" + CommonTypes()));
EXPECT_TRUE(p->BuildAndParseInternalModule()); EXPECT_TRUE(p->BuildAndParseInternalModule());
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
Program program = p->program(); Program program = p->program();
const auto program_ast = program.to_str(false); const auto program_ast = program.to_str(false);
EXPECT_THAT(program_ast, Not(HasSubstr("Function{"))); EXPECT_THAT(program_ast, Not(HasSubstr("Function{")));
p->SkipDumpingPending("Not valid for Vulkan: needs an entry point");
} }
TEST_F(SpvParserTest, EmitFunctions_FunctionWithoutBody) { TEST_F(SpvParserTest, EmitFunctions_FunctionWithoutBody) {
auto p = parser(test::Assemble(Names({"main"}) + CommonTypes() + R"( auto p =
parser(test::Assemble(Preamble() + Names({"main"}) + CommonTypes() + R"(
%main = OpFunction %void None %voidfn %main = OpFunction %void None %voidfn
OpFunctionEnd OpFunctionEnd
)")); )"));
@ -63,11 +91,12 @@ TEST_F(SpvParserTest, EmitFunctions_FunctionWithoutBody) {
Program program = p->program(); Program program = p->program();
const auto program_ast = program.to_str(false); const auto program_ast = program.to_str(false);
EXPECT_THAT(program_ast, Not(HasSubstr("Function{"))); EXPECT_THAT(program_ast, Not(HasSubstr("Function{")));
p->SkipDumpingPending("Missing an entry point body requires Linkage");
} }
TEST_F(SpvParserTest, EmitFunctions_Function_EntryPoint_Vertex) { TEST_F(SpvParserTest, EmitFunctions_Function_EntryPoint_Vertex) {
std::string input = Names({"main"}) + R"(OpEntryPoint Vertex %main "main" std::string input = Caps() + R"(OpEntryPoint Vertex %main "main" )" +
)" + CommonTypes() + R"( Names({"main"}) + CommonTypes() + R"(
%main = OpFunction %void None %voidfn %main = OpFunction %void None %voidfn
%entry = OpLabel %entry = OpLabel
OpReturn OpReturn
@ -87,12 +116,11 @@ OpFunctionEnd)";
} }
TEST_F(SpvParserTest, EmitFunctions_Function_EntryPoint_Fragment) { TEST_F(SpvParserTest, EmitFunctions_Function_EntryPoint_Fragment) {
std::string input = Names({"main"}) + R"(OpEntryPoint Fragment %main "main" std::string input = Caps() + R"(
)" + CommonTypes() + R"( OpEntryPoint Fragment %main "main"
%main = OpFunction %void None %voidfn OpExecutionMode %main OriginUpperLeft
%entry = OpLabel )" + Names({"main"}) + CommonTypes() +
OpReturn MainBody();
OpFunctionEnd)";
auto p = parser(test::Assemble(input)); auto p = parser(test::Assemble(input));
ASSERT_TRUE(p->BuildAndParseInternalModule()); ASSERT_TRUE(p->BuildAndParseInternalModule());
@ -108,12 +136,11 @@ OpFunctionEnd)";
} }
TEST_F(SpvParserTest, EmitFunctions_Function_EntryPoint_GLCompute) { TEST_F(SpvParserTest, EmitFunctions_Function_EntryPoint_GLCompute) {
std::string input = Names({"main"}) + R"(OpEntryPoint GLCompute %main "main" std::string input = Caps() + R"(
)" + CommonTypes() + R"( OpEntryPoint GLCompute %main "main"
%main = OpFunction %void None %voidfn OpExecutionMode %main LocalSize 1 1 1
%entry = OpLabel )" + Names({"main"}) + CommonTypes() +
OpReturn MainBody();
OpFunctionEnd)";
auto p = parser(test::Assemble(input)); auto p = parser(test::Assemble(input));
ASSERT_TRUE(p->BuildAndParseInternalModule()); ASSERT_TRUE(p->BuildAndParseInternalModule());
@ -129,14 +156,12 @@ OpFunctionEnd)";
} }
TEST_F(SpvParserTest, EmitFunctions_Function_EntryPoint_MultipleEntryPoints) { TEST_F(SpvParserTest, EmitFunctions_Function_EntryPoint_MultipleEntryPoints) {
std::string input = Names({"main"}) + std::string input = Caps() +
R"(OpEntryPoint GLCompute %main "comp_main" R"(
OpEntryPoint Fragment %main "frag_main" OpEntryPoint Vertex %main "first_shader"
)" + CommonTypes() + R"( OpEntryPoint Vertex %main "second_shader"
%main = OpFunction %void None %voidfn )" + Names({"main"}) + CommonTypes() +
%entry = OpLabel MainBody();
OpReturn
OpFunctionEnd)";
auto p = parser(test::Assemble(input)); auto p = parser(test::Assemble(input));
ASSERT_TRUE(p->BuildAndParseInternalModule()); ASSERT_TRUE(p->BuildAndParseInternalModule());
@ -144,32 +169,33 @@ OpFunctionEnd)";
Program program = p->program(); Program program = p->program();
const auto program_ast = program.to_str(false); const auto program_ast = program.to_str(false);
EXPECT_THAT(program_ast, HasSubstr(R"( EXPECT_THAT(program_ast, HasSubstr(R"(
Function )" + program.Symbols().Get("frag_main").to_str() + Function )" + program.Symbols().Get("first_shader").to_str() +
R"( -> __void R"( -> __void
StageDecoration{fragment} StageDecoration{vertex}
() ()
{)")); {)"));
EXPECT_THAT(program_ast, HasSubstr(R"( EXPECT_THAT(program_ast, HasSubstr(R"(
Function )" + program.Symbols().Get("comp_main").to_str() + Function )" + program.Symbols().Get("second_shader").to_str() +
R"( -> __void R"( -> __void
StageDecoration{compute} StageDecoration{vertex}
() ()
{)")); {)"));
} }
TEST_F(SpvParserTest, EmitFunctions_VoidFunctionWithoutParams) { TEST_F(SpvParserTest, EmitFunctions_VoidFunctionWithoutParams) {
auto p = parser(test::Assemble(Names({"main"}) + CommonTypes() + R"( auto p = parser(test::Assemble(Preamble() + Names({"another_function"}) +
%main = OpFunction %void None %voidfn CommonTypes() + R"(
%another_function = OpFunction %void None %voidfn
%entry = OpLabel %entry = OpLabel
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildAndParseInternalModule()); EXPECT_TRUE(p->BuildAndParseInternalModule());
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
Program program = p->program(); Program program = p->program();
const auto program_ast = program.to_str(false); const auto program_ast = program.to_str(false);
EXPECT_THAT(program_ast, HasSubstr(R"( EXPECT_THAT(program_ast, HasSubstr(R"(
Function )" + program.Symbols().Get("main").to_str() + Function )" + program.Symbols().Get("another_function").to_str() +
R"( -> __void R"( -> __void
() ()
{)")); {)"));
@ -177,6 +203,7 @@ TEST_F(SpvParserTest, EmitFunctions_VoidFunctionWithoutParams) {
TEST_F(SpvParserTest, EmitFunctions_CalleePrecedesCaller) { TEST_F(SpvParserTest, EmitFunctions_CalleePrecedesCaller) {
auto p = parser(test::Assemble( auto p = parser(test::Assemble(
Preamble() +
Names({"root", "branch", "leaf", "leaf_result", "branch_result"}) + Names({"root", "branch", "leaf", "leaf_result", "branch_result"}) +
CommonTypes() + R"( CommonTypes() + R"(
%uintfn = OpTypeFunction %uint %uintfn = OpTypeFunction %uint
@ -198,7 +225,7 @@ TEST_F(SpvParserTest, EmitFunctions_CalleePrecedesCaller) {
%leaf_entry = OpLabel %leaf_entry = OpLabel
OpReturnValue %uint_0 OpReturnValue %uint_0
OpFunctionEnd OpFunctionEnd
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildAndParseInternalModule()); EXPECT_TRUE(p->BuildAndParseInternalModule());
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
Program program = p->program(); Program program = p->program();
@ -257,18 +284,25 @@ TEST_F(SpvParserTest, EmitFunctions_CalleePrecedesCaller) {
} }
Return{} Return{}
} }
Function x_100 -> __void
StageDecoration{vertex}
()
{
Return{}
}
})")) << program_ast; })")) << program_ast;
} }
TEST_F(SpvParserTest, EmitFunctions_NonVoidResultType) { TEST_F(SpvParserTest, EmitFunctions_NonVoidResultType) {
auto p = parser(test::Assemble(Names({"ret_float"}) + CommonTypes() + R"( auto p = parser(
test::Assemble(Preamble() + Names({"ret_float"}) + CommonTypes() + R"(
%fn_ret_float = OpTypeFunction %float %fn_ret_float = OpTypeFunction %float
%ret_float = OpFunction %float None %fn_ret_float %ret_float = OpFunction %float None %fn_ret_float
%ret_float_entry = OpLabel %ret_float_entry = OpLabel
OpReturnValue %float_0 OpReturnValue %float_0
OpFunctionEnd OpFunctionEnd
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildAndParseInternalModule()); EXPECT_TRUE(p->BuildAndParseInternalModule());
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
Program program = p->program(); Program program = p->program();
@ -287,9 +321,9 @@ TEST_F(SpvParserTest, EmitFunctions_NonVoidResultType) {
} }
TEST_F(SpvParserTest, EmitFunctions_MixedParamTypes) { TEST_F(SpvParserTest, EmitFunctions_MixedParamTypes) {
auto p = parser(test::Assemble(Names({"mixed_params", "a", "b", "c"}) + auto p = parser(test::Assemble(
CommonTypes() + R"( Preamble() + Names({"mixed_params", "a", "b", "c"}) + CommonTypes() + R"(
%fn_mixed_params = OpTypeFunction %float %uint %float %int %fn_mixed_params = OpTypeFunction %void %uint %float %int
%mixed_params = OpFunction %void None %fn_mixed_params %mixed_params = OpFunction %void None %fn_mixed_params
%a = OpFunctionParameter %uint %a = OpFunctionParameter %uint
@ -298,7 +332,7 @@ TEST_F(SpvParserTest, EmitFunctions_MixedParamTypes) {
%mixed_entry = OpLabel %mixed_entry = OpLabel
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildAndParseInternalModule()); EXPECT_TRUE(p->BuildAndParseInternalModule());
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
Program program = p->program(); Program program = p->program();
@ -331,8 +365,9 @@ TEST_F(SpvParserTest, EmitFunctions_MixedParamTypes) {
} }
TEST_F(SpvParserTest, EmitFunctions_GenerateParamNames) { TEST_F(SpvParserTest, EmitFunctions_GenerateParamNames) {
auto p = parser(test::Assemble(Names({"mixed_params"}) + CommonTypes() + R"( auto p = parser(
%fn_mixed_params = OpTypeFunction %float %uint %float %int test::Assemble(Preamble() + Names({"mixed_params"}) + CommonTypes() + R"(
%fn_mixed_params = OpTypeFunction %void %uint %float %int
%mixed_params = OpFunction %void None %fn_mixed_params %mixed_params = OpFunction %void None %fn_mixed_params
%14 = OpFunctionParameter %uint %14 = OpFunctionParameter %uint
@ -341,7 +376,7 @@ TEST_F(SpvParserTest, EmitFunctions_GenerateParamNames) {
%mixed_entry = OpLabel %mixed_entry = OpLabel
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd
)")); )" + MainBody()));
EXPECT_TRUE(p->BuildAndParseInternalModule()); EXPECT_TRUE(p->BuildAndParseInternalModule());
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
Program program = p->program(); Program program = p->program();

View File

@ -26,12 +26,15 @@ using ::testing::UnorderedElementsAre;
using SpvParserGetDecorationsTest = SpvParserTest; using SpvParserGetDecorationsTest = SpvParserTest;
const char* kSkipReason = "This example is deliberately a SPIR-V fragment";
TEST_F(SpvParserGetDecorationsTest, GetDecorationsFor_NotAnId) { TEST_F(SpvParserGetDecorationsTest, GetDecorationsFor_NotAnId) {
auto p = parser(test::Assemble("")); auto p = parser(test::Assemble(""));
EXPECT_TRUE(p->BuildAndParseInternalModule()); EXPECT_TRUE(p->BuildAndParseInternalModule());
auto decorations = p->GetDecorationsFor(42); auto decorations = p->GetDecorationsFor(42);
EXPECT_TRUE(decorations.empty()); EXPECT_TRUE(decorations.empty());
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
p->SkipDumpingPending(kSkipReason);
} }
TEST_F(SpvParserGetDecorationsTest, GetDecorationsFor_NoDecorations) { TEST_F(SpvParserGetDecorationsTest, GetDecorationsFor_NoDecorations) {
@ -40,6 +43,7 @@ TEST_F(SpvParserGetDecorationsTest, GetDecorationsFor_NoDecorations) {
auto decorations = p->GetDecorationsFor(1); auto decorations = p->GetDecorationsFor(1);
EXPECT_TRUE(decorations.empty()); EXPECT_TRUE(decorations.empty());
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
p->SkipDumpingPending(kSkipReason);
} }
TEST_F(SpvParserGetDecorationsTest, GetDecorationsFor_OneDecoration) { TEST_F(SpvParserGetDecorationsTest, GetDecorationsFor_OneDecoration) {
@ -53,6 +57,7 @@ TEST_F(SpvParserGetDecorationsTest, GetDecorationsFor_OneDecoration) {
EXPECT_THAT(decorations, EXPECT_THAT(decorations,
UnorderedElementsAre(Decoration{SpvDecorationBlock})); UnorderedElementsAre(Decoration{SpvDecorationBlock}));
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
p->SkipDumpingPending(kSkipReason);
} }
TEST_F(SpvParserGetDecorationsTest, GetDecorationsFor_MultiDecoration) { TEST_F(SpvParserGetDecorationsTest, GetDecorationsFor_MultiDecoration) {
@ -68,6 +73,7 @@ TEST_F(SpvParserGetDecorationsTest, GetDecorationsFor_MultiDecoration) {
UnorderedElementsAre(Decoration{SpvDecorationRelaxedPrecision}, UnorderedElementsAre(Decoration{SpvDecorationRelaxedPrecision},
Decoration{SpvDecorationLocation, 7})); Decoration{SpvDecorationLocation, 7}));
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
p->SkipDumpingPending(kSkipReason);
} }
TEST_F(SpvParserGetDecorationsTest, GetDecorationsForMember_NotAnId) { TEST_F(SpvParserGetDecorationsTest, GetDecorationsForMember_NotAnId) {
@ -76,6 +82,7 @@ TEST_F(SpvParserGetDecorationsTest, GetDecorationsForMember_NotAnId) {
auto decorations = p->GetDecorationsForMember(42, 9); auto decorations = p->GetDecorationsForMember(42, 9);
EXPECT_TRUE(decorations.empty()); EXPECT_TRUE(decorations.empty());
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
p->SkipDumpingPending(kSkipReason);
} }
TEST_F(SpvParserGetDecorationsTest, GetDecorationsForMember_NotAStruct) { TEST_F(SpvParserGetDecorationsTest, GetDecorationsForMember_NotAStruct) {
@ -84,6 +91,7 @@ TEST_F(SpvParserGetDecorationsTest, GetDecorationsForMember_NotAStruct) {
auto decorations = p->GetDecorationsFor(1); auto decorations = p->GetDecorationsFor(1);
EXPECT_TRUE(decorations.empty()); EXPECT_TRUE(decorations.empty());
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
p->SkipDumpingPending(kSkipReason);
} }
TEST_F(SpvParserGetDecorationsTest, TEST_F(SpvParserGetDecorationsTest,
@ -96,6 +104,7 @@ TEST_F(SpvParserGetDecorationsTest,
auto decorations = p->GetDecorationsForMember(10, 0); auto decorations = p->GetDecorationsForMember(10, 0);
EXPECT_TRUE(decorations.empty()); EXPECT_TRUE(decorations.empty());
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
p->SkipDumpingPending(kSkipReason);
} }
TEST_F(SpvParserGetDecorationsTest, GetDecorationsForMember_RelaxedPrecision) { TEST_F(SpvParserGetDecorationsTest, GetDecorationsForMember_RelaxedPrecision) {

View File

@ -1701,6 +1701,7 @@ TEST_F(SpvModuleScopeVarParserTest,
TEST_F(SpvModuleScopeVarParserTest, DescriptorGroupDecoration_Valid) { TEST_F(SpvModuleScopeVarParserTest, DescriptorGroupDecoration_Valid) {
auto p = parser(test::Assemble(Preamble() + FragMain() + CommonLayout() + R"( auto p = parser(test::Assemble(Preamble() + FragMain() + CommonLayout() + R"(
OpDecorate %1 DescriptorSet 3 OpDecorate %1 DescriptorSet 3
OpDecorate %1 Binding 9 ; Required to pass WGSL validation
OpDecorate %strct Block OpDecorate %strct Block
)" + CommonTypes() + R"( )" + CommonTypes() + R"(
%ptr_sb_strct = OpTypePointer StorageBuffer %strct %ptr_sb_strct = OpTypePointer StorageBuffer %strct
@ -1713,6 +1714,7 @@ TEST_F(SpvModuleScopeVarParserTest, DescriptorGroupDecoration_Valid) {
Variable{ Variable{
Decorations{ Decorations{
GroupDecoration{3} GroupDecoration{3}
BindingDecoration{9}
} }
x_1 x_1
storage storage
@ -1753,6 +1755,7 @@ TEST_F(SpvModuleScopeVarParserTest,
TEST_F(SpvModuleScopeVarParserTest, BindingDecoration_Valid) { TEST_F(SpvModuleScopeVarParserTest, BindingDecoration_Valid) {
auto p = parser(test::Assemble(Preamble() + FragMain() + R"( auto p = parser(test::Assemble(Preamble() + FragMain() + R"(
OpDecorate %1 DescriptorSet 0 ; WGSL validation requires this already
OpDecorate %1 Binding 3 OpDecorate %1 Binding 3
OpDecorate %strct Block OpDecorate %strct Block
)" + CommonLayout() + CommonTypes() + )" + CommonLayout() + CommonTypes() +
@ -1766,6 +1769,7 @@ TEST_F(SpvModuleScopeVarParserTest, BindingDecoration_Valid) {
EXPECT_THAT(module_str, HasSubstr(R"( EXPECT_THAT(module_str, HasSubstr(R"(
Variable{ Variable{
Decorations{ Decorations{
GroupDecoration{0}
BindingDecoration{3} BindingDecoration{3}
} }
x_1 x_1
@ -1807,10 +1811,13 @@ TEST_F(SpvModuleScopeVarParserTest, BindingDecoration_TwoOperandsWontAssemble) {
TEST_F(SpvModuleScopeVarParserTest, TEST_F(SpvModuleScopeVarParserTest,
StructMember_NonReadableDecoration_Dropped) { StructMember_NonReadableDecoration_Dropped) {
auto p = parser(test::Assemble(Preamble() + FragMain() + CommonLayout() + R"( auto p = parser(test::Assemble(Preamble() + FragMain() + R"(
OpDecorate %1 DescriptorSet 0
OpDecorate %1 Binding 0
OpDecorate %strct Block OpDecorate %strct Block
OpMemberDecorate %strct 0 NonReadable OpMemberDecorate %strct 0 NonReadable
)" + CommonTypes() + R"( )" + CommonLayout() + CommonTypes() +
R"(
%ptr_sb_strct = OpTypePointer StorageBuffer %strct %ptr_sb_strct = OpTypePointer StorageBuffer %strct
%1 = OpVariable %ptr_sb_strct StorageBuffer %1 = OpVariable %ptr_sb_strct StorageBuffer
)" + MainBody())); )" + MainBody()));
@ -1826,6 +1833,10 @@ TEST_F(SpvModuleScopeVarParserTest,
StructMember{[[ offset 8 ]] field2: __type_name_Arr} StructMember{[[ offset 8 ]] field2: __type_name_Arr}
} }
Variable{ Variable{
Decorations{
GroupDecoration{0}
BindingDecoration{0}
}
x_1 x_1
storage storage
read_write read_write
@ -1837,6 +1848,8 @@ TEST_F(SpvModuleScopeVarParserTest,
TEST_F(SpvModuleScopeVarParserTest, ColMajorDecoration_Dropped) { TEST_F(SpvModuleScopeVarParserTest, ColMajorDecoration_Dropped) {
auto p = parser(test::Assemble(Preamble() + FragMain() + R"( auto p = parser(test::Assemble(Preamble() + FragMain() + R"(
OpName %myvar "myvar" OpName %myvar "myvar"
OpDecorate %myvar DescriptorSet 0
OpDecorate %myvar Binding 0
OpDecorate %s Block OpDecorate %s Block
OpMemberDecorate %s 0 ColMajor OpMemberDecorate %s 0 ColMajor
OpMemberDecorate %s 0 Offset 0 OpMemberDecorate %s 0 Offset 0
@ -1860,6 +1873,10 @@ TEST_F(SpvModuleScopeVarParserTest, ColMajorDecoration_Dropped) {
StructMember{[[ offset 0 ]] field0: __mat_2_3__f32} StructMember{[[ offset 0 ]] field0: __mat_2_3__f32}
} }
Variable{ Variable{
Decorations{
GroupDecoration{0}
BindingDecoration{0}
}
myvar myvar
storage storage
read_write read_write
@ -1871,6 +1888,8 @@ TEST_F(SpvModuleScopeVarParserTest, ColMajorDecoration_Dropped) {
TEST_F(SpvModuleScopeVarParserTest, MatrixStrideDecoration_Dropped) { TEST_F(SpvModuleScopeVarParserTest, MatrixStrideDecoration_Dropped) {
auto p = parser(test::Assemble(Preamble() + FragMain() + R"( auto p = parser(test::Assemble(Preamble() + FragMain() + R"(
OpName %myvar "myvar" OpName %myvar "myvar"
OpDecorate %myvar DescriptorSet 0
OpDecorate %myvar Binding 0
OpDecorate %s Block OpDecorate %s Block
OpMemberDecorate %s 0 MatrixStride 8 OpMemberDecorate %s 0 MatrixStride 8
OpMemberDecorate %s 0 Offset 0 OpMemberDecorate %s 0 Offset 0
@ -1893,6 +1912,10 @@ TEST_F(SpvModuleScopeVarParserTest, MatrixStrideDecoration_Dropped) {
StructMember{[[ offset 0 ]] field0: __mat_2_3__f32} StructMember{[[ offset 0 ]] field0: __mat_2_3__f32}
} }
Variable{ Variable{
Decorations{
GroupDecoration{0}
BindingDecoration{0}
}
myvar myvar
storage storage
read_write read_write
@ -1928,6 +1951,8 @@ TEST_F(SpvModuleScopeVarParserTest, StorageBuffer_NonWritable_AllMembers) {
// Variable should have access(read) // Variable should have access(read)
auto p = parser(test::Assemble(Preamble() + FragMain() + R"( auto p = parser(test::Assemble(Preamble() + FragMain() + R"(
OpDecorate %s Block OpDecorate %s Block
OpDecorate %1 DescriptorSet 0
OpDecorate %1 Binding 0
OpMemberDecorate %s 0 NonWritable OpMemberDecorate %s 0 NonWritable
OpMemberDecorate %s 1 NonWritable OpMemberDecorate %s 1 NonWritable
OpMemberDecorate %s 0 Offset 0 OpMemberDecorate %s 0 Offset 0
@ -1950,6 +1975,10 @@ TEST_F(SpvModuleScopeVarParserTest, StorageBuffer_NonWritable_AllMembers) {
StructMember{[[ offset 4 ]] field1: __f32} StructMember{[[ offset 4 ]] field1: __f32}
} }
Variable{ Variable{
Decorations{
GroupDecoration{0}
BindingDecoration{0}
}
x_1 x_1
storage storage
read read
@ -1961,6 +1990,8 @@ TEST_F(SpvModuleScopeVarParserTest, StorageBuffer_NonWritable_AllMembers) {
TEST_F(SpvModuleScopeVarParserTest, StorageBuffer_NonWritable_NotAllMembers) { TEST_F(SpvModuleScopeVarParserTest, StorageBuffer_NonWritable_NotAllMembers) {
// Variable should have access(read_write) // Variable should have access(read_write)
auto p = parser(test::Assemble(Preamble() + FragMain() + R"( auto p = parser(test::Assemble(Preamble() + FragMain() + R"(
OpDecorate %1 DescriptorSet 0
OpDecorate %1 Binding 0
OpDecorate %s Block OpDecorate %s Block
OpMemberDecorate %s 0 NonWritable OpMemberDecorate %s 0 NonWritable
OpMemberDecorate %s 0 Offset 0 OpMemberDecorate %s 0 Offset 0
@ -1983,6 +2014,10 @@ TEST_F(SpvModuleScopeVarParserTest, StorageBuffer_NonWritable_NotAllMembers) {
StructMember{[[ offset 4 ]] field1: __f32} StructMember{[[ offset 4 ]] field1: __f32}
} }
Variable{ Variable{
Decorations{
GroupDecoration{0}
BindingDecoration{0}
}
x_1 x_1
storage storage
read_write read_write
@ -1997,6 +2032,8 @@ TEST_F(
// Variable should have access(read_write) // Variable should have access(read_write)
auto p = parser(test::Assemble(Preamble() + FragMain() + R"( auto p = parser(test::Assemble(Preamble() + FragMain() + R"(
OpDecorate %s Block OpDecorate %s Block
OpDecorate %1 DescriptorSet 0
OpDecorate %1 Binding 0
OpMemberDecorate %s 0 NonWritable OpMemberDecorate %s 0 NonWritable
OpMemberDecorate %s 0 NonWritable ; same member. Don't double-count it OpMemberDecorate %s 0 NonWritable ; same member. Don't double-count it
OpMemberDecorate %s 0 Offset 0 OpMemberDecorate %s 0 Offset 0
@ -2019,6 +2056,10 @@ TEST_F(
StructMember{[[ offset 4 ]] field1: __f32} StructMember{[[ offset 4 ]] field1: __f32}
} }
Variable{ Variable{
Decorations{
GroupDecoration{0}
BindingDecoration{0}
}
x_1 x_1
storage storage
read_write read_write