reader/wgsl: Remove old shader IO syntax
Removing parsing support for the 'in' and 'out' storage classes is enough to prevent anyone from using the old syntax. The Input and Output storage classes will remain in the AST for now, as the SPIR-V reader still has codepaths that use them, and the SPIR-V writer currently still relies on them. Bug: tint:697 Change-Id: Ifef9eda8bcbf2f243b1e1d8d4fab25784cd3f80e Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/54841 Auto-Submit: James Price <jrprice@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Ben Clayton <bclayton@google.com> Commit-Queue: James Price <jrprice@google.com>
This commit is contained in:
parent
443c41de33
commit
90503dec9c
|
@ -586,8 +586,6 @@ Token Lexer::check_keyword(const Source& source, const std::string& str) {
|
|||
return {Token::Type::kImage, source, "image"};
|
||||
if (str == "import")
|
||||
return {Token::Type::kImport, source, "import"};
|
||||
if (str == "in")
|
||||
return {Token::Type::kIn, source, "in"};
|
||||
if (str == "let")
|
||||
return {Token::Type::kLet, source, "let"};
|
||||
if (str == "loop")
|
||||
|
@ -610,8 +608,6 @@ Token Lexer::check_keyword(const Source& source, const std::string& str) {
|
|||
return {Token::Type::kMat4x3, source, "mat4x3"};
|
||||
if (str == "mat4x4")
|
||||
return {Token::Type::kMat4x4, source, "mat4x4"};
|
||||
if (str == "out")
|
||||
return {Token::Type::kOut, source, "out"};
|
||||
if (str == "private")
|
||||
return {Token::Type::kPrivate, source, "private"};
|
||||
if (str == "ptr")
|
||||
|
|
|
@ -475,7 +475,6 @@ INSTANTIATE_TEST_SUITE_P(
|
|||
TokenData{"if", Token::Type::kIf},
|
||||
TokenData{"image", Token::Type::kImage},
|
||||
TokenData{"import", Token::Type::kImport},
|
||||
TokenData{"in", Token::Type::kIn},
|
||||
TokenData{"let", Token::Type::kLet},
|
||||
TokenData{"loop", Token::Type::kLoop},
|
||||
TokenData{"mat2x2", Token::Type::kMat2x2},
|
||||
|
@ -487,7 +486,6 @@ INSTANTIATE_TEST_SUITE_P(
|
|||
TokenData{"mat4x2", Token::Type::kMat4x2},
|
||||
TokenData{"mat4x3", Token::Type::kMat4x3},
|
||||
TokenData{"mat4x4", Token::Type::kMat4x4},
|
||||
TokenData{"out", Token::Type::kOut},
|
||||
TokenData{"private", Token::Type::kPrivate},
|
||||
TokenData{"ptr", Token::Type::kPtr},
|
||||
TokenData{"return", Token::Type::kReturn},
|
||||
|
|
|
@ -530,18 +530,6 @@ Maybe<ParserImpl::VarDeclInfo> ParserImpl::variable_decl(bool allow_inferred) {
|
|||
return Failure::kErrored;
|
||||
if (explicit_vq.matched) {
|
||||
vq = explicit_vq.value;
|
||||
|
||||
// TODO(crbug.com/tint/697): Remove this.
|
||||
if (vq.storage_class == ast::StorageClass::kInput) {
|
||||
deprecated(explicit_vq.source,
|
||||
"use an entry point parameter instead of a variable in the "
|
||||
"`in` storage class");
|
||||
}
|
||||
if (vq.storage_class == ast::StorageClass::kOutput) {
|
||||
deprecated(explicit_vq.source,
|
||||
"use an entry point return value instead of a variable in the "
|
||||
"`out` storage class");
|
||||
}
|
||||
}
|
||||
|
||||
auto decl =
|
||||
|
@ -1236,12 +1224,6 @@ Expect<ast::StorageClass> ParserImpl::expect_storage_class(
|
|||
const std::string& use) {
|
||||
auto source = peek().source();
|
||||
|
||||
if (match(Token::Type::kIn))
|
||||
return {ast::StorageClass::kInput, source};
|
||||
|
||||
if (match(Token::Type::kOut))
|
||||
return {ast::StorageClass::kOutput, source};
|
||||
|
||||
if (match(Token::Type::kUniform))
|
||||
return {ast::StorageClass::kUniform, source};
|
||||
|
||||
|
|
|
@ -996,17 +996,17 @@ TEST_F(ParserImplErrorTest, GlobalDeclVarPtrMissingLessThan) {
|
|||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarPtrMissingGreaterThan) {
|
||||
EXPECT("var i : ptr<in, u32;",
|
||||
"test.wgsl:1:20 error: expected '>' for ptr declaration\n"
|
||||
"var i : ptr<in, u32;\n"
|
||||
" ^\n");
|
||||
EXPECT("var i : ptr<private, u32;",
|
||||
"test.wgsl:1:25 error: expected '>' for ptr declaration\n"
|
||||
"var i : ptr<private, u32;\n"
|
||||
" ^\n");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarPtrMissingComma) {
|
||||
EXPECT("var i : ptr<in u32>;",
|
||||
"test.wgsl:1:16 error: expected ',' for ptr declaration\n"
|
||||
"var i : ptr<in u32>;\n"
|
||||
" ^^^\n");
|
||||
EXPECT("var i : ptr<private u32>;",
|
||||
"test.wgsl:1:21 error: expected ',' for ptr declaration\n"
|
||||
"var i : ptr<private u32>;\n"
|
||||
" ^^^\n");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarPtrMissingStorageClass) {
|
||||
|
@ -1017,10 +1017,10 @@ TEST_F(ParserImplErrorTest, GlobalDeclVarPtrMissingStorageClass) {
|
|||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarPtrMissingType) {
|
||||
EXPECT("var i : ptr<in, 1>;",
|
||||
"test.wgsl:1:17 error: invalid type for ptr declaration\n"
|
||||
"var i : ptr<in, 1>;\n"
|
||||
" ^\n");
|
||||
EXPECT("var i : ptr<private, 1>;",
|
||||
"test.wgsl:1:22 error: invalid type for ptr declaration\n"
|
||||
"var i : ptr<private, 1>;\n"
|
||||
" ^\n");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarAtomicMissingLessThan) {
|
||||
|
@ -1045,10 +1045,10 @@ TEST_F(ParserImplErrorTest, GlobalDeclVarStorageDeclInvalidClass) {
|
|||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarStorageDeclMissingGThan) {
|
||||
EXPECT("var<in i : i32",
|
||||
"test.wgsl:1:8 error: expected '>' for variable declaration\n"
|
||||
"var<in i : i32\n"
|
||||
" ^\n");
|
||||
EXPECT("var<private i : i32",
|
||||
"test.wgsl:1:13 error: expected '>' for variable declaration\n"
|
||||
"var<private i : i32\n"
|
||||
" ^\n");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplErrorTest, GlobalDeclVarVectorMissingLessThan) {
|
||||
|
|
|
@ -168,48 +168,6 @@ TEST_F(ParserImplTest, GlobalVariableDecl_InvalidVariableDecl) {
|
|||
EXPECT_EQ(p->error(), "1:5: invalid storage class for variable declaration");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, GlobalVariableDecl_StorageClassIn_Deprecated) {
|
||||
auto p = parser("[[location(0)]] var<in> a : f32");
|
||||
auto f = p->function_header();
|
||||
auto decos = p->decoration_list();
|
||||
EXPECT_FALSE(decos.errored);
|
||||
EXPECT_TRUE(decos.matched);
|
||||
auto e = p->global_variable_decl(decos.value);
|
||||
ASSERT_FALSE(p->has_error()) << p->error();
|
||||
|
||||
EXPECT_EQ(e->symbol(), p->builder().Symbols().Get("a"));
|
||||
EXPECT_TRUE(e->type()->Is<ast::F32>());
|
||||
EXPECT_EQ(e->declared_storage_class(), ast::StorageClass::kInput);
|
||||
|
||||
EXPECT_EQ(
|
||||
p->builder().Diagnostics().str(),
|
||||
R"(test.wgsl:1:21 warning: use of deprecated language feature: use an entry point parameter instead of a variable in the `in` storage class
|
||||
[[location(0)]] var<in> a : f32
|
||||
^^
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, GlobalVariableDecl_StorageClassOut_Deprecated) {
|
||||
auto p = parser("[[location(0)]] var<out> a : f32");
|
||||
auto f = p->function_header();
|
||||
auto decos = p->decoration_list();
|
||||
EXPECT_FALSE(decos.errored);
|
||||
EXPECT_TRUE(decos.matched);
|
||||
auto e = p->global_variable_decl(decos.value);
|
||||
ASSERT_FALSE(p->has_error()) << p->error();
|
||||
|
||||
EXPECT_EQ(e->symbol(), p->builder().Symbols().Get("a"));
|
||||
EXPECT_TRUE(e->type()->Is<ast::F32>());
|
||||
EXPECT_EQ(e->declared_storage_class(), ast::StorageClass::kOutput);
|
||||
|
||||
EXPECT_EQ(
|
||||
p->builder().Diagnostics().str(),
|
||||
R"(test.wgsl:1:21 warning: use of deprecated language feature: use an entry point return value instead of a variable in the `out` storage class
|
||||
[[location(0)]] var<out> a : f32
|
||||
^^^
|
||||
)");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace wgsl
|
||||
} // namespace reader
|
||||
|
|
|
@ -46,8 +46,6 @@ INSTANTIATE_TEST_SUITE_P(
|
|||
ParserImplTest,
|
||||
StorageClassTest,
|
||||
testing::Values(
|
||||
StorageClassData{"in", ast::StorageClass::kInput},
|
||||
StorageClassData{"out", ast::StorageClass::kOutput},
|
||||
StorageClassData{"uniform", ast::StorageClass::kUniform},
|
||||
StorageClassData{"workgroup", ast::StorageClass::kWorkgroup},
|
||||
StorageClassData{"storage", ast::StorageClass::kStorage},
|
||||
|
|
|
@ -26,18 +26,15 @@ TEST_F(ParserImplTest, Empty) {
|
|||
|
||||
TEST_F(ParserImplTest, Parses) {
|
||||
auto p = parser(R"(
|
||||
[[location(0)]] var<out> gl_FragColor : vec4<f32>;
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn main() {
|
||||
gl_FragColor = vec4<f32>(.4, .2, .3, 1);
|
||||
[[stage(fragment)]]
|
||||
fn main() -> [[location(0)]] vec4<f32> {
|
||||
return vec4<f32>(.4, .2, .3, 1);
|
||||
}
|
||||
)");
|
||||
ASSERT_TRUE(p->Parse()) << p->error();
|
||||
|
||||
Program program = p->program();
|
||||
ASSERT_EQ(1u, program.AST().Functions().size());
|
||||
ASSERT_EQ(1u, program.AST().GlobalVariables().size());
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, HandlesError) {
|
||||
|
|
|
@ -50,10 +50,6 @@ INSTANTIATE_TEST_SUITE_P(
|
|||
ParserImplTest,
|
||||
VariableQualifierTest,
|
||||
testing::Values(
|
||||
VariableStorageData{"in", ast::StorageClass::kInput,
|
||||
ast::Access::kUndefined},
|
||||
VariableStorageData{"out", ast::StorageClass::kOutput,
|
||||
ast::Access::kUndefined},
|
||||
VariableStorageData{"uniform", ast::StorageClass::kUniform,
|
||||
ast::Access::kUndefined},
|
||||
VariableStorageData{"workgroup", ast::StorageClass::kWorkgroup,
|
||||
|
@ -94,34 +90,34 @@ TEST_F(ParserImplTest, VariableQualifier_Empty) {
|
|||
}
|
||||
|
||||
TEST_F(ParserImplTest, VariableQualifier_MissingLessThan) {
|
||||
auto p = parser("in>");
|
||||
auto p = parser("private>");
|
||||
auto sc = p->variable_qualifier();
|
||||
EXPECT_FALSE(p->has_error());
|
||||
EXPECT_FALSE(sc.errored);
|
||||
EXPECT_FALSE(sc.matched);
|
||||
|
||||
auto t = p->next();
|
||||
ASSERT_TRUE(t.IsIn());
|
||||
ASSERT_TRUE(t.IsPrivate());
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, VariableQualifier_MissingLessThan_AfterSC) {
|
||||
auto p = parser("in, >");
|
||||
auto p = parser("private, >");
|
||||
auto sc = p->variable_qualifier();
|
||||
EXPECT_FALSE(p->has_error());
|
||||
EXPECT_FALSE(sc.errored);
|
||||
EXPECT_FALSE(sc.matched);
|
||||
|
||||
auto t = p->next();
|
||||
ASSERT_TRUE(t.IsIn());
|
||||
ASSERT_TRUE(t.IsPrivate());
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, VariableQualifier_MissingGreaterThan) {
|
||||
auto p = parser("<in");
|
||||
auto p = parser("<private");
|
||||
auto sc = p->variable_qualifier();
|
||||
EXPECT_TRUE(p->has_error());
|
||||
EXPECT_TRUE(sc.errored);
|
||||
EXPECT_FALSE(sc.matched);
|
||||
EXPECT_EQ(p->error(), "1:4: expected '>' for variable declaration");
|
||||
EXPECT_EQ(p->error(), "1:9: expected '>' for variable declaration");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -34,11 +34,9 @@ TEST_F(ParserTest, Empty) {
|
|||
|
||||
TEST_F(ParserTest, Parses) {
|
||||
Source::File file("test.wgsl", R"(
|
||||
[[location(0)]] var<out> gl_FragColor : vec4<f32>;
|
||||
|
||||
[[stage(fragment)]]
|
||||
fn main() {
|
||||
gl_FragColor = vec4<f32>(.4, .2, .3, 1.);
|
||||
fn main() -> [[location(0)]] vec4<f32> {
|
||||
return vec4<f32>(.4, .2, .3, 1.);
|
||||
}
|
||||
)");
|
||||
auto program = Parse(&file);
|
||||
|
@ -46,7 +44,6 @@ fn main() {
|
|||
ASSERT_TRUE(program.IsValid()) << errs;
|
||||
|
||||
ASSERT_EQ(1u, program.AST().Functions().size());
|
||||
ASSERT_EQ(1u, program.AST().GlobalVariables().size());
|
||||
}
|
||||
|
||||
TEST_F(ParserTest, HandlesError) {
|
||||
|
|
|
@ -221,8 +221,6 @@ std::string Token::TypeToName(Type type) {
|
|||
return "image";
|
||||
case Token::Type::kImport:
|
||||
return "import";
|
||||
case Token::Type::kIn:
|
||||
return "in";
|
||||
case Token::Type::kLet:
|
||||
return "let";
|
||||
case Token::Type::kLoop:
|
||||
|
@ -245,8 +243,6 @@ std::string Token::TypeToName(Type type) {
|
|||
return "mat4x3";
|
||||
case Token::Type::kMat4x4:
|
||||
return "mat4x4";
|
||||
case Token::Type::kOut:
|
||||
return "out";
|
||||
case Token::Type::kPrivate:
|
||||
return "private";
|
||||
case Token::Type::kPtr:
|
||||
|
|
|
@ -229,8 +229,6 @@ class Token {
|
|||
kImage,
|
||||
/// A 'import'
|
||||
kImport,
|
||||
/// A 'in'
|
||||
kIn,
|
||||
/// A 'let'
|
||||
kLet,
|
||||
/// A 'loop'
|
||||
|
@ -253,8 +251,6 @@ class Token {
|
|||
kMat4x3,
|
||||
/// A 'mat4x4'
|
||||
kMat4x4,
|
||||
/// A 'out'
|
||||
kOut,
|
||||
/// A 'private'
|
||||
kPrivate,
|
||||
/// A 'ptr'
|
||||
|
@ -576,8 +572,6 @@ class Token {
|
|||
bool IsImage() const { return type_ == Type::kImage; }
|
||||
/// @returns true if token is a 'import'
|
||||
bool IsImport() const { return type_ == Type::kImport; }
|
||||
/// @returns true if token is a 'in'
|
||||
bool IsIn() const { return type_ == Type::kIn; }
|
||||
/// @returns true if token is a 'let'
|
||||
bool IsLet() const { return type_ == Type::kLet; }
|
||||
/// @returns true if token is a 'loop'
|
||||
|
@ -600,8 +594,6 @@ class Token {
|
|||
bool IsMat4x3() const { return type_ == Type::kMat4x3; }
|
||||
/// @returns true if token is a 'mat4x4'
|
||||
bool IsMat4x4() const { return type_ == Type::kMat4x4; }
|
||||
/// @returns true if token is a 'out'
|
||||
bool IsOut() const { return type_ == Type::kOut; }
|
||||
/// @returns true if token is a 'private'
|
||||
bool IsPrivate() const { return type_ == Type::kPrivate; }
|
||||
/// @returns true if token is a 'ptr'
|
||||
|
|
|
@ -326,236 +326,6 @@ fn entry_c([[builtin(instance_index)]] inst_idx : u32) -> [[builtin(position)]]
|
|||
EXPECT_EQ(data->first_instance_offset, 4u);
|
||||
}
|
||||
|
||||
TEST_F(FirstIndexOffsetTest, OLD_BasicModuleVertexIndex) {
|
||||
auto* src = R"(
|
||||
[[builtin(vertex_index)]] var<in> vert_idx : u32;
|
||||
|
||||
[[builtin(position)]] var<out> pos : vec4<f32>;
|
||||
|
||||
fn test() -> u32 {
|
||||
return vert_idx;
|
||||
}
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn entry() {
|
||||
ignore(test());
|
||||
pos = vec4<f32>();
|
||||
}
|
||||
)";
|
||||
|
||||
auto* expect = R"(
|
||||
[[block]]
|
||||
struct tint_symbol {
|
||||
first_vertex_index : u32;
|
||||
};
|
||||
|
||||
[[binding(1), group(2)]] var<uniform> tint_symbol_1 : tint_symbol;
|
||||
|
||||
[[builtin(vertex_index)]] var<in> vert_idx : u32;
|
||||
|
||||
[[builtin(position)]] var<out> pos : vec4<f32>;
|
||||
|
||||
fn test() -> u32 {
|
||||
return (vert_idx + tint_symbol_1.first_vertex_index);
|
||||
}
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn entry() {
|
||||
ignore(test());
|
||||
pos = vec4<f32>();
|
||||
}
|
||||
)";
|
||||
|
||||
DataMap config;
|
||||
config.Add<FirstIndexOffset::BindingPoint>(1, 2);
|
||||
auto got = Run<FirstIndexOffset>(src, std::move(config));
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
|
||||
auto* data = got.data.Get<FirstIndexOffset::Data>();
|
||||
|
||||
ASSERT_NE(data, nullptr);
|
||||
EXPECT_EQ(data->has_vertex_index, true);
|
||||
EXPECT_EQ(data->has_instance_index, false);
|
||||
EXPECT_EQ(data->first_vertex_offset, 0u);
|
||||
EXPECT_EQ(data->first_instance_offset, 0u);
|
||||
}
|
||||
|
||||
TEST_F(FirstIndexOffsetTest, OLD_BasicModuleInstanceIndex) {
|
||||
auto* src = R"(
|
||||
[[builtin(instance_index)]] var<in> inst_idx : u32;
|
||||
|
||||
[[builtin(position)]] var<out> pos : vec4<f32>;
|
||||
|
||||
fn test() -> u32 {
|
||||
return inst_idx;
|
||||
}
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn entry() {
|
||||
ignore(test());
|
||||
pos = vec4<f32>();
|
||||
}
|
||||
)";
|
||||
|
||||
auto* expect = R"(
|
||||
[[block]]
|
||||
struct tint_symbol {
|
||||
first_instance_index : u32;
|
||||
};
|
||||
|
||||
[[binding(1), group(7)]] var<uniform> tint_symbol_1 : tint_symbol;
|
||||
|
||||
[[builtin(instance_index)]] var<in> inst_idx : u32;
|
||||
|
||||
[[builtin(position)]] var<out> pos : vec4<f32>;
|
||||
|
||||
fn test() -> u32 {
|
||||
return (inst_idx + tint_symbol_1.first_instance_index);
|
||||
}
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn entry() {
|
||||
ignore(test());
|
||||
pos = vec4<f32>();
|
||||
}
|
||||
)";
|
||||
|
||||
DataMap config;
|
||||
config.Add<FirstIndexOffset::BindingPoint>(1, 7);
|
||||
auto got = Run<FirstIndexOffset>(src, std::move(config));
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
|
||||
auto* data = got.data.Get<FirstIndexOffset::Data>();
|
||||
|
||||
ASSERT_NE(data, nullptr);
|
||||
EXPECT_EQ(data->has_vertex_index, false);
|
||||
EXPECT_EQ(data->has_instance_index, true);
|
||||
EXPECT_EQ(data->first_vertex_offset, 0u);
|
||||
EXPECT_EQ(data->first_instance_offset, 0u);
|
||||
}
|
||||
|
||||
TEST_F(FirstIndexOffsetTest, OLD_BasicModuleBothIndex) {
|
||||
auto* src = R"(
|
||||
[[builtin(instance_index)]] var<in> instance_idx : u32;
|
||||
[[builtin(vertex_index)]] var<in> vert_idx : u32;
|
||||
[[builtin(position)]] var<out> pos : vec4<f32>;
|
||||
|
||||
fn test() -> u32 {
|
||||
return instance_idx + vert_idx;
|
||||
}
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn entry() {
|
||||
ignore(test());
|
||||
pos = vec4<f32>();
|
||||
}
|
||||
)";
|
||||
|
||||
auto* expect = R"(
|
||||
[[block]]
|
||||
struct tint_symbol {
|
||||
first_vertex_index : u32;
|
||||
first_instance_index : u32;
|
||||
};
|
||||
|
||||
[[binding(1), group(2)]] var<uniform> tint_symbol_1 : tint_symbol;
|
||||
|
||||
[[builtin(instance_index)]] var<in> instance_idx : u32;
|
||||
|
||||
[[builtin(vertex_index)]] var<in> vert_idx : u32;
|
||||
|
||||
[[builtin(position)]] var<out> pos : vec4<f32>;
|
||||
|
||||
fn test() -> u32 {
|
||||
return ((instance_idx + tint_symbol_1.first_instance_index) + (vert_idx + tint_symbol_1.first_vertex_index));
|
||||
}
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn entry() {
|
||||
ignore(test());
|
||||
pos = vec4<f32>();
|
||||
}
|
||||
)";
|
||||
|
||||
DataMap config;
|
||||
config.Add<FirstIndexOffset::BindingPoint>(1, 2);
|
||||
auto got = Run<FirstIndexOffset>(src, std::move(config));
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
|
||||
auto* data = got.data.Get<FirstIndexOffset::Data>();
|
||||
|
||||
ASSERT_NE(data, nullptr);
|
||||
EXPECT_EQ(data->has_vertex_index, true);
|
||||
EXPECT_EQ(data->has_instance_index, true);
|
||||
EXPECT_EQ(data->first_vertex_offset, 0u);
|
||||
EXPECT_EQ(data->first_instance_offset, 4u);
|
||||
}
|
||||
|
||||
TEST_F(FirstIndexOffsetTest, OLD_NestedCalls) {
|
||||
auto* src = R"(
|
||||
[[builtin(vertex_index)]] var<in> vert_idx : u32;
|
||||
[[builtin(position)]] var<out> pos : vec4<f32>;
|
||||
|
||||
fn func1() -> u32 {
|
||||
return vert_idx;
|
||||
}
|
||||
|
||||
fn func2() -> u32 {
|
||||
return func1();
|
||||
}
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn entry() {
|
||||
ignore(func2());
|
||||
pos = vec4<f32>();
|
||||
}
|
||||
)";
|
||||
|
||||
auto* expect = R"(
|
||||
[[block]]
|
||||
struct tint_symbol {
|
||||
first_vertex_index : u32;
|
||||
};
|
||||
|
||||
[[binding(1), group(2)]] var<uniform> tint_symbol_1 : tint_symbol;
|
||||
|
||||
[[builtin(vertex_index)]] var<in> vert_idx : u32;
|
||||
|
||||
[[builtin(position)]] var<out> pos : vec4<f32>;
|
||||
|
||||
fn func1() -> u32 {
|
||||
return (vert_idx + tint_symbol_1.first_vertex_index);
|
||||
}
|
||||
|
||||
fn func2() -> u32 {
|
||||
return func1();
|
||||
}
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn entry() {
|
||||
ignore(func2());
|
||||
pos = vec4<f32>();
|
||||
}
|
||||
)";
|
||||
|
||||
DataMap config;
|
||||
config.Add<FirstIndexOffset::BindingPoint>(1, 2);
|
||||
auto got = Run<FirstIndexOffset>(src, std::move(config));
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
|
||||
auto* data = got.data.Get<FirstIndexOffset::Data>();
|
||||
|
||||
ASSERT_NE(data, nullptr);
|
||||
EXPECT_EQ(data->has_vertex_index, true);
|
||||
EXPECT_EQ(data->has_instance_index, false);
|
||||
EXPECT_EQ(data->first_vertex_offset, 0u);
|
||||
EXPECT_EQ(data->first_instance_offset, 0u);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace transform
|
||||
} // namespace tint
|
||||
|
|
|
@ -42,29 +42,26 @@ TEST_F(RenamerTest, EmptyModule) {
|
|||
|
||||
TEST_F(RenamerTest, BasicModuleVertexIndex) {
|
||||
auto* src = R"(
|
||||
[[builtin(vertex_index)]] var<in> vert_idx : u32;
|
||||
|
||||
fn test() -> u32 {
|
||||
fn test(vert_idx : u32) -> u32 {
|
||||
return vert_idx;
|
||||
}
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn entry() -> [[builtin(position)]] vec4<f32> {
|
||||
ignore(test());
|
||||
fn entry([[builtin(vertex_index)]] vert_idx : u32
|
||||
) -> [[builtin(position)]] vec4<f32> {
|
||||
ignore(test(vert_idx));
|
||||
return vec4<f32>();
|
||||
}
|
||||
)";
|
||||
|
||||
auto* expect = R"(
|
||||
[[builtin(vertex_index)]] var<in> tint_symbol : u32;
|
||||
|
||||
fn tint_symbol_1() -> u32 {
|
||||
return tint_symbol;
|
||||
fn tint_symbol(tint_symbol_1 : u32) -> u32 {
|
||||
return tint_symbol_1;
|
||||
}
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn tint_symbol_2() -> [[builtin(position)]] vec4<f32> {
|
||||
ignore(tint_symbol_1());
|
||||
fn tint_symbol_2([[builtin(vertex_index)]] tint_symbol_1 : u32) -> [[builtin(position)]] vec4<f32> {
|
||||
ignore(tint_symbol(tint_symbol_1));
|
||||
return vec4<f32>();
|
||||
}
|
||||
)";
|
||||
|
@ -77,8 +74,8 @@ fn tint_symbol_2() -> [[builtin(position)]] vec4<f32> {
|
|||
|
||||
ASSERT_NE(data, nullptr);
|
||||
Renamer::Data::Remappings expected_remappings = {
|
||||
{"vert_idx", "tint_symbol"},
|
||||
{"test", "tint_symbol_1"},
|
||||
{"vert_idx", "tint_symbol_1"},
|
||||
{"test", "tint_symbol"},
|
||||
{"entry", "tint_symbol_2"},
|
||||
};
|
||||
EXPECT_THAT(data->remappings, ContainerEq(expected_remappings));
|
||||
|
|
|
@ -492,28 +492,29 @@ fn main() {
|
|||
|
||||
TEST_F(SpirvTest, HandleSampleMaskBuiltins_Basic) {
|
||||
auto* src = R"(
|
||||
[[builtin(sample_index)]] var<in> sample_index : u32;
|
||||
|
||||
[[builtin(sample_mask)]] var<in> mask_in : u32;
|
||||
|
||||
[[builtin(sample_mask)]] var<out> mask_out : u32;
|
||||
|
||||
[[stage(fragment)]]
|
||||
fn main() {
|
||||
mask_out = mask_in;
|
||||
fn main([[builtin(sample_index)]] sample_index : u32,
|
||||
[[builtin(sample_mask)]] mask_in : u32
|
||||
) -> [[builtin(sample_mask)]] u32 {
|
||||
return mask_in;
|
||||
}
|
||||
)";
|
||||
|
||||
auto* expect = R"(
|
||||
[[builtin(sample_index)]] var<in> sample_index : u32;
|
||||
[[builtin(sample_index)]] var<in> tint_symbol : u32;
|
||||
|
||||
[[builtin(sample_mask)]] var<in> mask_in : array<u32, 1>;
|
||||
[[builtin(sample_mask)]] var<in> tint_symbol_1 : array<u32, 1>;
|
||||
|
||||
[[builtin(sample_mask)]] var<out> mask_out : array<u32, 1>;
|
||||
[[builtin(sample_mask)]] var<out> tint_symbol_3 : array<u32, 1>;
|
||||
|
||||
fn tint_symbol_4(tint_symbol_2 : u32) {
|
||||
tint_symbol_3[0] = tint_symbol_2;
|
||||
}
|
||||
|
||||
[[stage(fragment)]]
|
||||
fn main() {
|
||||
mask_out[0] = mask_in[0];
|
||||
tint_symbol_4(tint_symbol_1[0]);
|
||||
return;
|
||||
}
|
||||
)";
|
||||
|
||||
|
@ -524,40 +525,42 @@ fn main() {
|
|||
|
||||
TEST_F(SpirvTest, HandleSampleMaskBuiltins_FunctionArg) {
|
||||
auto* src = R"(
|
||||
[[builtin(sample_mask)]] var<in> mask_in : u32;
|
||||
|
||||
[[builtin(sample_mask)]] var<out> mask_out : u32;
|
||||
|
||||
fn filter(mask: u32) -> u32 {
|
||||
return (mask & 3u);
|
||||
}
|
||||
|
||||
fn set_mask(input : u32) {
|
||||
mask_out = input;
|
||||
fn set_mask(input : u32) -> u32 {
|
||||
return input;
|
||||
}
|
||||
|
||||
[[stage(fragment)]]
|
||||
fn main() {
|
||||
set_mask(filter(mask_in));
|
||||
fn main([[builtin(sample_mask)]] mask_in : u32
|
||||
) -> [[builtin(sample_mask)]] u32 {
|
||||
return set_mask(filter(mask_in));
|
||||
}
|
||||
)";
|
||||
|
||||
auto* expect = R"(
|
||||
[[builtin(sample_mask)]] var<in> mask_in : array<u32, 1>;
|
||||
|
||||
[[builtin(sample_mask)]] var<out> mask_out : array<u32, 1>;
|
||||
|
||||
fn filter(mask : u32) -> u32 {
|
||||
return (mask & 3u);
|
||||
}
|
||||
|
||||
fn set_mask(input : u32) {
|
||||
mask_out[0] = input;
|
||||
fn set_mask(input : u32) -> u32 {
|
||||
return input;
|
||||
}
|
||||
|
||||
[[builtin(sample_mask)]] var<in> tint_symbol : array<u32, 1>;
|
||||
|
||||
[[builtin(sample_mask)]] var<out> tint_symbol_2 : array<u32, 1>;
|
||||
|
||||
fn tint_symbol_3(tint_symbol_1 : u32) {
|
||||
tint_symbol_2[0] = tint_symbol_1;
|
||||
}
|
||||
|
||||
[[stage(fragment)]]
|
||||
fn main() {
|
||||
set_mask(filter(mask_in[0]));
|
||||
tint_symbol_3(set_mask(filter(tint_symbol[0])));
|
||||
return;
|
||||
}
|
||||
)";
|
||||
|
||||
|
|
|
@ -652,174 +652,6 @@ fn main([[builtin(vertex_index)]] tint_pulling_vertex_index_1 : u32) -> [[builti
|
|||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
// TODO(crbug.com/tint/697): Remove this.
|
||||
TEST_F(VertexPullingTest, OneAttributeDifferentOutputSet_Legacy) {
|
||||
auto* src = R"(
|
||||
[[location(0)]] var<in> var_a : f32;
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn main() -> [[builtin(position)]] vec4<f32> {
|
||||
return vec4<f32>();
|
||||
}
|
||||
)";
|
||||
|
||||
auto* expect = R"(
|
||||
[[builtin(vertex_index)]] var<in> tint_pulling_vertex_index : u32;
|
||||
|
||||
[[block]]
|
||||
struct TintVertexData {
|
||||
tint_vertex_data : [[stride(4)]] array<u32>;
|
||||
};
|
||||
|
||||
[[binding(0), group(5)]] var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
|
||||
|
||||
var<private> var_a : f32;
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn main() -> [[builtin(position)]] vec4<f32> {
|
||||
{
|
||||
var tint_pulling_pos : u32;
|
||||
tint_pulling_pos = ((tint_pulling_vertex_index * 4u) + 0u);
|
||||
var_a = bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(tint_pulling_pos / 4u)]);
|
||||
}
|
||||
return vec4<f32>();
|
||||
}
|
||||
)";
|
||||
|
||||
VertexPulling::Config cfg;
|
||||
cfg.vertex_state = {
|
||||
{{4, InputStepMode::kVertex, {{VertexFormat::kF32, 0, 0}}}}};
|
||||
cfg.pulling_group = 5;
|
||||
cfg.entry_point_name = "main";
|
||||
|
||||
DataMap data;
|
||||
data.Add<VertexPulling::Config>(cfg);
|
||||
auto got = Run<VertexPulling>(src, data);
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
// TODO(crbug.com/tint/697): Remove this.
|
||||
// We expect the transform to use an existing builtin variables if it finds them
|
||||
TEST_F(VertexPullingTest, ExistingVertexIndexAndInstanceIndex_Legacy) {
|
||||
auto* src = R"(
|
||||
[[location(0)]] var<in> var_a : f32;
|
||||
[[location(1)]] var<in> var_b : f32;
|
||||
[[builtin(vertex_index)]] var<in> custom_vertex_index : u32;
|
||||
[[builtin(instance_index)]] var<in> custom_instance_index : u32;
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn main() -> [[builtin(position)]] vec4<f32> {
|
||||
return vec4<f32>();
|
||||
}
|
||||
)";
|
||||
|
||||
auto* expect = R"(
|
||||
[[block]]
|
||||
struct TintVertexData {
|
||||
tint_vertex_data : [[stride(4)]] array<u32>;
|
||||
};
|
||||
|
||||
[[binding(0), group(4)]] var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
|
||||
|
||||
[[binding(1), group(4)]] var<storage, read> tint_pulling_vertex_buffer_1 : TintVertexData;
|
||||
|
||||
var<private> var_a : f32;
|
||||
|
||||
var<private> var_b : f32;
|
||||
|
||||
[[builtin(vertex_index)]] var<in> custom_vertex_index : u32;
|
||||
|
||||
[[builtin(instance_index)]] var<in> custom_instance_index : u32;
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn main() -> [[builtin(position)]] vec4<f32> {
|
||||
{
|
||||
var tint_pulling_pos : u32;
|
||||
tint_pulling_pos = ((custom_vertex_index * 4u) + 0u);
|
||||
var_a = bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(tint_pulling_pos / 4u)]);
|
||||
tint_pulling_pos = ((custom_instance_index * 4u) + 0u);
|
||||
var_b = bitcast<f32>(tint_pulling_vertex_buffer_1.tint_vertex_data[(tint_pulling_pos / 4u)]);
|
||||
}
|
||||
return vec4<f32>();
|
||||
}
|
||||
)";
|
||||
|
||||
VertexPulling::Config cfg;
|
||||
cfg.vertex_state = {{
|
||||
{
|
||||
4,
|
||||
InputStepMode::kVertex,
|
||||
{{VertexFormat::kF32, 0, 0}},
|
||||
},
|
||||
{
|
||||
4,
|
||||
InputStepMode::kInstance,
|
||||
{{VertexFormat::kF32, 0, 1}},
|
||||
},
|
||||
}};
|
||||
cfg.entry_point_name = "main";
|
||||
|
||||
DataMap data;
|
||||
data.Add<VertexPulling::Config>(cfg);
|
||||
auto got = Run<VertexPulling>(src, data);
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
// TODO(crbug.com/tint/697): Remove this.
|
||||
TEST_F(VertexPullingTest, TwoAttributesSameBuffer_Legacy) {
|
||||
auto* src = R"(
|
||||
[[location(0)]] var<in> var_a : f32;
|
||||
[[location(1)]] var<in> var_b : vec4<f32>;
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn main() -> [[builtin(position)]] vec4<f32> {
|
||||
return vec4<f32>();
|
||||
}
|
||||
)";
|
||||
|
||||
auto* expect = R"(
|
||||
[[builtin(vertex_index)]] var<in> tint_pulling_vertex_index : u32;
|
||||
|
||||
[[block]]
|
||||
struct TintVertexData {
|
||||
tint_vertex_data : [[stride(4)]] array<u32>;
|
||||
};
|
||||
|
||||
[[binding(0), group(4)]] var<storage, read> tint_pulling_vertex_buffer_0 : TintVertexData;
|
||||
|
||||
var<private> var_a : f32;
|
||||
|
||||
var<private> var_b : vec4<f32>;
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn main() -> [[builtin(position)]] vec4<f32> {
|
||||
{
|
||||
var tint_pulling_pos : u32;
|
||||
tint_pulling_pos = ((tint_pulling_vertex_index * 16u) + 0u);
|
||||
var_a = bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(tint_pulling_pos / 4u)]);
|
||||
tint_pulling_pos = ((tint_pulling_vertex_index * 16u) + 0u);
|
||||
var_b = vec4<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[((tint_pulling_pos + 0u) / 4u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[((tint_pulling_pos + 4u) / 4u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[((tint_pulling_pos + 8u) / 4u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[((tint_pulling_pos + 12u) / 4u)]));
|
||||
}
|
||||
return vec4<f32>();
|
||||
}
|
||||
)";
|
||||
|
||||
VertexPulling::Config cfg;
|
||||
cfg.vertex_state = {
|
||||
{{16,
|
||||
InputStepMode::kVertex,
|
||||
{{VertexFormat::kF32, 0, 0}, {VertexFormat::kVec4F32, 0, 1}}}}};
|
||||
cfg.entry_point_name = "main";
|
||||
|
||||
DataMap data;
|
||||
data.Add<VertexPulling::Config>(cfg);
|
||||
auto got = Run<VertexPulling>(src, data);
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace transform
|
||||
} // namespace tint
|
||||
|
|
Loading…
Reference in New Issue