mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-07-06 05:06:07 +00:00
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,16 +996,16 @@ 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"
|
||||
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"
|
||||
EXPECT("var i : ptr<private u32>;",
|
||||
"test.wgsl:1:21 error: expected ',' for ptr declaration\n"
|
||||
"var i : ptr<private u32>;\n"
|
||||
" ^^^\n");
|
||||
}
|
||||
|
||||
@ -1017,9 +1017,9 @@ 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"
|
||||
EXPECT("var i : ptr<private, 1>;",
|
||||
"test.wgsl:1:22 error: invalid type for ptr declaration\n"
|
||||
"var i : ptr<private, 1>;\n"
|
||||
" ^\n");
|
||||
}
|
||||
|
||||
@ -1045,9 +1045,9 @@ 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"
|
||||
EXPECT("var<private i : i32",
|
||||
"test.wgsl:1:13 error: expected '>' for variable declaration\n"
|
||||
"var<private i : i32\n"
|
||||
" ^\n");
|
||||
}
|
||||
|
||||
|
@ -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…
x
Reference in New Issue
Block a user