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

View File

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

View File

@ -24,6 +24,14 @@ namespace {
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
/// to particular 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) {
auto p = parser(test::Assemble(CommonTypes() + R"(
auto p = parser(test::Assemble(Preamble() + CommonTypes() + R"(
%100 = OpFunction %void None %voidfn
%entry = OpLabel
OpReturn
@ -68,20 +85,20 @@ TEST_F(SpvParserTest, Emit_VoidFunctionWithoutParams) {
}
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
%100 = OpFunction %float None %fn_ret_float
%200 = OpFunction %float None %fn_ret_float
%entry = OpLabel
OpReturnValue %float_0
OpFunctionEnd
)"));
)" + MainBody()));
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
auto fe = p->function_emitter(100);
auto fe = p->function_emitter(200);
EXPECT_TRUE(fe.Emit());
auto got = p->program().to_str();
std::string expect = R"(Module{
Function x_100 -> __f32
Function x_200 -> __f32
()
{
Return{
@ -92,28 +109,29 @@ TEST_F(SpvParserTest, Emit_NonVoidResultType) {
}
}
)";
EXPECT_EQ(got, expect);
EXPECT_THAT(got, HasSubstr(expect));
}
TEST_F(SpvParserTest, Emit_MixedParamTypes) {
auto p = parser(test::Assemble(Names({"a", "b", "c"}) + CommonTypes() + R"(
%fn_mixed_params = OpTypeFunction %float %uint %float %int
auto p = parser(
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
%b = OpFunctionParameter %float
%c = OpFunctionParameter %int
%mixed_entry = OpLabel
OpReturn
OpFunctionEnd
)"));
)" + MainBody()));
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
auto fe = p->function_emitter(100);
auto fe = p->function_emitter(200);
EXPECT_TRUE(fe.Emit());
auto got = p->program().to_str();
std::string expect = R"(Module{
Function x_100 -> __void
Function x_200 -> __void
(
VariableConst{
a
@ -139,28 +157,28 @@ TEST_F(SpvParserTest, Emit_MixedParamTypes) {
}
}
)";
EXPECT_EQ(got, expect);
EXPECT_THAT(got, HasSubstr(expect));
}
TEST_F(SpvParserTest, Emit_GenerateParamNames) {
auto p = parser(test::Assemble(CommonTypes() + R"(
%fn_mixed_params = OpTypeFunction %float %uint %float %int
auto p = parser(test::Assemble(Preamble() + CommonTypes() + R"(
%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
%15 = OpFunctionParameter %float
%16 = OpFunctionParameter %int
%mixed_entry = OpLabel
OpReturn
OpFunctionEnd
)"));
)" + MainBody()));
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
auto fe = p->function_emitter(100);
auto fe = p->function_emitter(200);
EXPECT_TRUE(fe.Emit());
auto got = p->program().to_str();
std::string expect = R"(Module{
Function x_100 -> __void
Function x_200 -> __void
(
VariableConst{
x_14
@ -186,7 +204,7 @@ TEST_F(SpvParserTest, Emit_GenerateParamNames) {
}
}
)";
EXPECT_EQ(got, expect);
EXPECT_THAT(got, HasSubstr(expect));
}
} // namespace

View File

@ -306,7 +306,7 @@ TEST_F(SpvParserMemoryTest,
%ptr_wg_ty = OpTypePointer Workgroup %ty
%ptr_priv_ty = OpTypePointer Private %ty
%1 = OpVariable %ptr_wg_ty Workgroup
%2 = OpVariable %ptr_priv_ty Workgroup
%2 = OpVariable %ptr_priv_ty Private
%100 = OpFunction %void None %voidfn
%entry = OpLabel
OpCopyMemory %2 %1
@ -1048,6 +1048,10 @@ Assignment{
}
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
// has its declaration hoisted.
const auto assembly = OldStorageBufferPreamble() + R"(
@ -1119,6 +1123,7 @@ Assignment{
}
Return{}
)") << p->error();
p->SkipDumpingPending("crbug.com/tint/98");
}
TEST_F(SpvParserMemoryTest, DISABLED_RemapStorageBuffer_ThroughFunctionCall) {

View File

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

View File

@ -1951,7 +1951,7 @@ TEST_F(SpvParserFunctionVarTest, EmitStatement_Phi_FromElseAndThen) {
OpBranch %89
%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
OpBranch %10
@ -2026,6 +2026,10 @@ Loop{
Continue{}
}
}
Assignment{
Identifier[not set]{x_2_phi}
ScalarConstructor[not set]{0u}
}
continuing {
VariableDeclStatement{
VariableConst{

View File

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

View File

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

View File

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

View File

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