writer/spirv: Validate arrayLength()
This was tested but the output was not run through the validator. Once the AST is actually correct, the output is validated correctly. Fixed: tint:266 Change-Id: I83bb53323c124c8fbaa3cd9b80524f89c2e30557 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/40601 Auto-Submit: Ben Clayton <bclayton@google.com> Commit-Queue: dan sinclair <dsinclair@chromium.org> Reviewed-by: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
parent
7b7d69854d
commit
6f48851f27
|
@ -25,6 +25,7 @@
|
||||||
#include "src/ast/sint_literal.h"
|
#include "src/ast/sint_literal.h"
|
||||||
#include "src/ast/stage_decoration.h"
|
#include "src/ast/stage_decoration.h"
|
||||||
#include "src/ast/struct.h"
|
#include "src/ast/struct.h"
|
||||||
|
#include "src/ast/struct_block_decoration.h"
|
||||||
#include "src/ast/struct_member.h"
|
#include "src/ast/struct_member.h"
|
||||||
#include "src/ast/type_constructor_expression.h"
|
#include "src/ast/type_constructor_expression.h"
|
||||||
#include "src/ast/uint_literal.h"
|
#include "src/ast/uint_literal.h"
|
||||||
|
@ -1406,77 +1407,103 @@ OpFunctionEnd
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IntrinsicBuilderTest, Call_ArrayLength) {
|
TEST_F(IntrinsicBuilderTest, Call_ArrayLength) {
|
||||||
auto* s =
|
auto* s = create<ast::Struct>(
|
||||||
create<ast::Struct>(ast::StructMemberList{Member("a", ty.array<f32>())},
|
ast::StructMemberList{Member(0, "a", ty.array<f32>(4))},
|
||||||
ast::StructDecorationList{});
|
ast::StructDecorationList{
|
||||||
|
create<ast::StructBlockDecoration>(),
|
||||||
|
});
|
||||||
auto* s_type = ty.struct_("my_struct", s);
|
auto* s_type = ty.struct_("my_struct", s);
|
||||||
auto* var = Global("b", ast::StorageClass::kPrivate, s_type);
|
Global("b", ast::StorageClass::kStorage, s_type, nullptr,
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
create<ast::BindingDecoration>(1),
|
||||||
|
create<ast::GroupDecoration>(2),
|
||||||
|
});
|
||||||
|
|
||||||
auto* expr = Call("arrayLength", MemberAccessor("b", "a"));
|
auto* expr = Call("arrayLength", MemberAccessor("b", "a"));
|
||||||
WrapInFunction(expr);
|
|
||||||
|
|
||||||
auto* func = Func("a_func", ast::VariableList{}, ty.void_(),
|
Func("a_func", ast::VariableList{}, ty.void_(),
|
||||||
ast::StatementList{}, ast::FunctionDecorationList{});
|
ast::StatementList{
|
||||||
|
create<ast::CallStatement>(expr),
|
||||||
|
},
|
||||||
|
ast::FunctionDecorationList{
|
||||||
|
create<ast::StageDecoration>(ast::PipelineStage::kVertex),
|
||||||
|
});
|
||||||
|
|
||||||
spirv::Builder& b = Build();
|
spirv::Builder& b = Build();
|
||||||
|
|
||||||
ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
|
ASSERT_TRUE(b.Build()) << b.error();
|
||||||
ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
|
|
||||||
EXPECT_EQ(b.GenerateExpression(expr), 11u) << b.error();
|
|
||||||
|
|
||||||
EXPECT_EQ(DumpInstructions(b.types()),
|
ASSERT_EQ(b.functions().size(), 1u);
|
||||||
R"(%2 = OpTypeVoid
|
|
||||||
%1 = OpTypeFunction %2
|
|
||||||
%9 = OpTypeFloat 32
|
|
||||||
%8 = OpTypeRuntimeArray %9
|
|
||||||
%7 = OpTypeStruct %8
|
|
||||||
%6 = OpTypePointer Private %7
|
|
||||||
%10 = OpConstantNull %7
|
|
||||||
%5 = OpVariable %6 Private %10
|
|
||||||
%12 = OpTypeInt 32 0
|
|
||||||
)");
|
|
||||||
|
|
||||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
auto* expected_types = R"(%5 = OpTypeFloat 32
|
||||||
R"(%11 = OpArrayLength %12 %5 0
|
%4 = OpTypeRuntimeArray %5
|
||||||
)");
|
%3 = OpTypeStruct %4
|
||||||
|
%2 = OpTypePointer StorageBuffer %3
|
||||||
|
%1 = OpVariable %2 StorageBuffer
|
||||||
|
%7 = OpTypeVoid
|
||||||
|
%6 = OpTypeFunction %7
|
||||||
|
%11 = OpTypeInt 32 0
|
||||||
|
)";
|
||||||
|
auto got_types = DumpInstructions(b.types());
|
||||||
|
EXPECT_EQ(expected_types, got_types);
|
||||||
|
|
||||||
|
auto* expected_instructions = R"(%10 = OpArrayLength %11 %1 0
|
||||||
|
)";
|
||||||
|
auto got_instructions = DumpInstructions(b.functions()[0].instructions());
|
||||||
|
EXPECT_EQ(expected_instructions, got_instructions);
|
||||||
|
|
||||||
|
Validate(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IntrinsicBuilderTest, Call_ArrayLength_OtherMembersInStruct) {
|
TEST_F(IntrinsicBuilderTest, Call_ArrayLength_OtherMembersInStruct) {
|
||||||
auto* s =
|
auto* s = create<ast::Struct>(
|
||||||
create<ast::Struct>(ast::StructMemberList{Member("z", ty.f32()),
|
ast::StructMemberList{Member(0, "z", ty.f32()),
|
||||||
Member("a", ty.array<f32>())},
|
Member(4, "a", ty.array<f32>(4))},
|
||||||
ast::StructDecorationList{});
|
ast::StructDecorationList{
|
||||||
|
create<ast::StructBlockDecoration>(),
|
||||||
|
});
|
||||||
|
|
||||||
auto* s_type = ty.struct_("my_struct", s);
|
auto* s_type = ty.struct_("my_struct", s);
|
||||||
auto* var = Global("b", ast::StorageClass::kPrivate, s_type);
|
Global("b", ast::StorageClass::kStorage, s_type, nullptr,
|
||||||
|
ast::VariableDecorationList{
|
||||||
|
create<ast::BindingDecoration>(1),
|
||||||
|
create<ast::GroupDecoration>(2),
|
||||||
|
});
|
||||||
|
|
||||||
auto* expr = Call("arrayLength", MemberAccessor("b", "a"));
|
auto* expr = Call("arrayLength", MemberAccessor("b", "a"));
|
||||||
WrapInFunction(expr);
|
|
||||||
|
|
||||||
auto* func = Func("a_func", ast::VariableList{}, ty.void_(),
|
Func("a_func", ast::VariableList{}, ty.void_(),
|
||||||
ast::StatementList{}, ast::FunctionDecorationList{});
|
ast::StatementList{
|
||||||
|
create<ast::CallStatement>(expr),
|
||||||
|
},
|
||||||
|
ast::FunctionDecorationList{
|
||||||
|
create<ast::StageDecoration>(ast::PipelineStage::kVertex),
|
||||||
|
});
|
||||||
|
|
||||||
spirv::Builder& b = Build();
|
spirv::Builder& b = Build();
|
||||||
|
|
||||||
ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
|
ASSERT_TRUE(b.Build()) << b.error();
|
||||||
ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
|
|
||||||
EXPECT_EQ(b.GenerateExpression(expr), 11u) << b.error();
|
|
||||||
|
|
||||||
EXPECT_EQ(DumpInstructions(b.types()),
|
ASSERT_EQ(b.functions().size(), 1u);
|
||||||
R"(%2 = OpTypeVoid
|
|
||||||
%1 = OpTypeFunction %2
|
|
||||||
%8 = OpTypeFloat 32
|
|
||||||
%9 = OpTypeRuntimeArray %8
|
|
||||||
%7 = OpTypeStruct %8 %9
|
|
||||||
%6 = OpTypePointer Private %7
|
|
||||||
%10 = OpConstantNull %7
|
|
||||||
%5 = OpVariable %6 Private %10
|
|
||||||
%12 = OpTypeInt 32 0
|
|
||||||
)");
|
|
||||||
|
|
||||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
auto* expected_types = R"(%4 = OpTypeFloat 32
|
||||||
R"(%11 = OpArrayLength %12 %5 1
|
%5 = OpTypeRuntimeArray %4
|
||||||
)");
|
%3 = OpTypeStruct %4 %5
|
||||||
|
%2 = OpTypePointer StorageBuffer %3
|
||||||
|
%1 = OpVariable %2 StorageBuffer
|
||||||
|
%7 = OpTypeVoid
|
||||||
|
%6 = OpTypeFunction %7
|
||||||
|
%11 = OpTypeInt 32 0
|
||||||
|
)";
|
||||||
|
auto got_types = DumpInstructions(b.types());
|
||||||
|
EXPECT_EQ(expected_types, got_types);
|
||||||
|
|
||||||
|
auto* expected_instructions = R"(%10 = OpArrayLength %11 %1 1
|
||||||
|
)";
|
||||||
|
auto got_instructions = DumpInstructions(b.functions()[0].instructions());
|
||||||
|
EXPECT_EQ(expected_instructions, got_instructions);
|
||||||
|
|
||||||
|
Validate(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
Loading…
Reference in New Issue