Remove EntryPoint.
This CL removes the EntryPoint node and transitions everything to the
stage decoration.
Change-Id: Ib2840155905c8fa60ff35870f0c4b6705efb73ff
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/28705
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: David Neto <dneto@google.com>
Reviewed-by: Sarah Mashayekhi <sarahmashay@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index 37366c1..084ee6f 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -255,8 +255,6 @@
"src/ast/discard_statement.h",
"src/ast/else_statement.cc",
"src/ast/else_statement.h",
- "src/ast/entry_point.cc",
- "src/ast/entry_point.h",
"src/ast/expression.cc",
"src/ast/expression.h",
"src/ast/fallthrough_statement.cc",
@@ -706,7 +704,6 @@
"src/ast/decorated_variable_test.cc",
"src/ast/discard_statement_test.cc",
"src/ast/else_statement_test.cc",
- "src/ast/entry_point_test.cc",
"src/ast/expression_test.cc",
"src/ast/fallthrough_statement_test.cc",
"src/ast/float_literal_test.cc",
@@ -840,7 +837,6 @@
"src/writer/spirv/builder_cast_expression_test.cc",
"src/writer/spirv/builder_constructor_expression_test.cc",
"src/writer/spirv/builder_discard_test.cc",
- "src/writer/spirv/builder_entry_point_test.cc",
"src/writer/spirv/builder_format_conversion_test.cc",
"src/writer/spirv/builder_function_decoration_test.cc",
"src/writer/spirv/builder_function_test.cc",
@@ -899,7 +895,6 @@
"src/reader/wgsl/parser_impl_depth_texture_type_test.cc",
"src/reader/wgsl/parser_impl_else_stmt_test.cc",
"src/reader/wgsl/parser_impl_elseif_stmt_test.cc",
- "src/reader/wgsl/parser_impl_entry_point_decl_test.cc",
"src/reader/wgsl/parser_impl_equality_expression_test.cc",
"src/reader/wgsl/parser_impl_exclusive_or_expression_test.cc",
"src/reader/wgsl/parser_impl_for_stmt_test.cc",
@@ -992,7 +987,6 @@
"src/writer/wgsl/generator_impl_constructor_test.cc",
"src/writer/wgsl/generator_impl_continue_test.cc",
"src/writer/wgsl/generator_impl_discard_test.cc",
- "src/writer/wgsl/generator_impl_entry_point_test.cc",
"src/writer/wgsl/generator_impl_fallthrough_test.cc",
"src/writer/wgsl/generator_impl_function_test.cc",
"src/writer/wgsl/generator_impl_identifier_test.cc",
@@ -1043,7 +1037,6 @@
"src/writer/msl/generator_impl_constructor_test.cc",
"src/writer/msl/generator_impl_continue_test.cc",
"src/writer/msl/generator_impl_discard_test.cc",
- "src/writer/msl/generator_impl_entry_point_test.cc",
"src/writer/msl/generator_impl_function_entry_point_data_test.cc",
"src/writer/msl/generator_impl_function_test.cc",
"src/writer/msl/generator_impl_identifier_test.cc",
@@ -1096,7 +1089,6 @@
"src/writer/hlsl/generator_impl_constructor_test.cc",
"src/writer/hlsl/generator_impl_continue_test.cc",
"src/writer/hlsl/generator_impl_discard_test.cc",
- "src/writer/hlsl/generator_impl_entry_point_test.cc",
"src/writer/hlsl/generator_impl_function_entry_point_data_test.cc",
"src/writer/hlsl/generator_impl_function_test.cc",
"src/writer/hlsl/generator_impl_identifier_test.cc",
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 213cc99..15c84cd 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -76,8 +76,6 @@
ast/discard_statement.h
ast/else_statement.cc
ast/else_statement.h
- ast/entry_point.cc
- ast/entry_point.h
ast/expression.cc
ast/expression.h
ast/fallthrough_statement.cc
@@ -315,7 +313,6 @@
ast/discard_statement_test.cc
ast/decorated_variable_test.cc
ast/else_statement_test.cc
- ast/entry_point_test.cc
ast/expression_test.cc
ast/fallthrough_statement_test.cc
ast/float_literal_test.cc
@@ -429,7 +426,6 @@
reader/wgsl/parser_impl_depth_texture_type_test.cc
reader/wgsl/parser_impl_else_stmt_test.cc
reader/wgsl/parser_impl_elseif_stmt_test.cc
- reader/wgsl/parser_impl_entry_point_decl_test.cc
reader/wgsl/parser_impl_equality_expression_test.cc
reader/wgsl/parser_impl_exclusive_or_expression_test.cc
reader/wgsl/parser_impl_for_stmt_test.cc
@@ -500,7 +496,6 @@
writer/spirv/builder_cast_expression_test.cc
writer/spirv/builder_constructor_expression_test.cc
writer/spirv/builder_discard_test.cc
- writer/spirv/builder_entry_point_test.cc
writer/spirv/builder_format_conversion_test.cc
writer/spirv/builder_function_decoration_test.cc
writer/spirv/builder_function_test.cc
@@ -539,7 +534,6 @@
writer/wgsl/generator_impl_constructor_test.cc
writer/wgsl/generator_impl_continue_test.cc
writer/wgsl/generator_impl_discard_test.cc
- writer/wgsl/generator_impl_entry_point_test.cc
writer/wgsl/generator_impl_fallthrough_test.cc
writer/wgsl/generator_impl_function_test.cc
writer/wgsl/generator_impl_identifier_test.cc
@@ -571,7 +565,6 @@
writer/msl/generator_impl_constructor_test.cc
writer/msl/generator_impl_continue_test.cc
writer/msl/generator_impl_discard_test.cc
- writer/msl/generator_impl_entry_point_test.cc
writer/msl/generator_impl_function_entry_point_data_test.cc
writer/msl/generator_impl_function_test.cc
writer/msl/generator_impl_identifier_test.cc
@@ -606,7 +599,6 @@
writer/hlsl/generator_impl_constructor_test.cc
writer/hlsl/generator_impl_continue_test.cc
writer/hlsl/generator_impl_discard_test.cc
- writer/hlsl/generator_impl_entry_point_test.cc
writer/hlsl/generator_impl_function_entry_point_data_test.cc
writer/hlsl/generator_impl_function_test.cc
writer/hlsl/generator_impl_identifier_test.cc
diff --git a/src/ast/entry_point.cc b/src/ast/entry_point.cc
deleted file mode 100644
index 69a4493..0000000
--- a/src/ast/entry_point.cc
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2020 The Tint Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/ast/entry_point.h"
-
-namespace tint {
-namespace ast {
-
-EntryPoint::EntryPoint(PipelineStage stage,
- const std::string& name,
- const std::string& fn_name)
- : Node(), stage_(stage), name_(name), fn_name_(fn_name) {}
-
-EntryPoint::EntryPoint(const Source& source,
- PipelineStage stage,
- const std::string& name,
- const std::string& fn_name)
- : Node(source), stage_(stage), name_(name), fn_name_(fn_name) {}
-
-EntryPoint::~EntryPoint() = default;
-
-bool EntryPoint::IsValid() const {
- if (stage_ == PipelineStage::kNone) {
- return false;
- }
- if (fn_name_.length() == 0) {
- return false;
- }
- return true;
-}
-
-void EntryPoint::to_str(std::ostream& out, size_t indent) const {
- make_indent(out, indent);
- out << "EntryPoint{" << stage_;
- if (name_.length() > 0)
- out << " as " << name_;
-
- out << " = " << fn_name_ << "}" << std::endl;
-}
-
-} // namespace ast
-} // namespace tint
diff --git a/src/ast/entry_point.h b/src/ast/entry_point.h
deleted file mode 100644
index 3b4086e..0000000
--- a/src/ast/entry_point.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2020 The Tint Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef SRC_AST_ENTRY_POINT_H_
-#define SRC_AST_ENTRY_POINT_H_
-
-#include <memory>
-#include <ostream>
-#include <string>
-#include <vector>
-
-#include "src/ast/node.h"
-#include "src/ast/pipeline_stage.h"
-
-namespace tint {
-namespace ast {
-
-/// An entry point statement.
-class EntryPoint : public Node {
- public:
- /// Constructor
- EntryPoint() = default;
- /// Constructor
- /// @param stage the entry point stage
- /// @param name the entry point name
- /// @param fn_name the function name
- EntryPoint(PipelineStage stage,
- const std::string& name,
- const std::string& fn_name);
- /// Constructor
- /// @param source the source of the entry point
- /// @param stage the entry point stage
- /// @param name the entry point name
- /// @param fn_name the function name
- EntryPoint(const Source& source,
- PipelineStage stage,
- const std::string& name,
- const std::string& fn_name);
- /// Move constructor
- EntryPoint(EntryPoint&&) = default;
-
- ~EntryPoint() override;
-
- /// Sets the entry point name
- /// @param name the name to set
- void set_name(const std::string& name) { name_ = name; }
- /// @returns the entry points name
- const std::string& name() const { return name_; }
- /// Sets the entry point function name
- /// @param name the function name
- void set_function_name(const std::string& name) { fn_name_ = name; }
- /// @returns the function name for the entry point
- const std::string& function_name() const { return fn_name_; }
- /// Sets the piepline stage
- /// @param stage the stage to set
- void set_pipeline_stage(PipelineStage stage) { stage_ = stage; }
- /// @returns the pipeline stage for the entry point
- PipelineStage stage() const { return stage_; }
-
- /// @returns true if the entry point is valid
- bool IsValid() const override;
-
- /// Writes a representation of the entry point to the output stream
- /// @param out the stream to write too
- /// @param indent number of spaces to ident the node when writing
- void to_str(std::ostream& out, size_t indent) const override;
-
- private:
- EntryPoint(const EntryPoint&) = delete;
-
- Source source_;
- PipelineStage stage_;
- std::string name_;
- std::string fn_name_;
-};
-
-/// A list of unique entry points.
-using EntryPointList = std::vector<std::unique_ptr<EntryPoint>>;
-
-} // namespace ast
-} // namespace tint
-
-#endif // SRC_AST_ENTRY_POINT_H_
diff --git a/src/ast/entry_point_test.cc b/src/ast/entry_point_test.cc
deleted file mode 100644
index 0f34fb9..0000000
--- a/src/ast/entry_point_test.cc
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2020 The Tint Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/ast/entry_point.h"
-
-#include <sstream>
-
-#include "gtest/gtest.h"
-
-namespace tint {
-namespace ast {
-namespace {
-
-using EntryPointTest = testing::Test;
-
-TEST_F(EntryPointTest, Creation) {
- EntryPoint e(PipelineStage::kVertex, "main", "vtx_main");
-
- EXPECT_EQ(e.name(), "main");
- EXPECT_EQ(e.function_name(), "vtx_main");
- EXPECT_EQ(e.stage(), PipelineStage::kVertex);
- EXPECT_EQ(e.line(), 0u);
- EXPECT_EQ(e.column(), 0u);
-}
-
-TEST_F(EntryPointTest, CreationWithSource) {
- Source s{27, 4};
- EntryPoint e(s, PipelineStage::kVertex, "main", "vtx_main");
-
- EXPECT_EQ(e.name(), "main");
- EXPECT_EQ(e.function_name(), "vtx_main");
- EXPECT_EQ(e.stage(), PipelineStage::kVertex);
- EXPECT_EQ(e.line(), 27u);
- EXPECT_EQ(e.column(), 4u);
-}
-
-TEST_F(EntryPointTest, CreationEmpty) {
- Source s{27, 4};
- EntryPoint e;
- e.set_source(s);
- e.set_pipeline_stage(PipelineStage::kFragment);
- e.set_function_name("my_func");
- e.set_name("a_name");
-
- EXPECT_EQ(e.function_name(), "my_func");
- EXPECT_EQ(e.name(), "a_name");
- EXPECT_EQ(e.stage(), PipelineStage::kFragment);
- EXPECT_EQ(e.line(), 27u);
- EXPECT_EQ(e.column(), 4u);
-}
-
-TEST_F(EntryPointTest, IsValid) {
- EntryPoint e(PipelineStage::kVertex, "", "vtx_main");
- EXPECT_TRUE(e.IsValid());
-}
-
-TEST_F(EntryPointTest, IsValid_MissingFunctionName) {
- EntryPoint e(PipelineStage::kVertex, "main", "");
- EXPECT_FALSE(e.IsValid());
-}
-
-TEST_F(EntryPointTest, IsValid_MissingStage) {
- EntryPoint e(PipelineStage::kNone, "main", "fn");
- EXPECT_FALSE(e.IsValid());
-}
-
-TEST_F(EntryPointTest, IsValid_MissingBoth) {
- EntryPoint e;
- EXPECT_FALSE(e.IsValid());
-}
-
-TEST_F(EntryPointTest, ToStr) {
- EntryPoint e(PipelineStage::kVertex, "text", "vtx_main");
- std::ostringstream out;
- e.to_str(out, 2);
- EXPECT_EQ(out.str(), R"( EntryPoint{vertex as text = vtx_main}
-)");
-}
-
-TEST_F(EntryPointTest, ToStr_NoName) {
- EntryPoint e(PipelineStage::kVertex, "", "vtx_main");
- std::ostringstream out;
- e.to_str(out, 2);
- EXPECT_EQ(out.str(), R"( EntryPoint{vertex = vtx_main}
-)");
-}
-
-} // namespace
-} // namespace ast
-} // namespace tint
diff --git a/src/ast/module.cc b/src/ast/module.cc
index ffb4132..b650a78 100644
--- a/src/ast/module.cc
+++ b/src/ast/module.cc
@@ -45,12 +45,14 @@
return nullptr;
}
-bool Module::IsFunctionEntryPoint(const std::string& name) const {
- for (const auto& ep : entry_points_) {
- if (ep->function_name() == name)
- return true;
+Function* Module::FindFunctionByNameAndStage(const std::string& name,
+ ast::PipelineStage stage) const {
+ for (const auto& func : functions_) {
+ if (func->name() == name && func->pipeline_stage() == stage) {
+ return func.get();
+ }
}
- return false;
+ return nullptr;
}
bool Module::IsValid() const {
@@ -64,11 +66,6 @@
return false;
}
}
- for (const auto& ep : entry_points_) {
- if (ep == nullptr || !ep->IsValid()) {
- return false;
- }
- }
for (auto* const alias : alias_types_) {
if (alias == nullptr) {
return false;
@@ -93,9 +90,6 @@
for (const auto& var : global_variables_) {
var->to_str(out, indent);
}
- for (const auto& ep : entry_points_) {
- ep->to_str(out, indent);
- }
for (auto* const alias : alias_types_) {
for (size_t i = 0; i < indent; ++i) {
out << " ";
diff --git a/src/ast/module.h b/src/ast/module.h
index 7734026..cb8f13a 100644
--- a/src/ast/module.h
+++ b/src/ast/module.h
@@ -20,7 +20,6 @@
#include <utility>
#include <vector>
-#include "src/ast/entry_point.h"
#include "src/ast/function.h"
#include "src/ast/import.h"
#include "src/ast/type/alias_type.h"
@@ -60,19 +59,6 @@
/// @returns the global variables for the module
VariableList& global_variables() { return global_variables_; }
- /// Adds an entry point to the module
- /// @param ep the entry point to add
- void AddEntryPoint(std::unique_ptr<EntryPoint> ep) {
- entry_points_.push_back(std::move(ep));
- }
- /// @returns the entry points in the module
- const EntryPointList& entry_points() const { return entry_points_; }
-
- /// Checks if the given function name is an entry point function
- /// @param name the function name
- /// @returns true if name is an entry point function
- bool IsFunctionEntryPoint(const std::string& name) const;
-
/// Adds a type alias to the module
/// @param type the alias to add
void AddAliasType(type::AliasType* type) { alias_types_.push_back(type); }
@@ -92,6 +78,12 @@
/// @param name the name to search for
/// @returns the associated function or nullptr if none exists
Function* FindFunctionByName(const std::string& name) const;
+ /// Returns the function with the given name
+ /// @param name the name to search for
+ /// @param stage the pipeline stage
+ /// @returns the associated function or nullptr if none exists
+ Function* FindFunctionByNameAndStage(const std::string& name,
+ ast::PipelineStage stage) const;
/// @returns true if all required fields in the AST are present.
bool IsValid() const;
@@ -104,7 +96,6 @@
ImportList imports_;
VariableList global_variables_;
- EntryPointList entry_points_;
// The alias types are owned by the type manager
std::vector<type::AliasType*> alias_types_;
FunctionList functions_;
diff --git a/src/ast/module_test.cc b/src/ast/module_test.cc
index 4cd0ebb..e1cec96 100644
--- a/src/ast/module_test.cc
+++ b/src/ast/module_test.cc
@@ -18,7 +18,6 @@
#include <utility>
#include "gmock/gmock.h"
-#include "src/ast/entry_point.h"
#include "src/ast/function.h"
#include "src/ast/import.h"
#include "src/ast/type/f32_type.h"
@@ -91,19 +90,6 @@
EXPECT_EQ(func_ptr, m.FindFunctionByName("main"));
}
-TEST_F(ModuleTest, IsEntryPoint) {
- type::F32Type f32;
- Module m;
-
- auto func = std::make_unique<Function>("other_func", VariableList{}, &f32);
- m.AddFunction(std::move(func));
-
- m.AddEntryPoint(
- std::make_unique<EntryPoint>(PipelineStage::kVertex, "main", "vtx_main"));
- EXPECT_TRUE(m.IsFunctionEntryPoint("vtx_main"));
- EXPECT_FALSE(m.IsFunctionEntryPoint("other_func"));
-}
-
TEST_F(ModuleTest, LookupFunctionMissing) {
Module m;
EXPECT_EQ(nullptr, m.FindFunctionByName("Missing"));
@@ -155,25 +141,6 @@
EXPECT_FALSE(m.IsValid());
}
-TEST_F(ModuleTest, IsValid_EntryPoint) {
- Module m;
- m.AddEntryPoint(
- std::make_unique<EntryPoint>(PipelineStage::kVertex, "main", "vtx_main"));
- EXPECT_TRUE(m.IsValid());
-}
-
-TEST_F(ModuleTest, IsValid_Null_EntryPoint) {
- Module m;
- m.AddEntryPoint(nullptr);
- EXPECT_FALSE(m.IsValid());
-}
-
-TEST_F(ModuleTest, IsValid_Invalid_EntryPoint) {
- Module m;
- m.AddEntryPoint(std::make_unique<EntryPoint>());
- EXPECT_FALSE(m.IsValid());
-}
-
TEST_F(ModuleTest, IsValid_Alias) {
type::F32Type f32;
type::AliasType alias("alias", &f32);
diff --git a/src/ast/transform/vertex_pulling_transform.cc b/src/ast/transform/vertex_pulling_transform.cc
index 9f2fe3d..69b9f43 100644
--- a/src/ast/transform/vertex_pulling_transform.cc
+++ b/src/ast/transform/vertex_pulling_transform.cc
@@ -77,29 +77,15 @@
}
// Find entry point
- EntryPoint* entry_point = nullptr;
- for (const auto& entry : mod_->entry_points()) {
- if (entry->name() == entry_point_name_ ||
- (entry->name().empty() &&
- entry->function_name() == entry_point_name_)) {
- entry_point = entry.get();
- break;
- }
- }
-
- if (entry_point == nullptr) {
+ auto* func = mod_->FindFunctionByNameAndStage(entry_point_name_,
+ PipelineStage::kVertex);
+ if (func == nullptr) {
SetError("Vertex stage entry point not found");
return false;
}
- // Check entry point is the right stage
- if (entry_point->stage() != PipelineStage::kVertex) {
- SetError("Entry point is not for vertex stage");
- return false;
- }
-
// Save the vertex function
- auto* vertex_func = mod_->FindFunctionByName(entry_point->function_name());
+ auto* vertex_func = mod_->FindFunctionByName(func->name());
// TODO(idanr): Need to check shader locations in descriptor cover all
// attributes
diff --git a/src/ast/transform/vertex_pulling_transform_test.cc b/src/ast/transform/vertex_pulling_transform_test.cc
index 070a4c4..caf4e4a 100644
--- a/src/ast/transform/vertex_pulling_transform_test.cc
+++ b/src/ast/transform/vertex_pulling_transform_test.cc
@@ -17,6 +17,8 @@
#include "gtest/gtest.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/function.h"
+#include "src/ast/pipeline_stage.h"
+#include "src/ast/stage_decoration.h"
#include "src/ast/type/array_type.h"
#include "src/ast/type/f32_type.h"
#include "src/ast/type/i32_type.h"
@@ -38,11 +40,12 @@
// Create basic module with an entry point and vertex function
void InitBasicModule() {
- mod()->AddEntryPoint(std::make_unique<EntryPoint>(PipelineStage::kVertex,
- "main", "vtx_main"));
- mod()->AddFunction(std::make_unique<Function>(
- "vtx_main", VariableList{},
- ctx_.type_mgr().Get(std::make_unique<type::VoidType>())));
+ auto func = std::make_unique<Function>(
+ "main", VariableList{},
+ ctx_.type_mgr().Get(std::make_unique<type::VoidType>()));
+ func->add_decoration(
+ std::make_unique<ast::StageDecoration>(ast::PipelineStage ::kVertex));
+ mod()->AddFunction(std::move(func));
}
// Set up the transformation, after building the module
@@ -71,6 +74,7 @@
mod_->AddGlobalVariable(std::move(var));
}
+ Context* ctx() { return &ctx_; }
ast::Module* mod() { return mod_.get(); }
VertexPullingTransform* transform() { return transform_.get(); }
@@ -104,12 +108,16 @@
}
TEST_F(VertexPullingTransformTest, Error_EntryPointWrongStage) {
- InitBasicModule();
- mod()->entry_points()[0]->set_pipeline_stage(PipelineStage::kFragment);
+ auto func = std::make_unique<Function>(
+ "main", VariableList{},
+ ctx()->type_mgr().Get(std::make_unique<type::VoidType>()));
+ func->add_decoration(
+ std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+ mod()->AddFunction(std::move(func));
InitTransform({});
EXPECT_FALSE(transform()->Run());
- EXPECT_EQ(transform()->GetError(), "Entry point is not for vertex stage");
+ EXPECT_EQ(transform()->GetError(), "Vertex stage entry point not found");
}
TEST_F(VertexPullingTransformTest, BasicModule) {
@@ -118,14 +126,6 @@
EXPECT_TRUE(transform()->Run());
}
-TEST_F(VertexPullingTransformTest, EntryPointUsingFunctionName) {
- InitBasicModule();
- mod()->entry_points()[0]->set_name("");
- InitTransform({});
- transform()->SetEntryPoint("vtx_main");
- EXPECT_TRUE(transform()->Run());
-}
-
TEST_F(VertexPullingTransformTest, OneAttribute) {
InitBasicModule();
@@ -159,8 +159,8 @@
storage_buffer
__struct_
}
- EntryPoint{vertex as main = vtx_main}
- Function vtx_main -> __void
+ Function main -> __void
+ StageDecoration{vertex}
()
{
Block{
@@ -240,8 +240,8 @@
storage_buffer
__struct_
}
- EntryPoint{vertex as main = vtx_main}
- Function vtx_main -> __void
+ Function main -> __void
+ StageDecoration{vertex}
()
{
Block{
@@ -321,8 +321,8 @@
storage_buffer
__struct_
}
- EntryPoint{vertex as main = vtx_main}
- Function vtx_main -> __void
+ Function main -> __void
+ StageDecoration{vertex}
()
{
Block{
@@ -454,8 +454,8 @@
storage_buffer
__struct_
}
- EntryPoint{vertex as main = vtx_main}
- Function vtx_main -> __void
+ Function main -> __void
+ StageDecoration{vertex}
()
{
Block{
@@ -573,8 +573,8 @@
storage_buffer
__struct_
}
- EntryPoint{vertex as main = vtx_main}
- Function vtx_main -> __void
+ Function main -> __void
+ StageDecoration{vertex}
()
{
Block{
@@ -777,8 +777,8 @@
storage_buffer
__struct_
}
- EntryPoint{vertex as main = vtx_main}
- Function vtx_main -> __void
+ Function main -> __void
+ StageDecoration{vertex}
()
{
Block{
diff --git a/src/reader/wgsl/lexer.cc b/src/reader/wgsl/lexer.cc
index 9a825b2..76d71e5 100644
--- a/src/reader/wgsl/lexer.cc
+++ b/src/reader/wgsl/lexer.cc
@@ -503,8 +503,6 @@
return {Token::Type::kElse, source, "else"};
if (str == "elseif")
return {Token::Type::kElseIf, source, "elseif"};
- if (str == "entry_point")
- return {Token::Type::kEntryPoint, source, "entry_point"};
if (str == "f32")
return {Token::Type::kF32, source, "f32"};
if (str == "fallthrough")
diff --git a/src/reader/wgsl/lexer_test.cc b/src/reader/wgsl/lexer_test.cc
index 0254824..1e90cdb 100644
--- a/src/reader/wgsl/lexer_test.cc
+++ b/src/reader/wgsl/lexer_test.cc
@@ -429,7 +429,6 @@
TokenData{"discard", Token::Type::kDiscard},
TokenData{"else", Token::Type::kElse},
TokenData{"elseif", Token::Type::kElseIf},
- TokenData{"entry_point", Token::Type::kEntryPoint},
TokenData{"f32", Token::Type::kF32},
TokenData{"fallthrough", Token::Type::kFallthrough},
TokenData{"false", Token::Type::kFalse},
diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc
index cff1b50..6a41627 100644
--- a/src/reader/wgsl/parser_impl.cc
+++ b/src/reader/wgsl/parser_impl.cc
@@ -206,7 +206,6 @@
// | import_decl SEMICOLON
// | global_variable_decl SEMICLON
// | global_constant_decl SEMICOLON
-// | entry_point_decl SEMICOLON
// | type_alias SEMICOLON
// | function_decl
void ParserImpl::global_decl() {
@@ -258,19 +257,6 @@
return;
}
- auto ep = entry_point_decl();
- if (has_error())
- return;
- if (ep != nullptr) {
- t = next();
- if (!t.IsSemicolon()) {
- set_error(t, "missing ';' for entry point");
- return;
- }
- module_.AddEntryPoint(std::move(ep));
- return;
- }
-
auto* ta = type_alias();
if (has_error())
return;
@@ -2036,60 +2022,6 @@
return ret;
}
-// entry_point_decl
-// : ENTRY_POINT pipeline_stage EQUAL IDENT
-// | ENTRY_POINT pipeline_stage AS STRING_LITERAL EQUAL IDENT
-// | ENTRY_POINT pipeline_stage AS IDENT EQUAL IDENT
-std::unique_ptr<ast::EntryPoint> ParserImpl::entry_point_decl() {
- auto t = peek();
- auto source = t.source();
- if (!t.IsEntryPoint())
- return nullptr;
-
- next(); // Consume the peek
-
- auto stage = pipeline_stage();
- if (has_error())
- return nullptr;
- if (stage == ast::PipelineStage::kNone) {
- set_error(peek(), "missing pipeline stage for entry point");
- return nullptr;
- }
-
- t = next();
- std::string name;
- if (t.IsAs()) {
- t = next();
- if (t.IsStringLiteral()) {
- name = t.to_str();
- } else if (t.IsIdentifier()) {
- name = t.to_str();
- } else {
- set_error(t, "invalid name for entry point");
- return nullptr;
- }
- t = next();
- }
-
- if (!t.IsEqual()) {
- set_error(t, "missing = for entry point");
- return nullptr;
- }
-
- t = next();
- if (!t.IsIdentifier()) {
- set_error(t, "invalid function name for entry point");
- return nullptr;
- }
- auto fn_name = t.to_str();
-
- // Set the name to the function name if it isn't provided
- if (name.length() == 0)
- name = fn_name;
-
- return std::make_unique<ast::EntryPoint>(source, stage, name, fn_name);
-}
-
// pipeline_stage
// : VERTEX
// | FRAGMENT
diff --git a/src/reader/wgsl/parser_impl.h b/src/reader/wgsl/parser_impl.h
index 578b4fd..2574958 100644
--- a/src/reader/wgsl/parser_impl.h
+++ b/src/reader/wgsl/parser_impl.h
@@ -27,7 +27,6 @@
#include "src/ast/case_statement.h"
#include "src/ast/constructor_expression.h"
#include "src/ast/else_statement.h"
-#include "src/ast/entry_point.h"
#include "src/ast/function.h"
#include "src/ast/import.h"
#include "src/ast/literal.h"
@@ -222,9 +221,6 @@
/// Parses a `param_list` grammar element
/// @returns the parsed variables
ast::VariableList param_list();
- /// Parses a `entry_point_decl` grammar element
- /// @returns the EntryPoint or nullptr on error
- std::unique_ptr<ast::EntryPoint> entry_point_decl();
/// Parses a `pipeline_stage` grammar element
/// @returns the pipeline stage or PipelineStage::kNone if none matched
ast::PipelineStage pipeline_stage();
diff --git a/src/reader/wgsl/parser_impl_entry_point_decl_test.cc b/src/reader/wgsl/parser_impl_entry_point_decl_test.cc
deleted file mode 100644
index ede75b3..0000000
--- a/src/reader/wgsl/parser_impl_entry_point_decl_test.cc
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2020 The Tint Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "gtest/gtest.h"
-#include "src/ast/variable.h"
-#include "src/reader/wgsl/parser_impl.h"
-#include "src/reader/wgsl/parser_impl_test_helper.h"
-
-namespace tint {
-namespace reader {
-namespace wgsl {
-namespace {
-
-TEST_F(ParserImplTest, EntryPoint_Parses) {
- auto* p = parser("entry_point fragment = main");
- auto e = p->entry_point_decl();
- ASSERT_NE(e, nullptr);
- ASSERT_FALSE(p->has_error());
- EXPECT_EQ(e->stage(), ast::PipelineStage::kFragment);
- EXPECT_EQ(e->name(), "main");
- EXPECT_EQ(e->function_name(), "main");
-}
-
-TEST_F(ParserImplTest, EntryPoint_ParsesWithStringName) {
- auto* p = parser(R"(entry_point vertex as "main" = vtx_main)");
- auto e = p->entry_point_decl();
- ASSERT_NE(e, nullptr);
- ASSERT_FALSE(p->has_error());
- EXPECT_EQ(e->stage(), ast::PipelineStage::kVertex);
- EXPECT_EQ(e->name(), "main");
- EXPECT_EQ(e->function_name(), "vtx_main");
-}
-
-TEST_F(ParserImplTest, EntryPoint_ParsesWithIdentName) {
- auto* p = parser(R"(entry_point vertex as main = vtx_main)");
- auto e = p->entry_point_decl();
- ASSERT_NE(e, nullptr);
- ASSERT_FALSE(p->has_error());
- EXPECT_EQ(e->stage(), ast::PipelineStage::kVertex);
- EXPECT_EQ(e->name(), "main");
- EXPECT_EQ(e->function_name(), "vtx_main");
-}
-
-TEST_F(ParserImplTest, EntryPoint_MissingFnName) {
- auto* p = parser(R"(entry_point vertex as main =)");
- auto e = p->entry_point_decl();
- ASSERT_TRUE(p->has_error());
- ASSERT_EQ(e, nullptr);
- EXPECT_EQ(p->error(), "1:29: invalid function name for entry point");
-}
-
-TEST_F(ParserImplTest, EntryPoint_InvalidFnName) {
- auto* p = parser(R"(entry_point vertex as main = 123)");
- auto e = p->entry_point_decl();
- ASSERT_TRUE(p->has_error());
- ASSERT_EQ(e, nullptr);
- EXPECT_EQ(p->error(), "1:30: invalid function name for entry point");
-}
-
-TEST_F(ParserImplTest, EntryPoint_MissingEqual) {
- auto* p = parser(R"(entry_point vertex as main vtx_main)");
- auto e = p->entry_point_decl();
- ASSERT_TRUE(p->has_error());
- ASSERT_EQ(e, nullptr);
- EXPECT_EQ(p->error(), "1:28: missing = for entry point");
-}
-
-TEST_F(ParserImplTest, EntryPoint_MissingName) {
- auto* p = parser(R"(entry_point vertex as = vtx_main)");
- auto e = p->entry_point_decl();
- ASSERT_TRUE(p->has_error());
- ASSERT_EQ(e, nullptr);
- EXPECT_EQ(p->error(), "1:23: invalid name for entry point");
-}
-
-TEST_F(ParserImplTest, EntryPoint_InvalidName) {
- auto* p = parser(R"(entry_point vertex as 123 = vtx_main)");
- auto e = p->entry_point_decl();
- ASSERT_TRUE(p->has_error());
- ASSERT_EQ(e, nullptr);
- EXPECT_EQ(p->error(), "1:23: invalid name for entry point");
-}
-
-TEST_F(ParserImplTest, EntryPoint_MissingStageWithIdent) {
- auto* p = parser(R"(entry_point as 123 = vtx_main)");
- auto e = p->entry_point_decl();
- ASSERT_TRUE(p->has_error());
- ASSERT_EQ(e, nullptr);
- EXPECT_EQ(p->error(), "1:13: missing pipeline stage for entry point");
-}
-
-TEST_F(ParserImplTest, EntryPoint_MissingStage) {
- auto* p = parser(R"(entry_point = vtx_main)");
- auto e = p->entry_point_decl();
- ASSERT_TRUE(p->has_error());
- ASSERT_EQ(e, nullptr);
- EXPECT_EQ(p->error(), "1:13: missing pipeline stage for entry point");
-}
-
-TEST_F(ParserImplTest, EntryPoint_InvalidStage) {
- auto* p = parser(R"(entry_point invalid = vtx_main)");
- auto e = p->entry_point_decl();
- ASSERT_TRUE(p->has_error());
- ASSERT_EQ(e, nullptr);
- EXPECT_EQ(p->error(), "1:13: missing pipeline stage for entry point");
-}
-
-} // namespace
-} // namespace wgsl
-} // namespace reader
-} // namespace tint
diff --git a/src/reader/wgsl/parser_impl_global_decl_test.cc b/src/reader/wgsl/parser_impl_global_decl_test.cc
index c04735b..432f2e1 100644
--- a/src/reader/wgsl/parser_impl_global_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_global_decl_test.cc
@@ -108,30 +108,6 @@
EXPECT_EQ(p->error(), "1:38: missing ';' for constant declaration");
}
-TEST_F(ParserImplTest, GlobalDecl_EntryPoint) {
- auto* p = parser("entry_point vertex = main;");
- p->global_decl();
- ASSERT_FALSE(p->has_error()) << p->error();
-
- auto m = p->module();
- ASSERT_EQ(m.entry_points().size(), 1u);
- EXPECT_EQ(m.entry_points()[0]->name(), "main");
-}
-
-TEST_F(ParserImplTest, GlobalDecl_EntryPoint_Invalid) {
- auto* p = parser("entry_point main;");
- p->global_decl();
- ASSERT_TRUE(p->has_error());
- EXPECT_EQ(p->error(), "1:13: missing pipeline stage for entry point");
-}
-
-TEST_F(ParserImplTest, GlobalDecl_EntryPoint_MissingSemicolon) {
- auto* p = parser("entry_point vertex = main");
- p->global_decl();
- ASSERT_TRUE(p->has_error());
- EXPECT_EQ(p->error(), "1:26: missing ';' for entry point");
-}
-
TEST_F(ParserImplTest, GlobalDecl_TypeAlias) {
auto* p = parser("type A = i32;");
p->global_decl();
diff --git a/src/reader/wgsl/parser_impl_test.cc b/src/reader/wgsl/parser_impl_test.cc
index 154a33a..7b6a5a0 100644
--- a/src/reader/wgsl/parser_impl_test.cc
+++ b/src/reader/wgsl/parser_impl_test.cc
@@ -34,7 +34,7 @@
[[location(0)]] var<out> gl_FragColor : vec4<f32>;
-entry_point vertex = main;
+[[stage(vertex)]]
fn main() -> void {
gl_FragColor = vec4<f32>(.4, .2, .3, 1);
}
@@ -43,7 +43,6 @@
auto m = p->module();
ASSERT_EQ(1u, m.imports().size());
- ASSERT_EQ(1u, m.entry_points().size());
ASSERT_EQ(1u, m.functions().size());
ASSERT_EQ(1u, m.global_variables().size());
}
diff --git a/src/reader/wgsl/parser_test.cc b/src/reader/wgsl/parser_test.cc
index 767c236..a67751e 100644
--- a/src/reader/wgsl/parser_test.cc
+++ b/src/reader/wgsl/parser_test.cc
@@ -38,7 +38,7 @@
[[location(0)]] var<out> gl_FragColor : vec4<f32>;
-entry_point vertex = main;
+[[stage(vertex)]]
fn main() -> void {
gl_FragColor = vec4<f32>(.4, .2, .3, 1);
}
@@ -47,7 +47,6 @@
auto m = p.module();
ASSERT_EQ(1u, m.imports().size());
- ASSERT_EQ(1u, m.entry_points().size());
ASSERT_EQ(1u, m.functions().size());
ASSERT_EQ(1u, m.global_variables().size());
}
diff --git a/src/reader/wgsl/token.cc b/src/reader/wgsl/token.cc
index a5dbea5..7afd80c 100644
--- a/src/reader/wgsl/token.cc
+++ b/src/reader/wgsl/token.cc
@@ -139,8 +139,6 @@
return "else";
case Token::Type::kElseIf:
return "elseif";
- case Token::Type::kEntryPoint:
- return "entry_point";
case Token::Type::kF32:
return "f32";
case Token::Type::kFallthrough:
diff --git a/src/reader/wgsl/token.h b/src/reader/wgsl/token.h
index 0f5f531..c67ef34 100644
--- a/src/reader/wgsl/token.h
+++ b/src/reader/wgsl/token.h
@@ -150,8 +150,6 @@
kElse,
/// A 'elseif'
kElseIf,
- /// A 'entry_point'
- kEntryPoint,
/// A 'f32'
kF32,
/// A 'fallthrough'
@@ -531,8 +529,6 @@
bool IsElse() const { return type_ == Type::kElse; }
/// @returns true if token is a 'elseif'
bool IsElseIf() const { return type_ == Type::kElseIf; }
- /// @returns true if token is a 'entry_point'
- bool IsEntryPoint() const { return type_ == Type::kEntryPoint; }
/// @returns true if token is a 'f32'
bool IsF32() const { return type_ == Type::kF32; }
/// @returns true if token is a 'fallthrough'
diff --git a/src/type_determiner.cc b/src/type_determiner.cc
index 7e62fcf..7dbfaf1 100644
--- a/src/type_determiner.cc
+++ b/src/type_determiner.cc
@@ -211,14 +211,6 @@
// Walk over the caller to callee information and update functions with which
// entry points call those functions.
- for (const auto& ep : mod_->entry_points()) {
- for (const auto& callee : caller_to_callee_[ep->function_name()]) {
- set_entry_points(callee, ep->name());
- }
- }
-
- // Walk over the caller to callee information and update functions with which
- // entry points call those functions.
for (const auto& func : mod_->functions()) {
if (!func->IsEntryPoint()) {
continue;
diff --git a/src/type_determiner_test.cc b/src/type_determiner_test.cc
index 67821ad..f2ce9d6 100644
--- a/src/type_determiner_test.cc
+++ b/src/type_determiner_test.cc
@@ -4373,114 +4373,6 @@
testing::Values(GLSLData{"sclamp", GLSLstd450SClamp},
GLSLData{"uclamp", GLSLstd450UClamp}));
-TEST_F(TypeDeterminerTest, Function_EntryPoints) {
- ast::type::F32Type f32;
-
- // fn b() {}
- // fn c() { b(); }
- // fn a() { c(); }
- // fn ep_1() { a(); b(); }
- // fn ep_2() { c();}
- //
- // c -> {ep_1, ep_2}
- // a -> {ep_1}
- // b -> {ep_1, ep_2}
- // ep_1 -> {}
- // ep_2 -> {}
-
- ast::VariableList params;
- auto func_b = std::make_unique<ast::Function>("b", std::move(params), &f32);
- auto* func_b_ptr = func_b.get();
-
- auto body = std::make_unique<ast::BlockStatement>();
- func_b->set_body(std::move(body));
-
- auto func_c = std::make_unique<ast::Function>("c", std::move(params), &f32);
- auto* func_c_ptr = func_c.get();
-
- body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("second"),
- std::make_unique<ast::CallExpression>(
- std::make_unique<ast::IdentifierExpression>("b"),
- ast::ExpressionList{})));
- func_c->set_body(std::move(body));
-
- auto func_a = std::make_unique<ast::Function>("a", std::move(params), &f32);
- auto* func_a_ptr = func_a.get();
-
- body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("first"),
- std::make_unique<ast::CallExpression>(
- std::make_unique<ast::IdentifierExpression>("c"),
- ast::ExpressionList{})));
- func_a->set_body(std::move(body));
-
- auto ep_1_func =
- std::make_unique<ast::Function>("ep_1_func", std::move(params), &f32);
- auto* ep_1_func_ptr = ep_1_func.get();
-
- body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("call_a"),
- std::make_unique<ast::CallExpression>(
- std::make_unique<ast::IdentifierExpression>("a"),
- ast::ExpressionList{})));
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("call_b"),
- std::make_unique<ast::CallExpression>(
- std::make_unique<ast::IdentifierExpression>("b"),
- ast::ExpressionList{})));
- ep_1_func->set_body(std::move(body));
-
- auto ep_2_func =
- std::make_unique<ast::Function>("ep_2_func", std::move(params), &f32);
- auto* ep_2_func_ptr = ep_2_func.get();
-
- body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("call_c"),
- std::make_unique<ast::CallExpression>(
- std::make_unique<ast::IdentifierExpression>("c"),
- ast::ExpressionList{})));
- ep_2_func->set_body(std::move(body));
-
- auto ep_1 = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kVertex,
- "ep_1", "ep_1_func");
- auto ep_2 = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kVertex,
- "ep_2", "ep_2_func");
-
- mod()->AddFunction(std::move(func_b));
- mod()->AddFunction(std::move(func_c));
- mod()->AddFunction(std::move(func_a));
- mod()->AddFunction(std::move(ep_1_func));
- mod()->AddFunction(std::move(ep_2_func));
-
- mod()->AddEntryPoint(std::move(ep_1));
- mod()->AddEntryPoint(std::move(ep_2));
-
- // Register the functions and calculate the callers
- ASSERT_TRUE(td()->Determine()) << td()->error();
-
- const auto& b_eps = func_b_ptr->ancestor_entry_points();
- ASSERT_EQ(2u, b_eps.size());
- EXPECT_EQ("ep_1", b_eps[0]);
- EXPECT_EQ("ep_2", b_eps[1]);
-
- const auto& a_eps = func_a_ptr->ancestor_entry_points();
- ASSERT_EQ(1u, a_eps.size());
- EXPECT_EQ("ep_1", a_eps[0]);
-
- const auto& c_eps = func_c_ptr->ancestor_entry_points();
- ASSERT_EQ(2u, c_eps.size());
- EXPECT_EQ("ep_1", c_eps[0]);
- EXPECT_EQ("ep_2", c_eps[1]);
-
- EXPECT_TRUE(ep_1_func_ptr->ancestor_entry_points().empty());
- EXPECT_TRUE(ep_2_func_ptr->ancestor_entry_points().empty());
-}
-
TEST_F(TypeDeterminerTest, Function_EntryPoints_StageDecoration) {
ast::type::F32Type f32;
diff --git a/src/validator_function_test.cc b/src/validator_function_test.cc
index ab827f2..145b345 100644
--- a/src/validator_function_test.cc
+++ b/src/validator_function_test.cc
@@ -17,7 +17,6 @@
#include "gtest/gtest.h"
#include "spirv/unified1/GLSL.std.450.h"
#include "src/ast/call_statement.h"
-#include "src/ast/entry_point.h"
#include "src/ast/pipeline_stage.h"
#include "src/ast/return_statement.h"
#include "src/ast/scalar_constructor_expression.h"
@@ -91,8 +90,7 @@
mod()->AddFunction(std::move(func));
EXPECT_TRUE(td()->DetermineFunctions(mod()->functions())) << td()->error();
- EXPECT_TRUE(v()->ValidateFunctions(mod(), mod()->functions()))
- << v()->error();
+ EXPECT_TRUE(v()->ValidateFunctions(mod()->functions())) << v()->error();
}
TEST_F(ValidateFunctionTest, FunctionTypeMustMatchReturnStatementType_fail) {
diff --git a/src/validator_impl.cc b/src/validator_impl.cc
index e64d9f1..2a8ce16 100644
--- a/src/validator_impl.cc
+++ b/src/validator_impl.cc
@@ -49,7 +49,7 @@
if (!CheckImports(module)) {
return false;
}
- if (!ValidateFunctions(module, module->functions())) {
+ if (!ValidateFunctions(module->functions())) {
return false;
}
@@ -82,8 +82,7 @@
return true;
}
-bool ValidatorImpl::ValidateFunctions(const ast::Module* mod,
- const ast::FunctionList& funcs) {
+bool ValidatorImpl::ValidateFunctions(const ast::FunctionList& funcs) {
ScopeStack<ast::PipelineStage> entry_point_map;
entry_point_map.push_scope();
@@ -135,7 +134,7 @@
current_function_ = nullptr;
}
- if (pipeline_count == 0 && mod->entry_points().empty()) {
+ if (pipeline_count == 0) {
set_error(Source{0, 0},
"v-0003: At least one of vertex, fragment or compute shader must "
"be present");
diff --git a/src/validator_impl.h b/src/validator_impl.h
index 81e46f1..6481292 100644
--- a/src/validator_impl.h
+++ b/src/validator_impl.h
@@ -20,7 +20,6 @@
#include "src/ast/assignment_statement.h"
#include "src/ast/call_expression.h"
-#include "src/ast/entry_point.h"
#include "src/ast/expression.h"
#include "src/ast/identifier_expression.h"
#include "src/ast/module.h"
@@ -58,11 +57,9 @@
/// @returns true if the validation was successful
bool ValidateGlobalVariables(const ast::VariableList& global_vars);
/// Validates Functions
- /// @param mod the module
/// @param funcs the functions to check
/// @returns true if the validation was successful
- bool ValidateFunctions(const ast::Module* mod,
- const ast::FunctionList& funcs);
+ bool ValidateFunctions(const ast::FunctionList& funcs);
/// Validates a function
/// @param func the function to check
/// @returns true if the validation was successful
@@ -112,11 +109,6 @@
/// @param expr the call to validate
/// @returns true if successful
bool ValidateCallExpr(const ast::CallExpression* expr);
- /// Validates entry points
- /// this funtion must be called after populating function_stack_
- /// @param eps the vector of entry points to check
- /// @return true if the validation was successful
- bool ValidateEntryPoints(const ast::EntryPointList& eps);
/// Validates switch statements
/// @param s the switch statement to check
/// @returns true if the valdiation was successful
diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc
index b219595..7fa9229 100644
--- a/src/writer/hlsl/generator_impl.cc
+++ b/src/writer/hlsl/generator_impl.cc
@@ -134,12 +134,6 @@
}
}
- for (const auto& ep : module_->entry_points()) {
- if (!EmitEntryPointData(out, ep.get())) {
- return false;
- }
- }
-
// Make sure all entry point data is emitted before the entry point functions
for (const auto& func : module_->functions()) {
if (!func->IsEntryPoint()) {
@@ -156,12 +150,6 @@
return false;
}
}
- for (const auto& ep : module_->entry_points()) {
- if (!EmitEntryPointFunction(out, ep.get())) {
- return false;
- }
- out << std::endl;
- }
for (const auto& func : module_->functions()) {
if (!func->IsEntryPoint()) {
@@ -1106,7 +1094,7 @@
make_indent(out);
// Entry points will be emitted later, skip for now.
- if (func->IsEntryPoint() || module_->IsFunctionEntryPoint(func->name())) {
+ if (func->IsEntryPoint()) {
return true;
}
@@ -1208,200 +1196,6 @@
return true;
}
-bool GeneratorImpl::EmitEntryPointData(std::ostream& out, ast::EntryPoint* ep) {
- auto* func = module_->FindFunctionByName(ep->function_name());
- if (func == nullptr) {
- error_ = "Unable to find entry point function: " + ep->function_name();
- return false;
- }
-
- std::vector<std::pair<ast::Variable*, ast::VariableDecoration*>> in_variables;
- std::vector<std::pair<ast::Variable*, ast::VariableDecoration*>> outvariables;
- for (auto data : func->referenced_location_variables()) {
- auto* var = data.first;
- auto* deco = data.second;
-
- if (var->storage_class() == ast::StorageClass::kInput) {
- in_variables.push_back({var, deco});
- } else if (var->storage_class() == ast::StorageClass::kOutput) {
- outvariables.push_back({var, deco});
- }
- }
-
- for (auto data : func->referenced_builtin_variables()) {
- auto* var = data.first;
- auto* deco = data.second;
-
- if (var->storage_class() == ast::StorageClass::kInput) {
- in_variables.push_back({var, deco});
- } else if (var->storage_class() == ast::StorageClass::kOutput) {
- outvariables.push_back({var, deco});
- }
- }
-
- bool emitted_uniform = false;
- for (auto data : func->referenced_uniform_variables()) {
- auto* var = data.first;
- // TODO(dsinclair): We're using the binding to make up the buffer number but
- // we should instead be using a provided mapping that uses both buffer and
- // set. https://bugs.chromium.org/p/tint/issues/detail?id=104
- auto* binding = data.second.binding;
- if (binding == nullptr) {
- error_ = "unable to find binding information for uniform: " + var->name();
- return false;
- }
- // auto* set = data.second.set;
-
- auto* type = var->type()->UnwrapAliasesIfNeeded();
- if (type->IsStruct()) {
- auto* strct = type->AsStruct();
-
- out << "ConstantBuffer<" << strct->name() << "> " << var->name()
- << " : register(b" << binding->value() << ");" << std::endl;
- } else {
- // TODO(dsinclair): There is outstanding spec work to require all uniform
- // buffers to be [[block]] decorated, which means structs. This is
- // currently not the case, so this code handles the cases where the data
- // is not a block.
- // Relevant: https://github.com/gpuweb/gpuweb/issues/1004
- // https://github.com/gpuweb/gpuweb/issues/1008
- out << "cbuffer : register(b" << binding->value() << ") {" << std::endl;
-
- increment_indent();
- make_indent(out);
- if (!EmitType(out, type, "")) {
- return false;
- }
- out << " " << var->name() << ";" << std::endl;
- decrement_indent();
- out << "};" << std::endl;
- }
-
- emitted_uniform = true;
- }
- if (emitted_uniform) {
- out << std::endl;
- }
-
- bool emitted_storagebuffer = false;
- for (auto data : func->referenced_storagebuffer_variables()) {
- auto* var = data.first;
- auto* binding = data.second.binding;
-
- out << "RWByteAddressBuffer " << var->name() << " : register(u"
- << binding->value() << ");" << std::endl;
- emitted_storagebuffer = true;
- }
- if (emitted_storagebuffer) {
- out << std::endl;
- }
-
- auto ep_name = ep->name();
- if (ep_name.empty()) {
- ep_name = ep->function_name();
- }
-
- // TODO(dsinclair): There is a potential bug here. Entry points can have the
- // same name in WGSL if they have different pipeline stages. This does not
- // take that into account and will emit duplicate struct names. I'm ignoring
- // this until https://github.com/gpuweb/gpuweb/issues/662 is resolved as it
- // may remove this issue and entry point names will need to be unique.
- if (!in_variables.empty()) {
- auto in_struct_name = generate_name(ep_name + "_" + kInStructNameSuffix);
- auto in_var_name = generate_name(kTintStructInVarPrefix);
- ep_name_to_in_data_[ep_name] = {in_struct_name, in_var_name};
-
- make_indent(out);
- out << "struct " << in_struct_name << " {" << std::endl;
-
- increment_indent();
-
- for (auto& data : in_variables) {
- auto* var = data.first;
- auto* deco = data.second;
-
- make_indent(out);
- if (!EmitType(out, var->type(), var->name())) {
- return false;
- }
-
- out << " " << var->name() << " : ";
- if (deco->IsLocation()) {
- if (ep->stage() == ast::PipelineStage::kCompute) {
- error_ = "invalid location variable for pipeline stage";
- return false;
- }
- out << "TEXCOORD" << deco->AsLocation()->value();
- } else if (deco->IsBuiltin()) {
- auto attr = builtin_to_attribute(deco->AsBuiltin()->value());
- if (attr.empty()) {
- error_ = "unsupported builtin";
- return false;
- }
- out << attr;
- } else {
- error_ = "unsupported variable decoration for entry point output";
- return false;
- }
- out << ";" << std::endl;
- }
- decrement_indent();
- make_indent(out);
-
- out << "};" << std::endl << std::endl;
- }
-
- if (!outvariables.empty()) {
- auto outstruct_name = generate_name(ep_name + "_" + kOutStructNameSuffix);
- auto outvar_name = generate_name(kTintStructOutVarPrefix);
- ep_name_to_out_data_[ep_name] = {outstruct_name, outvar_name};
-
- make_indent(out);
- out << "struct " << outstruct_name << " {" << std::endl;
-
- increment_indent();
- for (auto& data : outvariables) {
- auto* var = data.first;
- auto* deco = data.second;
-
- make_indent(out);
- if (!EmitType(out, var->type(), var->name())) {
- return false;
- }
-
- out << " " << var->name() << " : ";
-
- if (deco->IsLocation()) {
- auto loc = deco->AsLocation()->value();
- if (ep->stage() == ast::PipelineStage::kVertex) {
- out << "TEXCOORD" << loc;
- } else if (ep->stage() == ast::PipelineStage::kFragment) {
- out << "SV_Target" << loc << "";
- } else {
- error_ = "invalid location variable for pipeline stage";
- return false;
- }
- } else if (deco->IsBuiltin()) {
- auto attr = builtin_to_attribute(deco->AsBuiltin()->value());
- if (attr.empty()) {
- error_ = "unsupported builtin";
- return false;
- }
- out << attr;
- } else {
- error_ = "unsupported variable decoration for entry point output";
- return false;
- }
- out << ";" << std::endl;
- }
- decrement_indent();
- make_indent(out);
- out << "};" << std::endl << std::endl;
- }
-
- return true;
-}
-
bool GeneratorImpl::EmitEntryPointData(std::ostream& out, ast::Function* func) {
std::vector<std::pair<ast::Variable*, ast::VariableDecoration*>> in_variables;
std::vector<std::pair<ast::Variable*, ast::VariableDecoration*>> outvariables;
@@ -1609,71 +1403,6 @@
}
bool GeneratorImpl::EmitEntryPointFunction(std::ostream& out,
- ast::EntryPoint* ep) {
- make_indent(out);
-
- current_ep_name_ = ep->name();
- if (current_ep_name_.empty()) {
- current_ep_name_ = ep->function_name();
- }
-
- auto* func = module_->FindFunctionByName(ep->function_name());
- if (func == nullptr) {
- error_ = "unable to find function for entry point: " + ep->function_name();
- return false;
- }
-
- if (ep->stage() == ast::PipelineStage::kCompute) {
- uint32_t x = 0;
- uint32_t y = 0;
- uint32_t z = 0;
- std::tie(x, y, z) = func->workgroup_size();
- out << "[numthreads(" << std::to_string(x) << ", " << std::to_string(y)
- << ", " << std::to_string(z) << ")]" << std::endl;
- make_indent(out);
- }
-
- auto outdata = ep_name_to_out_data_.find(current_ep_name_);
- bool has_outdata = outdata != ep_name_to_out_data_.end();
- if (has_outdata) {
- out << outdata->second.struct_name;
- } else {
- out << "void";
- }
- out << " " << namer_.NameFor(current_ep_name_) << "(";
-
- auto in_data = ep_name_to_in_data_.find(current_ep_name_);
- if (in_data != ep_name_to_in_data_.end()) {
- out << in_data->second.struct_name << " " << in_data->second.var_name;
- }
- out << ") {" << std::endl;
-
- increment_indent();
-
- if (has_outdata) {
- make_indent(out);
- out << outdata->second.struct_name << " " << outdata->second.var_name << ";"
- << std::endl;
- }
-
- generating_entry_point_ = true;
- for (const auto& s : *(func->body())) {
- if (!EmitStatement(out, s.get())) {
- return false;
- }
- }
- generating_entry_point_ = false;
-
- decrement_indent();
- make_indent(out);
- out << "}" << std::endl;
-
- current_ep_name_ = "";
-
- return true;
-}
-
-bool GeneratorImpl::EmitEntryPointFunction(std::ostream& out,
ast::Function* func) {
make_indent(out);
diff --git a/src/writer/hlsl/generator_impl.h b/src/writer/hlsl/generator_impl.h
index 264c119..798bf87 100644
--- a/src/writer/hlsl/generator_impl.h
+++ b/src/writer/hlsl/generator_impl.h
@@ -193,21 +193,11 @@
const std::string& ep_name);
/// Handles emitting information for an entry point
/// @param out the output stream
- /// @param ep the entry point
- /// @returns true if the entry point data was emitted
- bool EmitEntryPointData(std::ostream& out, ast::EntryPoint* ep);
- /// Handles emitting information for an entry point
- /// @param out the output stream
/// @param func the entry point
/// @returns true if the entry point data was emitted
bool EmitEntryPointData(std::ostream& out, ast::Function* func);
/// Handles emitting the entry point function
/// @param out the output stream
- /// @param ep the entry point
- /// @returns true if the entry point function was emitted
- bool EmitEntryPointFunction(std::ostream& out, ast::EntryPoint* ep);
- /// Handles emitting the entry point function
- /// @param out the output stream
/// @param func the entry point
/// @returns true if the entry point function was emitted
bool EmitEntryPointFunction(std::ostream& out, ast::Function* func);
diff --git a/src/writer/hlsl/generator_impl_entry_point_test.cc b/src/writer/hlsl/generator_impl_entry_point_test.cc
deleted file mode 100644
index 184e725..0000000
--- a/src/writer/hlsl/generator_impl_entry_point_test.cc
+++ /dev/null
@@ -1,463 +0,0 @@
-// Copyright 2020 The Tint Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/ast/assignment_statement.h"
-#include "src/ast/decorated_variable.h"
-#include "src/ast/entry_point.h"
-#include "src/ast/identifier_expression.h"
-#include "src/ast/location_decoration.h"
-#include "src/ast/member_accessor_expression.h"
-#include "src/ast/module.h"
-#include "src/ast/return_statement.h"
-#include "src/ast/type/f32_type.h"
-#include "src/ast/type/i32_type.h"
-#include "src/ast/type/vector_type.h"
-#include "src/ast/type/void_type.h"
-#include "src/ast/variable.h"
-#include "src/context.h"
-#include "src/type_determiner.h"
-#include "src/writer/hlsl/test_helper.h"
-
-namespace tint {
-namespace writer {
-namespace hlsl {
-namespace {
-
-using HlslGeneratorImplTest_EntryPoint = TestHelper;
-
-TEST_F(HlslGeneratorImplTest_EntryPoint, EmitEntryPointData_Vertex_Input) {
- // [[location(0)]] var<in> foo : f32;
- // [[location(1)]] var<in> bar : i32;
- //
- // struct vtx_main_in {
- // float foo : TEXCOORD0;
- // int bar : TEXCOORD1;
- // };
-
- ast::type::F32Type f32;
- ast::type::I32Type i32;
-
- auto foo_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
-
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::LocationDecoration>(0));
- foo_var->set_decorations(std::move(decos));
-
- auto bar_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("bar", ast::StorageClass::kInput, &i32));
- decos.push_back(std::make_unique<ast::LocationDecoration>(1));
- bar_var->set_decorations(std::move(decos));
-
- td().RegisterVariableForTesting(foo_var.get());
- td().RegisterVariableForTesting(bar_var.get());
-
- mod()->AddGlobalVariable(std::move(foo_var));
- mod()->AddGlobalVariable(std::move(bar_var));
-
- ast::VariableList params;
- auto func =
- std::make_unique<ast::Function>("vtx_main", std::move(params), &f32);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("foo"),
- std::make_unique<ast::IdentifierExpression>("foo")));
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("bar"),
- std::make_unique<ast::IdentifierExpression>("bar")));
- func->set_body(std::move(body));
-
- mod()->AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kVertex, "",
- "vtx_main");
- auto* ep_ptr = ep.get();
-
- mod()->AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td().Determine()) << td().error();
- ASSERT_TRUE(gen().EmitEntryPointData(out(), ep_ptr)) << gen().error();
- EXPECT_EQ(result(), R"(struct vtx_main_in {
- float foo : TEXCOORD0;
- int bar : TEXCOORD1;
-};
-
-)");
-}
-
-TEST_F(HlslGeneratorImplTest_EntryPoint, EmitEntryPointData_Vertex_Output) {
- // [[location(0)]] var<out> foo : f32;
- // [[location(1)]] var<out> bar : i32;
- //
- // struct vtx_main_out {
- // float foo : TEXCOORD0;
- // int bar : TEXCOORD1;
- // };
-
- ast::type::F32Type f32;
- ast::type::I32Type i32;
-
- auto foo_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("foo", ast::StorageClass::kOutput, &f32));
-
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::LocationDecoration>(0));
- foo_var->set_decorations(std::move(decos));
-
- auto bar_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("bar", ast::StorageClass::kOutput, &i32));
- decos.push_back(std::make_unique<ast::LocationDecoration>(1));
- bar_var->set_decorations(std::move(decos));
-
- td().RegisterVariableForTesting(foo_var.get());
- td().RegisterVariableForTesting(bar_var.get());
-
- mod()->AddGlobalVariable(std::move(foo_var));
- mod()->AddGlobalVariable(std::move(bar_var));
-
- ast::VariableList params;
- auto func =
- std::make_unique<ast::Function>("vtx_main", std::move(params), &f32);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("foo"),
- std::make_unique<ast::IdentifierExpression>("foo")));
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("bar"),
- std::make_unique<ast::IdentifierExpression>("bar")));
- func->set_body(std::move(body));
-
- mod()->AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kVertex, "",
- "vtx_main");
- auto* ep_ptr = ep.get();
-
- mod()->AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td().Determine()) << td().error();
- ASSERT_TRUE(gen().EmitEntryPointData(out(), ep_ptr)) << gen().error();
- EXPECT_EQ(result(), R"(struct vtx_main_out {
- float foo : TEXCOORD0;
- int bar : TEXCOORD1;
-};
-
-)");
-}
-
-TEST_F(HlslGeneratorImplTest_EntryPoint, EmitEntryPointData_Fragment_Input) {
- // [[location(0)]] var<in> foo : f32;
- // [[location(1)]] var<in> bar : i32;
- //
- // struct frag_main_in {
- // float foo : TEXCOORD0;
- // int bar : TEXCOORD1;
- // };
-
- ast::type::F32Type f32;
- ast::type::I32Type i32;
-
- auto foo_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
-
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::LocationDecoration>(0));
- foo_var->set_decorations(std::move(decos));
-
- auto bar_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("bar", ast::StorageClass::kInput, &i32));
- decos.push_back(std::make_unique<ast::LocationDecoration>(1));
- bar_var->set_decorations(std::move(decos));
-
- td().RegisterVariableForTesting(foo_var.get());
- td().RegisterVariableForTesting(bar_var.get());
-
- mod()->AddGlobalVariable(std::move(foo_var));
- mod()->AddGlobalVariable(std::move(bar_var));
-
- ast::VariableList params;
- auto func =
- std::make_unique<ast::Function>("frag_main", std::move(params), &f32);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("foo"),
- std::make_unique<ast::IdentifierExpression>("foo")));
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("bar"),
- std::make_unique<ast::IdentifierExpression>("bar")));
- func->set_body(std::move(body));
-
- mod()->AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment,
- "main", "frag_main");
- auto* ep_ptr = ep.get();
-
- mod()->AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td().Determine()) << td().error();
- ASSERT_TRUE(gen().EmitEntryPointData(out(), ep_ptr)) << gen().error();
- EXPECT_EQ(result(), R"(struct main_in {
- float foo : TEXCOORD0;
- int bar : TEXCOORD1;
-};
-
-)");
-}
-
-TEST_F(HlslGeneratorImplTest_EntryPoint, EmitEntryPointData_Fragment_Output) {
- // [[location(0)]] var<out> foo : f32;
- // [[location(1)]] var<out> bar : i32;
- //
- // struct frag_main_out {
- // float foo : SV_Target0;
- // int bar : SV_Target1;
- // };
-
- ast::type::F32Type f32;
- ast::type::I32Type i32;
-
- auto foo_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("foo", ast::StorageClass::kOutput, &f32));
-
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::LocationDecoration>(0));
- foo_var->set_decorations(std::move(decos));
-
- auto bar_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("bar", ast::StorageClass::kOutput, &i32));
- decos.push_back(std::make_unique<ast::LocationDecoration>(1));
- bar_var->set_decorations(std::move(decos));
-
- td().RegisterVariableForTesting(foo_var.get());
- td().RegisterVariableForTesting(bar_var.get());
-
- mod()->AddGlobalVariable(std::move(foo_var));
- mod()->AddGlobalVariable(std::move(bar_var));
-
- ast::VariableList params;
- auto func =
- std::make_unique<ast::Function>("frag_main", std::move(params), &f32);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("foo"),
- std::make_unique<ast::IdentifierExpression>("foo")));
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("bar"),
- std::make_unique<ast::IdentifierExpression>("bar")));
- func->set_body(std::move(body));
-
- mod()->AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment,
- "main", "frag_main");
- auto* ep_ptr = ep.get();
-
- mod()->AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td().Determine()) << td().error();
- ASSERT_TRUE(gen().EmitEntryPointData(out(), ep_ptr)) << gen().error();
- EXPECT_EQ(result(), R"(struct main_out {
- float foo : SV_Target0;
- int bar : SV_Target1;
-};
-
-)");
-}
-
-TEST_F(HlslGeneratorImplTest_EntryPoint, EmitEntryPointData_Compute_Input) {
- // [[location(0)]] var<in> foo : f32;
- // [[location(1)]] var<in> bar : i32;
- //
- // -> Error, not allowed
-
- ast::type::F32Type f32;
- ast::type::I32Type i32;
-
- auto foo_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
-
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::LocationDecoration>(0));
- foo_var->set_decorations(std::move(decos));
-
- auto bar_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("bar", ast::StorageClass::kInput, &i32));
- decos.push_back(std::make_unique<ast::LocationDecoration>(1));
- bar_var->set_decorations(std::move(decos));
-
- td().RegisterVariableForTesting(foo_var.get());
- td().RegisterVariableForTesting(bar_var.get());
-
- mod()->AddGlobalVariable(std::move(foo_var));
- mod()->AddGlobalVariable(std::move(bar_var));
-
- ast::VariableList params;
- auto func =
- std::make_unique<ast::Function>("comp_main", std::move(params), &f32);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("foo"),
- std::make_unique<ast::IdentifierExpression>("foo")));
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("bar"),
- std::make_unique<ast::IdentifierExpression>("bar")));
- func->set_body(std::move(body));
-
- mod()->AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kCompute,
- "main", "comp_main");
- auto* ep_ptr = ep.get();
-
- mod()->AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td().Determine()) << td().error();
- ASSERT_FALSE(gen().EmitEntryPointData(out(), ep_ptr)) << gen().error();
- EXPECT_EQ(gen().error(), R"(invalid location variable for pipeline stage)");
-}
-
-TEST_F(HlslGeneratorImplTest_EntryPoint, EmitEntryPointData_Compute_Output) {
- // [[location(0)]] var<out> foo : f32;
- // [[location(1)]] var<out> bar : i32;
- //
- // -> Error not allowed
-
- ast::type::F32Type f32;
- ast::type::I32Type i32;
-
- auto foo_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("foo", ast::StorageClass::kOutput, &f32));
-
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::LocationDecoration>(0));
- foo_var->set_decorations(std::move(decos));
-
- auto bar_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("bar", ast::StorageClass::kOutput, &i32));
- decos.push_back(std::make_unique<ast::LocationDecoration>(1));
- bar_var->set_decorations(std::move(decos));
-
- td().RegisterVariableForTesting(foo_var.get());
- td().RegisterVariableForTesting(bar_var.get());
-
- mod()->AddGlobalVariable(std::move(foo_var));
- mod()->AddGlobalVariable(std::move(bar_var));
-
- ast::VariableList params;
- auto func =
- std::make_unique<ast::Function>("comp_main", std::move(params), &f32);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("foo"),
- std::make_unique<ast::IdentifierExpression>("foo")));
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("bar"),
- std::make_unique<ast::IdentifierExpression>("bar")));
- func->set_body(std::move(body));
-
- mod()->AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kCompute,
- "main", "comp_main");
- auto* ep_ptr = ep.get();
-
- mod()->AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td().Determine()) << td().error();
- ASSERT_FALSE(gen().EmitEntryPointData(out(), ep_ptr)) << gen().error();
- EXPECT_EQ(gen().error(), R"(invalid location variable for pipeline stage)");
-}
-
-TEST_F(HlslGeneratorImplTest_EntryPoint, EmitEntryPointData_Builtins) {
- // [[builtin(frag_coord)]] var<in> coord : vec4<f32>;
- // [[builtin(frag_depth)]] var<out> depth : f32;
- //
- // struct main_in {
- // vector<float, 4> coord : SV_Position;
- // };
- //
- // struct main_out {
- // float depth : SV_Depth;
- // };
-
- ast::type::F32Type f32;
- ast::type::VoidType void_type;
- ast::type::VectorType vec4(&f32, 4);
-
- auto coord_var =
- std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
- "coord", ast::StorageClass::kInput, &vec4));
-
- ast::VariableDecorationList decos;
- decos.push_back(
- std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragCoord));
- coord_var->set_decorations(std::move(decos));
-
- auto depth_var =
- std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
- "depth", ast::StorageClass::kOutput, &f32));
- decos.push_back(
- std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragDepth));
- depth_var->set_decorations(std::move(decos));
-
- td().RegisterVariableForTesting(coord_var.get());
- td().RegisterVariableForTesting(depth_var.get());
-
- mod()->AddGlobalVariable(std::move(coord_var));
- mod()->AddGlobalVariable(std::move(depth_var));
-
- ast::VariableList params;
- auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
- &void_type);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("depth"),
- std::make_unique<ast::MemberAccessorExpression>(
- std::make_unique<ast::IdentifierExpression>("coord"),
- std::make_unique<ast::IdentifierExpression>("x"))));
- func->set_body(std::move(body));
-
- mod()->AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment,
- "main", "frag_main");
- auto* ep_ptr = ep.get();
-
- mod()->AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td().Determine()) << td().error();
- ASSERT_TRUE(gen().EmitEntryPointData(out(), ep_ptr)) << gen().error();
- EXPECT_EQ(result(), R"(struct main_in {
- vector<float, 4> coord : SV_Position;
-};
-
-struct main_out {
- float depth : SV_Depth;
-};
-
-)");
-}
-
-} // namespace
-} // namespace hlsl
-} // namespace writer
-} // namespace tint
diff --git a/src/writer/hlsl/generator_impl_function_entry_point_data_test.cc b/src/writer/hlsl/generator_impl_function_entry_point_data_test.cc
index 4a65bef..04eca18 100644
--- a/src/writer/hlsl/generator_impl_function_entry_point_data_test.cc
+++ b/src/writer/hlsl/generator_impl_function_entry_point_data_test.cc
@@ -14,7 +14,6 @@
#include "src/ast/assignment_statement.h"
#include "src/ast/decorated_variable.h"
-#include "src/ast/entry_point.h"
#include "src/ast/identifier_expression.h"
#include "src/ast/location_decoration.h"
#include "src/ast/member_accessor_expression.h"
diff --git a/src/writer/hlsl/generator_impl_function_test.cc b/src/writer/hlsl/generator_impl_function_test.cc
index 4c25dd7..86e392f 100644
--- a/src/writer/hlsl/generator_impl_function_test.cc
+++ b/src/writer/hlsl/generator_impl_function_test.cc
@@ -124,82 +124,6 @@
)");
}
-TEST_F(HlslGeneratorImplTest_Function, Emit_Function_EntryPoint_NoName) {
- ast::type::VoidType void_type;
-
- auto func = std::make_unique<ast::Function>("frag_main", ast::VariableList{},
- &void_type);
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment, "",
- "frag_main");
-
- mod()->AddFunction(std::move(func));
- mod()->AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(gen().Generate(out())) << gen().error();
- EXPECT_EQ(result(), R"(void frag_main() {
-}
-
-)");
-}
-
-TEST_F(HlslGeneratorImplTest_Function, Emit_Function_EntryPoint_WithInOutVars) {
- ast::type::VoidType void_type;
- ast::type::F32Type f32;
-
- auto foo_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
-
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::LocationDecoration>(0));
- foo_var->set_decorations(std::move(decos));
-
- auto bar_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("bar", ast::StorageClass::kOutput, &f32));
- decos.push_back(std::make_unique<ast::LocationDecoration>(1));
- bar_var->set_decorations(std::move(decos));
-
- td().RegisterVariableForTesting(foo_var.get());
- td().RegisterVariableForTesting(bar_var.get());
-
- mod()->AddGlobalVariable(std::move(foo_var));
- mod()->AddGlobalVariable(std::move(bar_var));
-
- ast::VariableList params;
- auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
- &void_type);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("bar"),
- std::make_unique<ast::IdentifierExpression>("foo")));
- body->append(std::make_unique<ast::ReturnStatement>());
- func->set_body(std::move(body));
-
- mod()->AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment, "",
- "frag_main");
- mod()->AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td().Determine()) << td().error();
- ASSERT_TRUE(gen().Generate(out())) << gen().error();
- EXPECT_EQ(result(), R"(struct frag_main_in {
- float foo : TEXCOORD0;
-};
-
-struct frag_main_out {
- float bar : SV_Target1;
-};
-
-frag_main_out frag_main(frag_main_in tint_in) {
- frag_main_out tint_out;
- tint_out.bar = tint_in.foo;
- return tint_out;
-}
-
-)");
-}
-
TEST_F(HlslGeneratorImplTest_Function,
Emit_FunctionDecoration_EntryPoint_WithInOutVars) {
ast::type::VoidType void_type;
@@ -258,72 +182,6 @@
}
TEST_F(HlslGeneratorImplTest_Function,
- Emit_Function_EntryPoint_WithInOut_Builtins) {
- ast::type::VoidType void_type;
- ast::type::F32Type f32;
- ast::type::VectorType vec4(&f32, 4);
-
- auto coord_var =
- std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
- "coord", ast::StorageClass::kInput, &vec4));
-
- ast::VariableDecorationList decos;
- decos.push_back(
- std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragCoord));
- coord_var->set_decorations(std::move(decos));
-
- auto depth_var =
- std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
- "depth", ast::StorageClass::kOutput, &f32));
- decos.push_back(
- std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragDepth));
- depth_var->set_decorations(std::move(decos));
-
- td().RegisterVariableForTesting(coord_var.get());
- td().RegisterVariableForTesting(depth_var.get());
-
- mod()->AddGlobalVariable(std::move(coord_var));
- mod()->AddGlobalVariable(std::move(depth_var));
-
- ast::VariableList params;
- auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
- &void_type);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("depth"),
- std::make_unique<ast::MemberAccessorExpression>(
- std::make_unique<ast::IdentifierExpression>("coord"),
- std::make_unique<ast::IdentifierExpression>("x"))));
- body->append(std::make_unique<ast::ReturnStatement>());
- func->set_body(std::move(body));
-
- mod()->AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment, "",
- "frag_main");
- mod()->AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td().Determine()) << td().error();
- ASSERT_TRUE(gen().Generate(out())) << gen().error();
- EXPECT_EQ(result(), R"(struct frag_main_in {
- vector<float, 4> coord : SV_Position;
-};
-
-struct frag_main_out {
- float depth : SV_Depth;
-};
-
-frag_main_out frag_main(frag_main_in tint_in) {
- frag_main_out tint_out;
- tint_out.depth = tint_in.coord.x;
- return tint_out;
-}
-
-)");
-}
-
-TEST_F(HlslGeneratorImplTest_Function,
Emit_FunctionDecoration_EntryPoint_WithInOut_Builtins) {
ast::type::VoidType void_type;
ast::type::F32Type f32;
@@ -387,58 +245,6 @@
)");
}
-TEST_F(HlslGeneratorImplTest_Function, Emit_Function_EntryPoint_With_Uniform) {
- ast::type::VoidType void_type;
- ast::type::F32Type f32;
- ast::type::VectorType vec4(&f32, 4);
-
- auto coord_var =
- std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
- "coord", ast::StorageClass::kUniform, &vec4));
-
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::BindingDecoration>(0));
- decos.push_back(std::make_unique<ast::SetDecoration>(1));
- coord_var->set_decorations(std::move(decos));
-
- td().RegisterVariableForTesting(coord_var.get());
- mod()->AddGlobalVariable(std::move(coord_var));
-
- ast::VariableList params;
- auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
- &void_type);
-
- auto var =
- std::make_unique<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
- var->set_constructor(std::make_unique<ast::MemberAccessorExpression>(
- std::make_unique<ast::IdentifierExpression>("coord"),
- std::make_unique<ast::IdentifierExpression>("x")));
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::VariableDeclStatement>(std::move(var)));
- body->append(std::make_unique<ast::ReturnStatement>());
- func->set_body(std::move(body));
-
- mod()->AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment, "",
- "frag_main");
- mod()->AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td().Determine()) << td().error();
- ASSERT_TRUE(gen().Generate(out())) << gen().error();
- EXPECT_EQ(result(), R"(cbuffer : register(b0) {
- vector<float, 4> coord;
-};
-
-void frag_main() {
- float v = coord.x;
- return;
-}
-
-)");
-}
-
TEST_F(HlslGeneratorImplTest_Function,
Emit_FunctionDecoration_EntryPoint_With_Uniform) {
ast::type::VoidType void_type;
@@ -491,76 +297,6 @@
}
TEST_F(HlslGeneratorImplTest_Function,
- Emit_Function_EntryPoint_With_UniformStruct) {
- ast::type::VoidType void_type;
- ast::type::F32Type f32;
- ast::type::VectorType vec4(&f32, 4);
-
- ast::StructMemberList members;
- members.push_back(std::make_unique<ast::StructMember>(
- "coord", &vec4, ast::StructMemberDecorationList{}));
-
- auto str = std::make_unique<ast::Struct>();
- str->set_members(std::move(members));
-
- ast::type::StructType s(std::move(str));
- s.set_name("Uniforms");
- auto alias = std::make_unique<ast::type::AliasType>("Uniforms", &s);
-
- auto coord_var =
- std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
- "uniforms", ast::StorageClass::kUniform, alias.get()));
-
- mod()->AddAliasType(alias.get());
-
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::BindingDecoration>(0));
- decos.push_back(std::make_unique<ast::SetDecoration>(1));
- coord_var->set_decorations(std::move(decos));
-
- td().RegisterVariableForTesting(coord_var.get());
- mod()->AddGlobalVariable(std::move(coord_var));
-
- ast::VariableList params;
- auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
- &void_type);
-
- auto var =
- std::make_unique<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
- var->set_constructor(std::make_unique<ast::MemberAccessorExpression>(
- std::make_unique<ast::MemberAccessorExpression>(
- std::make_unique<ast::IdentifierExpression>("uniforms"),
- std::make_unique<ast::IdentifierExpression>("coord")),
- std::make_unique<ast::IdentifierExpression>("x")));
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::VariableDeclStatement>(std::move(var)));
- body->append(std::make_unique<ast::ReturnStatement>());
- func->set_body(std::move(body));
-
- mod()->AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment, "",
- "frag_main");
- mod()->AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td().Determine()) << td().error();
- ASSERT_TRUE(gen().Generate(out())) << gen().error();
- EXPECT_EQ(result(), R"(struct Uniforms {
- vector<float, 4> coord;
-};
-
-ConstantBuffer<Uniforms> uniforms : register(b0);
-
-void frag_main() {
- float v = uniforms.coord.x;
- return;
-}
-
-)");
-}
-
-TEST_F(HlslGeneratorImplTest_Function,
Emit_FunctionDecoration_EntryPoint_With_UniformStruct) {
ast::type::VoidType void_type;
ast::type::F32Type f32;
@@ -629,74 +365,6 @@
}
TEST_F(HlslGeneratorImplTest_Function,
- Emit_Function_EntryPoint_With_StorageBuffer_Read) {
- ast::type::VoidType void_type;
- ast::type::F32Type f32;
- ast::type::I32Type i32;
-
- ast::StructMemberList members;
- ast::StructMemberDecorationList a_deco;
- a_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
- members.push_back(
- std::make_unique<ast::StructMember>("a", &i32, std::move(a_deco)));
-
- ast::StructMemberDecorationList b_deco;
- b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
- members.push_back(
- std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
-
- auto str = std::make_unique<ast::Struct>();
- str->set_members(std::move(members));
-
- ast::type::StructType s(std::move(str));
- s.set_name("Data");
-
- auto coord_var =
- std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
- "coord", ast::StorageClass::kStorageBuffer, &s));
-
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::BindingDecoration>(0));
- decos.push_back(std::make_unique<ast::SetDecoration>(1));
- coord_var->set_decorations(std::move(decos));
-
- td().RegisterVariableForTesting(coord_var.get());
- mod()->AddGlobalVariable(std::move(coord_var));
-
- ast::VariableList params;
- auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
- &void_type);
-
- auto var =
- std::make_unique<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
- var->set_constructor(std::make_unique<ast::MemberAccessorExpression>(
- std::make_unique<ast::IdentifierExpression>("coord"),
- std::make_unique<ast::IdentifierExpression>("b")));
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::VariableDeclStatement>(std::move(var)));
- body->append(std::make_unique<ast::ReturnStatement>());
- func->set_body(std::move(body));
-
- mod()->AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment, "",
- "frag_main");
- mod()->AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td().Determine()) << td().error();
- ASSERT_TRUE(gen().Generate(out())) << gen().error();
- EXPECT_EQ(result(), R"(RWByteAddressBuffer coord : register(u0);
-
-void frag_main() {
- float v = asfloat(coord.Load(4));
- return;
-}
-
-)");
-}
-
-TEST_F(HlslGeneratorImplTest_Function,
Emit_FunctionDecoration_EntryPoint_With_StorageBuffer_Read) {
ast::type::VoidType void_type;
ast::type::F32Type f32;
@@ -763,76 +431,6 @@
}
TEST_F(HlslGeneratorImplTest_Function,
- Emit_Function_EntryPoint_With_StorageBuffer_Store) {
- ast::type::VoidType void_type;
- ast::type::F32Type f32;
- ast::type::I32Type i32;
-
- ast::StructMemberList members;
- ast::StructMemberDecorationList a_deco;
- a_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
- members.push_back(
- std::make_unique<ast::StructMember>("a", &i32, std::move(a_deco)));
-
- ast::StructMemberDecorationList b_deco;
- b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
- members.push_back(
- std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
-
- auto str = std::make_unique<ast::Struct>();
- str->set_members(std::move(members));
-
- ast::type::StructType s(std::move(str));
- s.set_name("Data");
-
- auto coord_var =
- std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
- "coord", ast::StorageClass::kStorageBuffer, &s));
-
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::BindingDecoration>(0));
- decos.push_back(std::make_unique<ast::SetDecoration>(1));
- coord_var->set_decorations(std::move(decos));
-
- td().RegisterVariableForTesting(coord_var.get());
-
- mod()->AddGlobalVariable(std::move(coord_var));
-
- ast::VariableList params;
- auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
- &void_type);
-
- auto assign = std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::MemberAccessorExpression>(
- std::make_unique<ast::IdentifierExpression>("coord"),
- std::make_unique<ast::IdentifierExpression>("b")),
- std::make_unique<ast::ScalarConstructorExpression>(
- std::make_unique<ast::FloatLiteral>(&f32, 2.0f)));
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::move(assign));
- body->append(std::make_unique<ast::ReturnStatement>());
- func->set_body(std::move(body));
-
- mod()->AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment, "",
- "frag_main");
- mod()->AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td().Determine()) << td().error();
- ASSERT_TRUE(gen().Generate(out())) << gen().error();
- EXPECT_EQ(result(), R"(RWByteAddressBuffer coord : register(u0);
-
-void frag_main() {
- coord.Store(4, asuint(2.00000000f));
- return;
-}
-
-)");
-}
-
-TEST_F(HlslGeneratorImplTest_Function,
Emit_FunctionDecoration_EntryPoint_With_StorageBuffer_Store) {
ast::type::VoidType void_type;
ast::type::F32Type f32;
@@ -900,103 +498,6 @@
)");
}
-TEST_F(HlslGeneratorImplTest_Function,
- Emit_Function_Called_By_EntryPoints_WithLocationGlobals_And_Params) {
- ast::type::VoidType void_type;
- ast::type::F32Type f32;
-
- auto foo_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
-
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::LocationDecoration>(0));
- foo_var->set_decorations(std::move(decos));
-
- auto bar_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("bar", ast::StorageClass::kOutput, &f32));
- decos.push_back(std::make_unique<ast::LocationDecoration>(1));
- bar_var->set_decorations(std::move(decos));
-
- auto val_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("val", ast::StorageClass::kOutput, &f32));
- decos.push_back(std::make_unique<ast::LocationDecoration>(0));
- val_var->set_decorations(std::move(decos));
-
- td().RegisterVariableForTesting(foo_var.get());
- td().RegisterVariableForTesting(bar_var.get());
- td().RegisterVariableForTesting(val_var.get());
-
- mod()->AddGlobalVariable(std::move(foo_var));
- mod()->AddGlobalVariable(std::move(bar_var));
- mod()->AddGlobalVariable(std::move(val_var));
-
- ast::VariableList params;
- params.push_back(std::make_unique<ast::Variable>(
- "param", ast::StorageClass::kFunction, &f32));
- auto sub_func =
- std::make_unique<ast::Function>("sub_func", std::move(params), &f32);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("bar"),
- std::make_unique<ast::IdentifierExpression>("foo")));
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("val"),
- std::make_unique<ast::IdentifierExpression>("param")));
- body->append(std::make_unique<ast::ReturnStatement>(
- std::make_unique<ast::IdentifierExpression>("foo")));
- sub_func->set_body(std::move(body));
-
- mod()->AddFunction(std::move(sub_func));
-
- auto func_1 = std::make_unique<ast::Function>("frag_1_main",
- std::move(params), &void_type);
-
- ast::ExpressionList expr;
- expr.push_back(std::make_unique<ast::ScalarConstructorExpression>(
- std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-
- body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("bar"),
- std::make_unique<ast::CallExpression>(
- std::make_unique<ast::IdentifierExpression>("sub_func"),
- std::move(expr))));
- body->append(std::make_unique<ast::ReturnStatement>());
- func_1->set_body(std::move(body));
-
- mod()->AddFunction(std::move(func_1));
-
- auto ep1 = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment,
- "ep_1", "frag_1_main");
- mod()->AddEntryPoint(std::move(ep1));
-
- ASSERT_TRUE(td().Determine()) << td().error();
- ASSERT_TRUE(gen().Generate(out())) << gen().error();
- EXPECT_EQ(result(), R"(struct ep_1_in {
- float foo : TEXCOORD0;
-};
-
-struct ep_1_out {
- float bar : SV_Target1;
- float val : SV_Target0;
-};
-
-float sub_func_ep_1(in ep_1_in tint_in, out ep_1_out tint_out, float param) {
- tint_out.bar = tint_in.foo;
- tint_out.val = param;
- return tint_in.foo;
-}
-
-ep_1_out ep_1(ep_1_in tint_in) {
- ep_1_out tint_out;
- tint_out.bar = sub_func_ep_1(tint_in, tint_out, 1.00000000f);
- return tint_out;
-}
-
-)");
-}
-
TEST_F(
HlslGeneratorImplTest_Function,
Emit_FunctionDecoration_Called_By_EntryPoints_WithLocationGlobals_And_Params) {
@@ -1094,79 +595,6 @@
}
TEST_F(HlslGeneratorImplTest_Function,
- Emit_Function_Called_By_EntryPoints_NoUsedGlobals) {
- ast::type::VoidType void_type;
- ast::type::F32Type f32;
- ast::type::VectorType vec4(&f32, 4);
-
- auto depth_var =
- std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
- "depth", ast::StorageClass::kOutput, &f32));
-
- ast::VariableDecorationList decos;
- decos.push_back(
- std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragDepth));
- depth_var->set_decorations(std::move(decos));
-
- td().RegisterVariableForTesting(depth_var.get());
-
- mod()->AddGlobalVariable(std::move(depth_var));
-
- ast::VariableList params;
- params.push_back(std::make_unique<ast::Variable>(
- "param", ast::StorageClass::kFunction, &f32));
- auto sub_func =
- std::make_unique<ast::Function>("sub_func", std::move(params), &f32);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::ReturnStatement>(
- std::make_unique<ast::IdentifierExpression>("param")));
- sub_func->set_body(std::move(body));
-
- mod()->AddFunction(std::move(sub_func));
-
- auto func_1 = std::make_unique<ast::Function>("frag_1_main",
- std::move(params), &void_type);
-
- ast::ExpressionList expr;
- expr.push_back(std::make_unique<ast::ScalarConstructorExpression>(
- std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-
- body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("depth"),
- std::make_unique<ast::CallExpression>(
- std::make_unique<ast::IdentifierExpression>("sub_func"),
- std::move(expr))));
- body->append(std::make_unique<ast::ReturnStatement>());
- func_1->set_body(std::move(body));
-
- mod()->AddFunction(std::move(func_1));
-
- auto ep1 = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment,
- "ep_1", "frag_1_main");
- mod()->AddEntryPoint(std::move(ep1));
-
- ASSERT_TRUE(td().Determine()) << td().error();
- ASSERT_TRUE(gen().Generate(out())) << gen().error();
- EXPECT_EQ(result(), R"(struct ep_1_out {
- float depth : SV_Depth;
-};
-
-float sub_func(float param) {
- return param;
-}
-
-ep_1_out ep_1() {
- ep_1_out tint_out;
- tint_out.depth = sub_func(1.00000000f);
- return tint_out;
-}
-
-)");
-}
-
-TEST_F(HlslGeneratorImplTest_Function,
Emit_FunctionDecoration_Called_By_EntryPoints_NoUsedGlobals) {
ast::type::VoidType void_type;
ast::type::F32Type f32;
@@ -1237,98 +665,6 @@
)");
}
-TEST_F(HlslGeneratorImplTest_Function,
- Emit_Function_Called_By_EntryPoints_WithBuiltinGlobals_And_Params) {
- ast::type::VoidType void_type;
- ast::type::F32Type f32;
- ast::type::VectorType vec4(&f32, 4);
-
- auto coord_var =
- std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
- "coord", ast::StorageClass::kInput, &vec4));
-
- ast::VariableDecorationList decos;
- decos.push_back(
- std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragCoord));
- coord_var->set_decorations(std::move(decos));
-
- auto depth_var =
- std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
- "depth", ast::StorageClass::kOutput, &f32));
- decos.push_back(
- std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragDepth));
- depth_var->set_decorations(std::move(decos));
-
- td().RegisterVariableForTesting(coord_var.get());
- td().RegisterVariableForTesting(depth_var.get());
-
- mod()->AddGlobalVariable(std::move(coord_var));
- mod()->AddGlobalVariable(std::move(depth_var));
-
- ast::VariableList params;
- params.push_back(std::make_unique<ast::Variable>(
- "param", ast::StorageClass::kFunction, &f32));
- auto sub_func =
- std::make_unique<ast::Function>("sub_func", std::move(params), &f32);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("depth"),
- std::make_unique<ast::MemberAccessorExpression>(
- std::make_unique<ast::IdentifierExpression>("coord"),
- std::make_unique<ast::IdentifierExpression>("x"))));
- body->append(std::make_unique<ast::ReturnStatement>(
- std::make_unique<ast::IdentifierExpression>("param")));
- sub_func->set_body(std::move(body));
-
- mod()->AddFunction(std::move(sub_func));
-
- auto func_1 = std::make_unique<ast::Function>("frag_1_main",
- std::move(params), &void_type);
-
- ast::ExpressionList expr;
- expr.push_back(std::make_unique<ast::ScalarConstructorExpression>(
- std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-
- body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("depth"),
- std::make_unique<ast::CallExpression>(
- std::make_unique<ast::IdentifierExpression>("sub_func"),
- std::move(expr))));
- body->append(std::make_unique<ast::ReturnStatement>());
- func_1->set_body(std::move(body));
-
- mod()->AddFunction(std::move(func_1));
-
- auto ep1 = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment,
- "ep_1", "frag_1_main");
- mod()->AddEntryPoint(std::move(ep1));
-
- ASSERT_TRUE(td().Determine()) << td().error();
- ASSERT_TRUE(gen().Generate(out())) << gen().error();
- EXPECT_EQ(result(), R"(struct ep_1_in {
- vector<float, 4> coord : SV_Position;
-};
-
-struct ep_1_out {
- float depth : SV_Depth;
-};
-
-float sub_func_ep_1(in ep_1_in tint_in, out ep_1_out tint_out, float param) {
- tint_out.depth = tint_in.coord.x;
- return param;
-}
-
-ep_1_out ep_1(ep_1_in tint_in) {
- ep_1_out tint_out;
- tint_out.depth = sub_func_ep_1(tint_in, tint_out, 1.00000000f);
- return tint_out;
-}
-
-)");
-}
-
TEST_F(
HlslGeneratorImplTest_Function,
Emit_FunctionDecoration_Called_By_EntryPoints_WithBuiltinGlobals_And_Params) {
@@ -1421,82 +757,6 @@
}
TEST_F(HlslGeneratorImplTest_Function,
- Emit_Function_Called_By_EntryPoint_With_Uniform) {
- ast::type::VoidType void_type;
- ast::type::F32Type f32;
- ast::type::VectorType vec4(&f32, 4);
-
- auto coord_var =
- std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
- "coord", ast::StorageClass::kUniform, &vec4));
-
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::BindingDecoration>(0));
- decos.push_back(std::make_unique<ast::SetDecoration>(1));
- coord_var->set_decorations(std::move(decos));
-
- td().RegisterVariableForTesting(coord_var.get());
-
- mod()->AddGlobalVariable(std::move(coord_var));
-
- ast::VariableList params;
- params.push_back(std::make_unique<ast::Variable>(
- "param", ast::StorageClass::kFunction, &f32));
- auto sub_func =
- std::make_unique<ast::Function>("sub_func", std::move(params), &f32);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::ReturnStatement>(
- std::make_unique<ast::MemberAccessorExpression>(
- std::make_unique<ast::IdentifierExpression>("coord"),
- std::make_unique<ast::IdentifierExpression>("x"))));
- sub_func->set_body(std::move(body));
-
- mod()->AddFunction(std::move(sub_func));
-
- auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
- &void_type);
-
- ast::ExpressionList expr;
- expr.push_back(std::make_unique<ast::ScalarConstructorExpression>(
- std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-
- auto var =
- std::make_unique<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
- var->set_constructor(std::make_unique<ast::CallExpression>(
- std::make_unique<ast::IdentifierExpression>("sub_func"),
- std::move(expr)));
-
- body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::VariableDeclStatement>(std::move(var)));
- body->append(std::make_unique<ast::ReturnStatement>());
- func->set_body(std::move(body));
-
- mod()->AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment, "",
- "frag_main");
- mod()->AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td().Determine()) << td().error();
- ASSERT_TRUE(gen().Generate(out())) << gen().error();
- EXPECT_EQ(result(), R"(cbuffer : register(b0) {
- vector<float, 4> coord;
-};
-
-float sub_func(float param) {
- return coord.x;
-}
-
-void frag_main() {
- float v = sub_func(1.00000000f);
- return;
-}
-
-)");
-}
-
-TEST_F(HlslGeneratorImplTest_Function,
Emit_FunctionDecoration_Called_By_EntryPoint_With_Uniform) {
ast::type::VoidType void_type;
ast::type::F32Type f32;
@@ -1571,80 +831,6 @@
}
TEST_F(HlslGeneratorImplTest_Function,
- Emit_Function_Called_By_EntryPoint_With_StorageBuffer) {
- ast::type::VoidType void_type;
- ast::type::F32Type f32;
- ast::type::VectorType vec4(&f32, 4);
-
- auto coord_var =
- std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
- "coord", ast::StorageClass::kStorageBuffer, &vec4));
-
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::BindingDecoration>(0));
- decos.push_back(std::make_unique<ast::SetDecoration>(1));
- coord_var->set_decorations(std::move(decos));
-
- td().RegisterVariableForTesting(coord_var.get());
-
- mod()->AddGlobalVariable(std::move(coord_var));
-
- ast::VariableList params;
- params.push_back(std::make_unique<ast::Variable>(
- "param", ast::StorageClass::kFunction, &f32));
- auto sub_func =
- std::make_unique<ast::Function>("sub_func", std::move(params), &f32);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::ReturnStatement>(
- std::make_unique<ast::MemberAccessorExpression>(
- std::make_unique<ast::IdentifierExpression>("coord"),
- std::make_unique<ast::IdentifierExpression>("x"))));
- sub_func->set_body(std::move(body));
-
- mod()->AddFunction(std::move(sub_func));
-
- auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
- &void_type);
-
- ast::ExpressionList expr;
- expr.push_back(std::make_unique<ast::ScalarConstructorExpression>(
- std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-
- auto var =
- std::make_unique<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
- var->set_constructor(std::make_unique<ast::CallExpression>(
- std::make_unique<ast::IdentifierExpression>("sub_func"),
- std::move(expr)));
-
- body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::VariableDeclStatement>(std::move(var)));
- body->append(std::make_unique<ast::ReturnStatement>());
- func->set_body(std::move(body));
-
- mod()->AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment, "",
- "frag_main");
- mod()->AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td().Determine()) << td().error();
- ASSERT_TRUE(gen().Generate(out())) << gen().error();
- EXPECT_EQ(result(), R"(RWByteAddressBuffer coord : register(u0);
-
-float sub_func(float param) {
- return asfloat(coord.Load((4 * 0)));
-}
-
-void frag_main() {
- float v = sub_func(1.00000000f);
- return;
-}
-
-)");
-}
-
-TEST_F(HlslGeneratorImplTest_Function,
Emit_FunctionDecoration_Called_By_EntryPoint_With_StorageBuffer) {
ast::type::VoidType void_type;
ast::type::F32Type f32;
@@ -1717,171 +903,6 @@
}
TEST_F(HlslGeneratorImplTest_Function,
- Emit_Function_Called_Two_EntryPoints_WithGlobals) {
- ast::type::VoidType void_type;
- ast::type::F32Type f32;
-
- auto foo_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
-
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::LocationDecoration>(0));
- foo_var->set_decorations(std::move(decos));
-
- auto bar_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("bar", ast::StorageClass::kOutput, &f32));
- decos.push_back(std::make_unique<ast::LocationDecoration>(1));
- bar_var->set_decorations(std::move(decos));
-
- td().RegisterVariableForTesting(foo_var.get());
- td().RegisterVariableForTesting(bar_var.get());
-
- mod()->AddGlobalVariable(std::move(foo_var));
- mod()->AddGlobalVariable(std::move(bar_var));
-
- ast::VariableList params;
- auto sub_func =
- std::make_unique<ast::Function>("sub_func", std::move(params), &f32);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("bar"),
- std::make_unique<ast::IdentifierExpression>("foo")));
- body->append(std::make_unique<ast::ReturnStatement>(
- std::make_unique<ast::IdentifierExpression>("foo")));
- sub_func->set_body(std::move(body));
-
- mod()->AddFunction(std::move(sub_func));
-
- auto func_1 = std::make_unique<ast::Function>("frag_1_main",
- std::move(params), &void_type);
-
- body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("bar"),
- std::make_unique<ast::CallExpression>(
- std::make_unique<ast::IdentifierExpression>("sub_func"),
- ast::ExpressionList{})));
- body->append(std::make_unique<ast::ReturnStatement>());
- func_1->set_body(std::move(body));
-
- mod()->AddFunction(std::move(func_1));
-
- auto ep1 = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment,
- "ep_1", "frag_1_main");
- auto ep2 = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment,
- "ep_2", "frag_1_main");
- mod()->AddEntryPoint(std::move(ep1));
- mod()->AddEntryPoint(std::move(ep2));
-
- ASSERT_TRUE(td().Determine()) << td().error();
- ASSERT_TRUE(gen().Generate(out())) << gen().error();
- EXPECT_EQ(result(), R"(struct ep_1_in {
- float foo : TEXCOORD0;
-};
-
-struct ep_1_out {
- float bar : SV_Target1;
-};
-
-struct ep_2_in {
- float foo : TEXCOORD0;
-};
-
-struct ep_2_out {
- float bar : SV_Target1;
-};
-
-float sub_func_ep_1(in ep_1_in tint_in, out ep_1_out tint_out) {
- tint_out.bar = tint_in.foo;
- return tint_in.foo;
-}
-
-float sub_func_ep_2(in ep_2_in tint_in_0, out ep_2_out tint_out_0) {
- tint_out_0.bar = tint_in_0.foo;
- return tint_in_0.foo;
-}
-
-ep_1_out ep_1(ep_1_in tint_in) {
- ep_1_out tint_out;
- tint_out.bar = sub_func_ep_1(tint_in, tint_out);
- return tint_out;
-}
-
-ep_2_out ep_2(ep_2_in tint_in_0) {
- ep_2_out tint_out_0;
- tint_out_0.bar = sub_func_ep_2(tint_in_0, tint_out_0);
- return tint_out_0;
-}
-
-)");
-}
-
-TEST_F(HlslGeneratorImplTest_Function,
- Emit_Function_EntryPoints_WithGlobal_Nested_Return) {
- ast::type::VoidType void_type;
- ast::type::F32Type f32;
- ast::type::I32Type i32;
-
- auto bar_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("bar", ast::StorageClass::kOutput, &f32));
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::LocationDecoration>(1));
- bar_var->set_decorations(std::move(decos));
-
- td().RegisterVariableForTesting(bar_var.get());
- mod()->AddGlobalVariable(std::move(bar_var));
-
- ast::VariableList params;
- auto func_1 = std::make_unique<ast::Function>("frag_1_main",
- std::move(params), &void_type);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("bar"),
- std::make_unique<ast::ScalarConstructorExpression>(
- std::make_unique<ast::FloatLiteral>(&f32, 1.0f))));
-
- auto list = std::make_unique<ast::BlockStatement>();
- list->append(std::make_unique<ast::ReturnStatement>());
-
- body->append(std::make_unique<ast::IfStatement>(
- std::make_unique<ast::BinaryExpression>(
- ast::BinaryOp::kEqual,
- std::make_unique<ast::ScalarConstructorExpression>(
- std::make_unique<ast::SintLiteral>(&i32, 1)),
- std::make_unique<ast::ScalarConstructorExpression>(
- std::make_unique<ast::SintLiteral>(&i32, 1))),
- std::move(list)));
-
- body->append(std::make_unique<ast::ReturnStatement>());
- func_1->set_body(std::move(body));
-
- mod()->AddFunction(std::move(func_1));
-
- auto ep1 = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment,
- "ep_1", "frag_1_main");
- mod()->AddEntryPoint(std::move(ep1));
-
- ASSERT_TRUE(td().Determine()) << td().error();
- ASSERT_TRUE(gen().Generate(out())) << gen().error();
- EXPECT_EQ(result(), R"(struct ep_1_out {
- float bar : SV_Target1;
-};
-
-ep_1_out ep_1() {
- ep_1_out tint_out;
- tint_out.bar = 1.00000000f;
- if ((1 == 1)) {
- return tint_out;
- }
- return tint_out;
-}
-
-)");
-}
-
-TEST_F(HlslGeneratorImplTest_Function,
Emit_FunctionDecoration_EntryPoints_WithGlobal_Nested_Return) {
ast::type::VoidType void_type;
ast::type::F32Type f32;
@@ -1944,103 +965,6 @@
}
TEST_F(HlslGeneratorImplTest_Function,
- Emit_Function_Called_Two_EntryPoints_WithoutGlobals) {
- ast::type::VoidType void_type;
- ast::type::F32Type f32;
-
- ast::VariableList params;
- auto sub_func =
- std::make_unique<ast::Function>("sub_func", std::move(params), &f32);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::ReturnStatement>(
- std::make_unique<ast::ScalarConstructorExpression>(
- std::make_unique<ast::FloatLiteral>(&f32, 1.0))));
- sub_func->set_body(std::move(body));
-
- mod()->AddFunction(std::move(sub_func));
-
- auto func_1 = std::make_unique<ast::Function>("frag_1_main",
- std::move(params), &void_type);
-
- auto var = std::make_unique<ast::Variable>(
- "foo", ast::StorageClass::kFunction, &f32);
- var->set_constructor(std::make_unique<ast::CallExpression>(
- std::make_unique<ast::IdentifierExpression>("sub_func"),
- ast::ExpressionList{}));
-
- body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::VariableDeclStatement>(std::move(var)));
- body->append(std::make_unique<ast::ReturnStatement>());
- func_1->set_body(std::move(body));
-
- mod()->AddFunction(std::move(func_1));
-
- auto ep1 = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment,
- "ep_1", "frag_1_main");
- auto ep2 = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment,
- "ep_2", "frag_1_main");
- mod()->AddEntryPoint(std::move(ep1));
- mod()->AddEntryPoint(std::move(ep2));
-
- ASSERT_TRUE(td().Determine()) << td().error();
-
- ASSERT_TRUE(gen().Generate(out())) << gen().error();
- EXPECT_EQ(result(), R"(float sub_func() {
- return 1.00000000f;
-}
-
-void ep_1() {
- float foo = sub_func();
- return;
-}
-
-void ep_2() {
- float foo = sub_func();
- return;
-}
-
-)");
-}
-
-TEST_F(HlslGeneratorImplTest_Function, Emit_Function_EntryPoint_WithName) {
- ast::type::VoidType void_type;
-
- auto func = std::make_unique<ast::Function>("frag_main", ast::VariableList{},
- &void_type);
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment,
- "my_main", "frag_main");
-
- mod()->AddFunction(std::move(func));
- mod()->AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(gen().Generate(out())) << gen().error();
- EXPECT_EQ(result(), R"(void my_main() {
-}
-
-)");
-}
-
-TEST_F(HlslGeneratorImplTest_Function,
- Emit_Function_EntryPoint_WithNameCollision) {
- ast::type::VoidType void_type;
-
- auto func = std::make_unique<ast::Function>("frag_main", ast::VariableList{},
- &void_type);
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment,
- "GeometryShader", "frag_main");
-
- mod()->AddFunction(std::move(func));
- mod()->AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(gen().Generate(out())) << gen().error();
- EXPECT_EQ(result(), R"(void GeometryShader_tint_0() {
-}
-
-)");
-}
-
-TEST_F(HlslGeneratorImplTest_Function,
Emit_FunctionDecoration_EntryPoint_WithNameCollision) {
ast::type::VoidType void_type;
@@ -2058,33 +982,6 @@
)");
}
-TEST_F(HlslGeneratorImplTest_Function, Emit_Function_EntryPoint_Compute) {
- ast::type::VoidType void_type;
-
- ast::VariableList params;
- auto func = std::make_unique<ast::Function>("comp_main", std::move(params),
- &void_type);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::ReturnStatement>());
- func->set_body(std::move(body));
-
- mod()->AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kCompute,
- "main", "comp_main");
- mod()->AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td().Determine()) << td().error();
- ASSERT_TRUE(gen().Generate(out())) << gen().error();
- EXPECT_EQ(result(), R"([numthreads(1, 1, 1)]
-void main() {
- return;
-}
-
-)");
-}
-
TEST_F(HlslGeneratorImplTest_Function,
Emit_FunctionDecoration_EntryPoint_Compute) {
ast::type::VoidType void_type;
@@ -2112,35 +1009,6 @@
}
TEST_F(HlslGeneratorImplTest_Function,
- Emit_Function_EntryPoint_Compute_WithWorkgroup) {
- ast::type::VoidType void_type;
-
- ast::VariableList params;
- auto func = std::make_unique<ast::Function>("comp_main", std::move(params),
- &void_type);
- func->add_decoration(std::make_unique<ast::WorkgroupDecoration>(2u, 4u, 6u));
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::ReturnStatement>());
- func->set_body(std::move(body));
-
- mod()->AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kCompute,
- "main", "comp_main");
- mod()->AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td().Determine()) << td().error();
- ASSERT_TRUE(gen().Generate(out())) << gen().error();
- EXPECT_EQ(result(), R"([numthreads(2, 4, 6)]
-void main() {
- return;
-}
-
-)");
-}
-
-TEST_F(HlslGeneratorImplTest_Function,
Emit_FunctionDecoration_EntryPoint_Compute_WithWorkgroup) {
ast::type::VoidType void_type;
diff --git a/src/writer/hlsl/generator_impl_test.cc b/src/writer/hlsl/generator_impl_test.cc
index 4055bb9..26b7003 100644
--- a/src/writer/hlsl/generator_impl_test.cc
+++ b/src/writer/hlsl/generator_impl_test.cc
@@ -14,7 +14,6 @@
#include <memory>
-#include "src/ast/entry_point.h"
#include "src/ast/function.h"
#include "src/ast/identifier_expression.h"
#include "src/ast/module.h"
@@ -30,10 +29,9 @@
TEST_F(HlslGeneratorImplTest, Generate) {
ast::type::VoidType void_type;
- mod()->AddFunction(std::make_unique<ast::Function>(
- "my_func", ast::VariableList{}, &void_type));
- mod()->AddEntryPoint(std::make_unique<ast::EntryPoint>(
- ast::PipelineStage::kFragment, "", "my_func"));
+ auto func = std::make_unique<ast::Function>("my_func", ast::VariableList{},
+ &void_type);
+ mod()->AddFunction(std::move(func));
ASSERT_TRUE(gen().Generate(out())) << gen().error();
EXPECT_EQ(result(), R"(void my_func() {
diff --git a/src/writer/msl/generator_impl.cc b/src/writer/msl/generator_impl.cc
index 34c9d6b..c6d45f7 100644
--- a/src/writer/msl/generator_impl.cc
+++ b/src/writer/msl/generator_impl.cc
@@ -124,12 +124,6 @@
}
}
- for (const auto& ep : module_->entry_points()) {
- if (!EmitEntryPointData(ep.get())) {
- return false;
- }
- }
-
// Make sure all entry point data is emitted before the entry point functions
for (const auto& func : module_->functions()) {
if (!func->IsEntryPoint()) {
@@ -147,12 +141,6 @@
}
}
- for (const auto& ep : module_->entry_points()) {
- if (!EmitEntryPointFunction(ep.get())) {
- return false;
- }
- out_ << std::endl;
- }
for (const auto& func : module_->functions()) {
if (!func->IsEntryPoint()) {
continue;
@@ -904,133 +892,6 @@
return true;
}
-bool GeneratorImpl::EmitEntryPointData(ast::EntryPoint* ep) {
- auto* func = module_->FindFunctionByName(ep->function_name());
- if (func == nullptr) {
- error_ = "Unable to find entry point function: " + ep->function_name();
- return false;
- }
-
- std::vector<std::pair<ast::Variable*, uint32_t>> in_locations;
- std::vector<std::pair<ast::Variable*, ast::VariableDecoration*>>
- out_variables;
- for (auto data : func->referenced_location_variables()) {
- auto* var = data.first;
- auto* deco = data.second;
-
- if (var->storage_class() == ast::StorageClass::kInput) {
- in_locations.push_back({var, deco->value()});
- } else if (var->storage_class() == ast::StorageClass::kOutput) {
- out_variables.push_back({var, deco});
- }
- }
-
- for (auto data : func->referenced_builtin_variables()) {
- auto* var = data.first;
- auto* deco = data.second;
-
- if (var->storage_class() == ast::StorageClass::kOutput) {
- out_variables.push_back({var, deco});
- }
- }
-
- auto ep_name = ep->name();
- if (ep_name.empty()) {
- ep_name = ep->function_name();
- }
-
- // TODO(dsinclair): There is a potential bug here. Entry points can have the
- // same name in WGSL if they have different pipeline stages. This does not
- // take that into account and will emit duplicate struct names. I'm ignoring
- // this until https://github.com/gpuweb/gpuweb/issues/662 is resolved as it
- // may remove this issue and entry point names will need to be unique.
- if (!in_locations.empty()) {
- auto in_struct_name = generate_name(ep_name + "_" + kInStructNameSuffix);
- auto in_var_name = generate_name(kTintStructInVarPrefix);
- ep_name_to_in_data_[ep_name] = {in_struct_name, in_var_name};
-
- make_indent();
- out_ << "struct " << in_struct_name << " {" << std::endl;
-
- increment_indent();
-
- for (auto& data : in_locations) {
- auto* var = data.first;
- uint32_t loc = data.second;
-
- make_indent();
- if (!EmitType(var->type(), var->name())) {
- return false;
- }
-
- out_ << " " << var->name() << " [[";
- if (ep->stage() == ast::PipelineStage::kVertex) {
- out_ << "attribute(" << loc << ")";
- } else if (ep->stage() == ast::PipelineStage::kFragment) {
- out_ << "user(locn" << loc << ")";
- } else {
- error_ = "invalid location variable for pipeline stage";
- return false;
- }
- out_ << "]];" << std::endl;
- }
- decrement_indent();
- make_indent();
-
- out_ << "};" << std::endl << std::endl;
- }
-
- if (!out_variables.empty()) {
- auto out_struct_name = generate_name(ep_name + "_" + kOutStructNameSuffix);
- auto out_var_name = generate_name(kTintStructOutVarPrefix);
- ep_name_to_out_data_[ep_name] = {out_struct_name, out_var_name};
-
- make_indent();
- out_ << "struct " << out_struct_name << " {" << std::endl;
-
- increment_indent();
- for (auto& data : out_variables) {
- auto* var = data.first;
- auto* deco = data.second;
-
- make_indent();
- if (!EmitType(var->type(), var->name())) {
- return false;
- }
-
- out_ << " " << var->name() << " [[";
-
- if (deco->IsLocation()) {
- auto loc = deco->AsLocation()->value();
- if (ep->stage() == ast::PipelineStage::kVertex) {
- out_ << "user(locn" << loc << ")";
- } else if (ep->stage() == ast::PipelineStage::kFragment) {
- out_ << "color(" << loc << ")";
- } else {
- error_ = "invalid location variable for pipeline stage";
- return false;
- }
- } else if (deco->IsBuiltin()) {
- auto attr = builtin_to_attribute(deco->AsBuiltin()->value());
- if (attr.empty()) {
- error_ = "unsupported builtin";
- return false;
- }
- out_ << attr;
- } else {
- error_ = "unsupported variable decoration for entry point output";
- return false;
- }
- out_ << "]];" << std::endl;
- }
- decrement_indent();
- make_indent();
- out_ << "};" << std::endl << std::endl;
- }
-
- return true;
-}
-
bool GeneratorImpl::EmitEntryPointData(ast::Function* func) {
std::vector<std::pair<ast::Variable*, uint32_t>> in_locations;
std::vector<std::pair<ast::Variable*, ast::VariableDecoration*>>
@@ -1230,7 +1091,7 @@
make_indent();
// Entry points will be emitted later, skip for now.
- if (func->IsEntryPoint() || module_->IsFunctionEntryPoint(func->name())) {
+ if (func->IsEntryPoint()) {
return true;
}
@@ -1402,141 +1263,6 @@
return "";
}
-bool GeneratorImpl::EmitEntryPointFunction(ast::EntryPoint* ep) {
- make_indent();
-
- current_ep_name_ = ep->name();
- if (current_ep_name_.empty()) {
- current_ep_name_ = ep->function_name();
- }
-
- auto* func = module_->FindFunctionByName(ep->function_name());
- if (func == nullptr) {
- error_ = "unable to find function for entry point: " + ep->function_name();
- return false;
- }
-
- EmitStage(ep->stage());
- out_ << " ";
-
- // This is an entry point, the return type is the entry point output structure
- // if one exists, or void otherwise.
- auto out_data = ep_name_to_out_data_.find(current_ep_name_);
- bool has_out_data = out_data != ep_name_to_out_data_.end();
- if (has_out_data) {
- out_ << out_data->second.struct_name;
- } else {
- out_ << "void";
- }
- out_ << " " << namer_.NameFor(current_ep_name_) << "(";
-
- bool first = true;
- auto in_data = ep_name_to_in_data_.find(current_ep_name_);
- if (in_data != ep_name_to_in_data_.end()) {
- out_ << in_data->second.struct_name << " " << in_data->second.var_name
- << " [[stage_in]]";
- first = false;
- }
-
- for (auto data : func->referenced_builtin_variables()) {
- auto* var = data.first;
- if (var->storage_class() != ast::StorageClass::kInput) {
- continue;
- }
-
- if (!first) {
- out_ << ", ";
- }
- first = false;
-
- auto* builtin = data.second;
-
- if (!EmitType(var->type(), "")) {
- return false;
- }
-
- auto attr = builtin_to_attribute(builtin->value());
- if (attr.empty()) {
- error_ = "unknown builtin";
- return false;
- }
- out_ << " " << var->name() << " [[" << attr << "]]";
- }
-
- for (auto data : func->referenced_uniform_variables()) {
- if (!first) {
- out_ << ", ";
- }
- first = false;
-
- auto* var = data.first;
- // TODO(dsinclair): We're using the binding to make up the buffer number but
- // we should instead be using a provided mapping that uses both buffer and
- // set. https://bugs.chromium.org/p/tint/issues/detail?id=104
- auto* binding = data.second.binding;
- if (binding == nullptr) {
- error_ = "unable to find binding information for uniform: " + var->name();
- return false;
- }
- // auto* set = data.second.set;
-
- out_ << "constant ";
- // TODO(dsinclair): Can you have a uniform array? If so, this needs to be
- // updated to handle arrays property.
- if (!EmitType(var->type(), "")) {
- return false;
- }
- out_ << "& " << var->name() << " [[buffer(" << binding->value() << ")]]";
- }
-
- for (auto data : func->referenced_storagebuffer_variables()) {
- if (!first) {
- out_ << ", ";
- }
- first = false;
-
- auto* var = data.first;
- // TODO(dsinclair): We're using the binding to make up the buffer number but
- // we should instead be using a provided mapping that uses both buffer and
- // set. https://bugs.chromium.org/p/tint/issues/detail?id=104
- auto* binding = data.second.binding;
- // auto* set = data.second.set;
-
- out_ << "device ";
- // TODO(dsinclair): Can you have a storagebuffer have an array? If so, this
- // needs to be updated to handle arrays property.
- if (!EmitType(var->type(), "")) {
- return false;
- }
- out_ << "& " << var->name() << " [[buffer(" << binding->value() << ")]]";
- }
-
- out_ << ") {" << std::endl;
-
- increment_indent();
-
- if (has_out_data) {
- make_indent();
- out_ << out_data->second.struct_name << " " << out_data->second.var_name
- << " = {};" << std::endl;
- }
-
- generating_entry_point_ = true;
- for (const auto& s : *(func->body())) {
- if (!EmitStatement(s.get())) {
- return false;
- }
- }
- generating_entry_point_ = false;
-
- decrement_indent();
- make_indent();
- out_ << "}" << std::endl;
-
- current_ep_name_ = "";
- return true;
-}
-
bool GeneratorImpl::EmitEntryPointFunction(ast::Function* func) {
make_indent();
diff --git a/src/writer/msl/generator_impl.h b/src/writer/msl/generator_impl.h
index 5852f30..459cac5 100644
--- a/src/writer/msl/generator_impl.h
+++ b/src/writer/msl/generator_impl.h
@@ -118,18 +118,10 @@
/// @returns true if the statement was emitted
bool EmitElse(ast::ElseStatement* stmt);
/// Handles emitting information for an entry point
- /// @param ep the entry point
- /// @returns true if the entry point data was emitted
- bool EmitEntryPointData(ast::EntryPoint* ep);
- /// Handles emitting information for an entry point
/// @param func the entry point function
/// @returns true if the entry point data was emitted
bool EmitEntryPointData(ast::Function* func);
/// Handles emitting the entry point function
- /// @param ep the entry point
- /// @returns true if the entry point function was emitted
- bool EmitEntryPointFunction(ast::EntryPoint* ep);
- /// Handles emitting the entry point function
/// @param func the entry point function
/// @returns true if the entry point function was emitted
bool EmitEntryPointFunction(ast::Function* func);
diff --git a/src/writer/msl/generator_impl_entry_point_test.cc b/src/writer/msl/generator_impl_entry_point_test.cc
deleted file mode 100644
index 74ad69a..0000000
--- a/src/writer/msl/generator_impl_entry_point_test.cc
+++ /dev/null
@@ -1,493 +0,0 @@
-// Copyright 2020 The Tint Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "gtest/gtest.h"
-#include "src/ast/assignment_statement.h"
-#include "src/ast/decorated_variable.h"
-#include "src/ast/entry_point.h"
-#include "src/ast/identifier_expression.h"
-#include "src/ast/location_decoration.h"
-#include "src/ast/member_accessor_expression.h"
-#include "src/ast/module.h"
-#include "src/ast/type/f32_type.h"
-#include "src/ast/type/i32_type.h"
-#include "src/ast/type/vector_type.h"
-#include "src/ast/type/void_type.h"
-#include "src/ast/variable.h"
-#include "src/context.h"
-#include "src/type_determiner.h"
-#include "src/writer/msl/generator_impl.h"
-
-namespace tint {
-namespace writer {
-namespace msl {
-namespace {
-
-using MslGeneratorImplTest = testing::Test;
-
-TEST_F(MslGeneratorImplTest, EmitEntryPointData_Vertex_Input) {
- // [[location(0)]] var<in> foo : f32;
- // [[location(1)]] var<in> bar : i32;
- //
- // struct vtx_main_in {
- // float foo [[attribute(0)]];
- // int bar [[attribute(1)]];
- // };
-
- ast::type::F32Type f32;
- ast::type::I32Type i32;
-
- auto foo_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
-
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::LocationDecoration>(0));
- foo_var->set_decorations(std::move(decos));
-
- auto bar_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("bar", ast::StorageClass::kInput, &i32));
- decos.push_back(std::make_unique<ast::LocationDecoration>(1));
- bar_var->set_decorations(std::move(decos));
-
- Context ctx;
- ast::Module mod;
- TypeDeterminer td(&ctx, &mod);
- td.RegisterVariableForTesting(foo_var.get());
- td.RegisterVariableForTesting(bar_var.get());
-
- mod.AddGlobalVariable(std::move(foo_var));
- mod.AddGlobalVariable(std::move(bar_var));
-
- ast::VariableList params;
- auto func =
- std::make_unique<ast::Function>("vtx_main", std::move(params), &f32);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("foo"),
- std::make_unique<ast::IdentifierExpression>("foo")));
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("bar"),
- std::make_unique<ast::IdentifierExpression>("bar")));
- func->set_body(std::move(body));
-
- mod.AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kVertex, "",
- "vtx_main");
- auto* ep_ptr = ep.get();
-
- mod.AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td.Determine()) << td.error();
-
- GeneratorImpl g(&mod);
- ASSERT_TRUE(g.EmitEntryPointData(ep_ptr)) << g.error();
- EXPECT_EQ(g.result(), R"(struct vtx_main_in {
- float foo [[attribute(0)]];
- int bar [[attribute(1)]];
-};
-
-)");
-}
-
-TEST_F(MslGeneratorImplTest, EmitEntryPointData_Vertex_Output) {
- // [[location(0)]] var<out> foo : f32;
- // [[location(1)]] var<out> bar : i32;
- //
- // struct vtx_main_out {
- // float foo [[user(locn0)]];
- // int bar [[user(locn1)]];
- // };
-
- ast::type::F32Type f32;
- ast::type::I32Type i32;
-
- auto foo_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("foo", ast::StorageClass::kOutput, &f32));
-
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::LocationDecoration>(0));
- foo_var->set_decorations(std::move(decos));
-
- auto bar_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("bar", ast::StorageClass::kOutput, &i32));
- decos.push_back(std::make_unique<ast::LocationDecoration>(1));
- bar_var->set_decorations(std::move(decos));
-
- Context ctx;
- ast::Module mod;
- TypeDeterminer td(&ctx, &mod);
- td.RegisterVariableForTesting(foo_var.get());
- td.RegisterVariableForTesting(bar_var.get());
-
- mod.AddGlobalVariable(std::move(foo_var));
- mod.AddGlobalVariable(std::move(bar_var));
-
- ast::VariableList params;
- auto func =
- std::make_unique<ast::Function>("vtx_main", std::move(params), &f32);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("foo"),
- std::make_unique<ast::IdentifierExpression>("foo")));
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("bar"),
- std::make_unique<ast::IdentifierExpression>("bar")));
- func->set_body(std::move(body));
-
- mod.AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kVertex, "",
- "vtx_main");
- auto* ep_ptr = ep.get();
-
- mod.AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td.Determine()) << td.error();
-
- GeneratorImpl g(&mod);
- ASSERT_TRUE(g.EmitEntryPointData(ep_ptr)) << g.error();
- EXPECT_EQ(g.result(), R"(struct vtx_main_out {
- float foo [[user(locn0)]];
- int bar [[user(locn1)]];
-};
-
-)");
-}
-
-TEST_F(MslGeneratorImplTest, EmitEntryPointData_Fragment_Input) {
- // [[location(0)]] var<in> foo : f32;
- // [[location(1)]] var<in> bar : i32;
- //
- // struct frag_main_in {
- // float foo [[user(locn0)]];
- // int bar [[user(locn1)]];
- // };
-
- ast::type::F32Type f32;
- ast::type::I32Type i32;
-
- auto foo_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
-
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::LocationDecoration>(0));
- foo_var->set_decorations(std::move(decos));
-
- auto bar_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("bar", ast::StorageClass::kInput, &i32));
- decos.push_back(std::make_unique<ast::LocationDecoration>(1));
- bar_var->set_decorations(std::move(decos));
-
- Context ctx;
- ast::Module mod;
- TypeDeterminer td(&ctx, &mod);
- td.RegisterVariableForTesting(foo_var.get());
- td.RegisterVariableForTesting(bar_var.get());
-
- mod.AddGlobalVariable(std::move(foo_var));
- mod.AddGlobalVariable(std::move(bar_var));
-
- ast::VariableList params;
- auto func =
- std::make_unique<ast::Function>("frag_main", std::move(params), &f32);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("foo"),
- std::make_unique<ast::IdentifierExpression>("foo")));
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("bar"),
- std::make_unique<ast::IdentifierExpression>("bar")));
- func->set_body(std::move(body));
-
- mod.AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment,
- "main", "frag_main");
- auto* ep_ptr = ep.get();
-
- mod.AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td.Determine()) << td.error();
-
- GeneratorImpl g(&mod);
- ASSERT_TRUE(g.EmitEntryPointData(ep_ptr)) << g.error();
- EXPECT_EQ(g.result(), R"(struct main_in {
- float foo [[user(locn0)]];
- int bar [[user(locn1)]];
-};
-
-)");
-}
-
-TEST_F(MslGeneratorImplTest, EmitEntryPointData_Fragment_Output) {
- // [[location(0)]] var<out> foo : f32;
- // [[location(1)]] var<out> bar : i32;
- //
- // struct frag_main_out {
- // float foo [[color(0)]];
- // int bar [[color(1)]];
- // };
-
- ast::type::F32Type f32;
- ast::type::I32Type i32;
-
- auto foo_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("foo", ast::StorageClass::kOutput, &f32));
-
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::LocationDecoration>(0));
- foo_var->set_decorations(std::move(decos));
-
- auto bar_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("bar", ast::StorageClass::kOutput, &i32));
- decos.push_back(std::make_unique<ast::LocationDecoration>(1));
- bar_var->set_decorations(std::move(decos));
-
- Context ctx;
- ast::Module mod;
- TypeDeterminer td(&ctx, &mod);
- td.RegisterVariableForTesting(foo_var.get());
- td.RegisterVariableForTesting(bar_var.get());
-
- mod.AddGlobalVariable(std::move(foo_var));
- mod.AddGlobalVariable(std::move(bar_var));
-
- ast::VariableList params;
- auto func =
- std::make_unique<ast::Function>("frag_main", std::move(params), &f32);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("foo"),
- std::make_unique<ast::IdentifierExpression>("foo")));
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("bar"),
- std::make_unique<ast::IdentifierExpression>("bar")));
- func->set_body(std::move(body));
-
- mod.AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment,
- "main", "frag_main");
- auto* ep_ptr = ep.get();
-
- mod.AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td.Determine()) << td.error();
-
- GeneratorImpl g(&mod);
- ASSERT_TRUE(g.EmitEntryPointData(ep_ptr)) << g.error();
- EXPECT_EQ(g.result(), R"(struct main_out {
- float foo [[color(0)]];
- int bar [[color(1)]];
-};
-
-)");
-}
-
-TEST_F(MslGeneratorImplTest, EmitEntryPointData_Compute_Input) {
- // [[location(0)]] var<in> foo : f32;
- // [[location(1)]] var<in> bar : i32;
- //
- // -> Error, not allowed
-
- ast::type::F32Type f32;
- ast::type::I32Type i32;
-
- auto foo_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
-
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::LocationDecoration>(0));
- foo_var->set_decorations(std::move(decos));
-
- auto bar_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("bar", ast::StorageClass::kInput, &i32));
- decos.push_back(std::make_unique<ast::LocationDecoration>(1));
- bar_var->set_decorations(std::move(decos));
-
- Context ctx;
- ast::Module mod;
- TypeDeterminer td(&ctx, &mod);
- td.RegisterVariableForTesting(foo_var.get());
- td.RegisterVariableForTesting(bar_var.get());
-
- mod.AddGlobalVariable(std::move(foo_var));
- mod.AddGlobalVariable(std::move(bar_var));
-
- ast::VariableList params;
- auto func =
- std::make_unique<ast::Function>("comp_main", std::move(params), &f32);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("foo"),
- std::make_unique<ast::IdentifierExpression>("foo")));
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("bar"),
- std::make_unique<ast::IdentifierExpression>("bar")));
- func->set_body(std::move(body));
-
- mod.AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kCompute,
- "main", "comp_main");
- auto* ep_ptr = ep.get();
-
- mod.AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td.Determine()) << td.error();
-
- GeneratorImpl g(&mod);
- ASSERT_FALSE(g.EmitEntryPointData(ep_ptr)) << g.error();
- EXPECT_EQ(g.error(), R"(invalid location variable for pipeline stage)");
-}
-
-TEST_F(MslGeneratorImplTest, EmitEntryPointData_Compute_Output) {
- // [[location(0)]] var<out> foo : f32;
- // [[location(1)]] var<out> bar : i32;
- //
- // -> Error not allowed
-
- ast::type::F32Type f32;
- ast::type::I32Type i32;
-
- auto foo_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("foo", ast::StorageClass::kOutput, &f32));
-
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::LocationDecoration>(0));
- foo_var->set_decorations(std::move(decos));
-
- auto bar_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("bar", ast::StorageClass::kOutput, &i32));
- decos.push_back(std::make_unique<ast::LocationDecoration>(1));
- bar_var->set_decorations(std::move(decos));
-
- Context ctx;
- ast::Module mod;
- TypeDeterminer td(&ctx, &mod);
- td.RegisterVariableForTesting(foo_var.get());
- td.RegisterVariableForTesting(bar_var.get());
-
- mod.AddGlobalVariable(std::move(foo_var));
- mod.AddGlobalVariable(std::move(bar_var));
-
- ast::VariableList params;
- auto func =
- std::make_unique<ast::Function>("comp_main", std::move(params), &f32);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("foo"),
- std::make_unique<ast::IdentifierExpression>("foo")));
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("bar"),
- std::make_unique<ast::IdentifierExpression>("bar")));
- func->set_body(std::move(body));
-
- mod.AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kCompute,
- "main", "comp_main");
- auto* ep_ptr = ep.get();
-
- mod.AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td.Determine()) << td.error();
-
- GeneratorImpl g(&mod);
- ASSERT_FALSE(g.EmitEntryPointData(ep_ptr)) << g.error();
- EXPECT_EQ(g.error(), R"(invalid location variable for pipeline stage)");
-}
-
-TEST_F(MslGeneratorImplTest, EmitEntryPointData_Builtins) {
- // Output builtins go in the output struct, input builtins will be passed
- // as input parameters to the entry point function.
-
- // [[builtin(frag_coord)]] var<in> coord : vec4<f32>;
- // [[builtin(frag_depth)]] var<out> depth : f32;
- //
- // struct main_out {
- // float depth [[depth(any)]];
- // };
-
- ast::type::F32Type f32;
- ast::type::VoidType void_type;
- ast::type::VectorType vec4(&f32, 4);
-
- auto coord_var =
- std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
- "coord", ast::StorageClass::kInput, &vec4));
-
- ast::VariableDecorationList decos;
- decos.push_back(
- std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragCoord));
- coord_var->set_decorations(std::move(decos));
-
- auto depth_var =
- std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
- "depth", ast::StorageClass::kOutput, &f32));
- decos.push_back(
- std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragDepth));
- depth_var->set_decorations(std::move(decos));
-
- Context ctx;
- ast::Module mod;
- TypeDeterminer td(&ctx, &mod);
- td.RegisterVariableForTesting(coord_var.get());
- td.RegisterVariableForTesting(depth_var.get());
-
- mod.AddGlobalVariable(std::move(coord_var));
- mod.AddGlobalVariable(std::move(depth_var));
-
- ast::VariableList params;
- auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
- &void_type);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("depth"),
- std::make_unique<ast::MemberAccessorExpression>(
- std::make_unique<ast::IdentifierExpression>("coord"),
- std::make_unique<ast::IdentifierExpression>("x"))));
- func->set_body(std::move(body));
-
- mod.AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment,
- "main", "frag_main");
- auto* ep_ptr = ep.get();
-
- mod.AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td.Determine()) << td.error();
-
- GeneratorImpl g(&mod);
- ASSERT_TRUE(g.EmitEntryPointData(ep_ptr)) << g.error();
- EXPECT_EQ(g.result(), R"(struct main_out {
- float depth [[depth(any)]];
-};
-
-)");
-}
-
-} // namespace
-} // namespace msl
-} // namespace writer
-} // namespace tint
diff --git a/src/writer/msl/generator_impl_function_test.cc b/src/writer/msl/generator_impl_function_test.cc
index f162b6b..564e286 100644
--- a/src/writer/msl/generator_impl_function_test.cc
+++ b/src/writer/msl/generator_impl_function_test.cc
@@ -135,93 +135,6 @@
)");
}
-TEST_F(MslGeneratorImplTest, Emit_Function_EntryPoint_NoName) {
- ast::type::VoidType void_type;
-
- auto func = std::make_unique<ast::Function>("frag_main", ast::VariableList{},
- &void_type);
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment, "",
- "frag_main");
-
- ast::Module m;
- m.AddFunction(std::move(func));
- m.AddEntryPoint(std::move(ep));
-
- GeneratorImpl g(&m);
- ASSERT_TRUE(g.Generate()) << g.error();
- EXPECT_EQ(g.result(), R"(#include <metal_stdlib>
-
-fragment void frag_main() {
-}
-
-)");
-}
-
-TEST_F(MslGeneratorImplTest, Emit_Function_EntryPoint_WithInOutVars) {
- ast::type::VoidType void_type;
- ast::type::F32Type f32;
-
- auto foo_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
-
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::LocationDecoration>(0));
- foo_var->set_decorations(std::move(decos));
-
- auto bar_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("bar", ast::StorageClass::kOutput, &f32));
- decos.push_back(std::make_unique<ast::LocationDecoration>(1));
- bar_var->set_decorations(std::move(decos));
-
- Context ctx;
- ast::Module mod;
- TypeDeterminer td(&ctx, &mod);
- td.RegisterVariableForTesting(foo_var.get());
- td.RegisterVariableForTesting(bar_var.get());
-
- mod.AddGlobalVariable(std::move(foo_var));
- mod.AddGlobalVariable(std::move(bar_var));
-
- ast::VariableList params;
- auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
- &void_type);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("bar"),
- std::make_unique<ast::IdentifierExpression>("foo")));
- body->append(std::make_unique<ast::ReturnStatement>());
- func->set_body(std::move(body));
-
- mod.AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment, "",
- "frag_main");
- mod.AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td.Determine()) << td.error();
-
- GeneratorImpl g(&mod);
- ASSERT_TRUE(g.Generate()) << g.error();
- EXPECT_EQ(g.result(), R"(#include <metal_stdlib>
-
-struct frag_main_in {
- float foo [[user(locn0)]];
-};
-
-struct frag_main_out {
- float bar [[color(1)]];
-};
-
-fragment frag_main_out frag_main(frag_main_in tint_in [[stage_in]]) {
- frag_main_out tint_out = {};
- tint_out.bar = tint_in.foo;
- return tint_out;
-}
-
-)");
-}
-
TEST_F(MslGeneratorImplTest, Emit_FunctionDecoration_EntryPoint_WithInOutVars) {
ast::type::VoidType void_type;
ast::type::F32Type f32;
@@ -285,74 +198,6 @@
)");
}
-TEST_F(MslGeneratorImplTest, Emit_Function_EntryPoint_WithInOut_Builtins) {
- ast::type::VoidType void_type;
- ast::type::F32Type f32;
- ast::type::VectorType vec4(&f32, 4);
-
- auto coord_var =
- std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
- "coord", ast::StorageClass::kInput, &vec4));
-
- ast::VariableDecorationList decos;
- decos.push_back(
- std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragCoord));
- coord_var->set_decorations(std::move(decos));
-
- auto depth_var =
- std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
- "depth", ast::StorageClass::kOutput, &f32));
- decos.push_back(
- std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragDepth));
- depth_var->set_decorations(std::move(decos));
-
- Context ctx;
- ast::Module mod;
- TypeDeterminer td(&ctx, &mod);
- td.RegisterVariableForTesting(coord_var.get());
- td.RegisterVariableForTesting(depth_var.get());
-
- mod.AddGlobalVariable(std::move(coord_var));
- mod.AddGlobalVariable(std::move(depth_var));
-
- ast::VariableList params;
- auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
- &void_type);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("depth"),
- std::make_unique<ast::MemberAccessorExpression>(
- std::make_unique<ast::IdentifierExpression>("coord"),
- std::make_unique<ast::IdentifierExpression>("x"))));
- body->append(std::make_unique<ast::ReturnStatement>());
- func->set_body(std::move(body));
-
- mod.AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment, "",
- "frag_main");
- mod.AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td.Determine()) << td.error();
-
- GeneratorImpl g(&mod);
- ASSERT_TRUE(g.Generate()) << g.error();
- EXPECT_EQ(g.result(), R"(#include <metal_stdlib>
-
-struct frag_main_out {
- float depth [[depth(any)]];
-};
-
-fragment frag_main_out frag_main(float4 coord [[position]]) {
- frag_main_out tint_out = {};
- tint_out.depth = coord.x;
- return tint_out;
-}
-
-)");
-}
-
TEST_F(MslGeneratorImplTest,
Emit_FunctionDecoration_EntryPoint_WithInOut_Builtins) {
ast::type::VoidType void_type;
@@ -420,62 +265,6 @@
)");
}
-TEST_F(MslGeneratorImplTest, Emit_Function_EntryPoint_With_Uniform) {
- ast::type::VoidType void_type;
- ast::type::F32Type f32;
- ast::type::VectorType vec4(&f32, 4);
-
- auto coord_var =
- std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
- "coord", ast::StorageClass::kUniform, &vec4));
-
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::BindingDecoration>(0));
- decos.push_back(std::make_unique<ast::SetDecoration>(1));
- coord_var->set_decorations(std::move(decos));
-
- Context ctx;
- ast::Module mod;
- TypeDeterminer td(&ctx, &mod);
- td.RegisterVariableForTesting(coord_var.get());
-
- mod.AddGlobalVariable(std::move(coord_var));
-
- ast::VariableList params;
- auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
- &void_type);
-
- auto var =
- std::make_unique<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
- var->set_constructor(std::make_unique<ast::MemberAccessorExpression>(
- std::make_unique<ast::IdentifierExpression>("coord"),
- std::make_unique<ast::IdentifierExpression>("x")));
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::VariableDeclStatement>(std::move(var)));
- body->append(std::make_unique<ast::ReturnStatement>());
- func->set_body(std::move(body));
-
- mod.AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment, "",
- "frag_main");
- mod.AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td.Determine()) << td.error();
-
- GeneratorImpl g(&mod);
- ASSERT_TRUE(g.Generate()) << g.error();
- EXPECT_EQ(g.result(), R"(#include <metal_stdlib>
-
-fragment void frag_main(constant float4& coord [[buffer(0)]]) {
- float v = coord.x;
- return;
-}
-
-)");
-}
-
TEST_F(MslGeneratorImplTest, Emit_FunctionDecoration_EntryPoint_With_Uniform) {
ast::type::VoidType void_type;
ast::type::F32Type f32;
@@ -530,62 +319,6 @@
)");
}
-TEST_F(MslGeneratorImplTest, Emit_Function_EntryPoint_With_StorageBuffer) {
- ast::type::VoidType void_type;
- ast::type::F32Type f32;
- ast::type::VectorType vec4(&f32, 4);
-
- auto coord_var =
- std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
- "coord", ast::StorageClass::kStorageBuffer, &vec4));
-
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::BindingDecoration>(0));
- decos.push_back(std::make_unique<ast::SetDecoration>(1));
- coord_var->set_decorations(std::move(decos));
-
- Context ctx;
- ast::Module mod;
- TypeDeterminer td(&ctx, &mod);
- td.RegisterVariableForTesting(coord_var.get());
-
- mod.AddGlobalVariable(std::move(coord_var));
-
- ast::VariableList params;
- auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
- &void_type);
-
- auto var =
- std::make_unique<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
- var->set_constructor(std::make_unique<ast::MemberAccessorExpression>(
- std::make_unique<ast::IdentifierExpression>("coord"),
- std::make_unique<ast::IdentifierExpression>("x")));
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::VariableDeclStatement>(std::move(var)));
- body->append(std::make_unique<ast::ReturnStatement>());
- func->set_body(std::move(body));
-
- mod.AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment, "",
- "frag_main");
- mod.AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td.Determine()) << td.error();
-
- GeneratorImpl g(&mod);
- ASSERT_TRUE(g.Generate()) << g.error();
- EXPECT_EQ(g.result(), R"(#include <metal_stdlib>
-
-fragment void frag_main(device float4& coord [[buffer(0)]]) {
- float v = coord.x;
- return;
-}
-
-)");
-}
-
TEST_F(MslGeneratorImplTest,
Emit_FunctionDecoration_EntryPoint_With_StorageBuffer) {
ast::type::VoidType void_type;
@@ -641,110 +374,6 @@
)");
}
-TEST_F(MslGeneratorImplTest,
- Emit_Function_Called_By_EntryPoints_WithLocationGlobals_And_Params) {
- ast::type::VoidType void_type;
- ast::type::F32Type f32;
-
- auto foo_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
-
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::LocationDecoration>(0));
- foo_var->set_decorations(std::move(decos));
-
- auto bar_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("bar", ast::StorageClass::kOutput, &f32));
- decos.push_back(std::make_unique<ast::LocationDecoration>(1));
- bar_var->set_decorations(std::move(decos));
-
- auto val_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("val", ast::StorageClass::kOutput, &f32));
- decos.push_back(std::make_unique<ast::LocationDecoration>(0));
- val_var->set_decorations(std::move(decos));
-
- Context ctx;
- ast::Module mod;
- TypeDeterminer td(&ctx, &mod);
- td.RegisterVariableForTesting(foo_var.get());
- td.RegisterVariableForTesting(bar_var.get());
- td.RegisterVariableForTesting(val_var.get());
-
- mod.AddGlobalVariable(std::move(foo_var));
- mod.AddGlobalVariable(std::move(bar_var));
- mod.AddGlobalVariable(std::move(val_var));
-
- ast::VariableList params;
- params.push_back(std::make_unique<ast::Variable>(
- "param", ast::StorageClass::kFunction, &f32));
- auto sub_func =
- std::make_unique<ast::Function>("sub_func", std::move(params), &f32);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("bar"),
- std::make_unique<ast::IdentifierExpression>("foo")));
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("val"),
- std::make_unique<ast::IdentifierExpression>("param")));
- body->append(std::make_unique<ast::ReturnStatement>(
- std::make_unique<ast::IdentifierExpression>("foo")));
- sub_func->set_body(std::move(body));
-
- mod.AddFunction(std::move(sub_func));
-
- auto func_1 = std::make_unique<ast::Function>("frag_1_main",
- std::move(params), &void_type);
-
- ast::ExpressionList expr;
- expr.push_back(std::make_unique<ast::ScalarConstructorExpression>(
- std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-
- body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("bar"),
- std::make_unique<ast::CallExpression>(
- std::make_unique<ast::IdentifierExpression>("sub_func"),
- std::move(expr))));
- body->append(std::make_unique<ast::ReturnStatement>());
- func_1->set_body(std::move(body));
-
- mod.AddFunction(std::move(func_1));
-
- auto ep1 = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment,
- "ep_1", "frag_1_main");
- mod.AddEntryPoint(std::move(ep1));
-
- ASSERT_TRUE(td.Determine()) << td.error();
-
- GeneratorImpl g(&mod);
- ASSERT_TRUE(g.Generate()) << g.error();
- EXPECT_EQ(g.result(), R"(#include <metal_stdlib>
-
-struct ep_1_in {
- float foo [[user(locn0)]];
-};
-
-struct ep_1_out {
- float bar [[color(1)]];
- float val [[color(0)]];
-};
-
-float sub_func_ep_1(thread ep_1_in& tint_in, thread ep_1_out& tint_out, float param) {
- tint_out.bar = tint_in.foo;
- tint_out.val = param;
- return tint_in.foo;
-}
-
-fragment ep_1_out ep_1(ep_1_in tint_in [[stage_in]]) {
- ep_1_out tint_out = {};
- tint_out.bar = sub_func_ep_1(tint_in, tint_out, 1.00000000f);
- return tint_out;
-}
-
-)");
-}
-
TEST_F(
MslGeneratorImplTest,
Emit_FunctionDecoration_Called_By_EntryPoints_WithLocationGlobals_And_Params) {
@@ -849,86 +478,6 @@
}
TEST_F(MslGeneratorImplTest,
- Emit_Function_Called_By_EntryPoints_NoUsedGlobals) {
- ast::type::VoidType void_type;
- ast::type::F32Type f32;
- ast::type::VectorType vec4(&f32, 4);
-
- auto depth_var =
- std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
- "depth", ast::StorageClass::kOutput, &f32));
-
- ast::VariableDecorationList decos;
- decos.push_back(
- std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragDepth));
- depth_var->set_decorations(std::move(decos));
-
- Context ctx;
- ast::Module mod;
- TypeDeterminer td(&ctx, &mod);
- td.RegisterVariableForTesting(depth_var.get());
-
- mod.AddGlobalVariable(std::move(depth_var));
-
- ast::VariableList params;
- params.push_back(std::make_unique<ast::Variable>(
- "param", ast::StorageClass::kFunction, &f32));
- auto sub_func =
- std::make_unique<ast::Function>("sub_func", std::move(params), &f32);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::ReturnStatement>(
- std::make_unique<ast::IdentifierExpression>("param")));
- sub_func->set_body(std::move(body));
-
- mod.AddFunction(std::move(sub_func));
-
- auto func_1 = std::make_unique<ast::Function>("frag_1_main",
- std::move(params), &void_type);
-
- ast::ExpressionList expr;
- expr.push_back(std::make_unique<ast::ScalarConstructorExpression>(
- std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-
- body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("depth"),
- std::make_unique<ast::CallExpression>(
- std::make_unique<ast::IdentifierExpression>("sub_func"),
- std::move(expr))));
- body->append(std::make_unique<ast::ReturnStatement>());
- func_1->set_body(std::move(body));
-
- mod.AddFunction(std::move(func_1));
-
- auto ep1 = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment,
- "ep_1", "frag_1_main");
- mod.AddEntryPoint(std::move(ep1));
-
- ASSERT_TRUE(td.Determine()) << td.error();
-
- GeneratorImpl g(&mod);
- ASSERT_TRUE(g.Generate()) << g.error();
- EXPECT_EQ(g.result(), R"(#include <metal_stdlib>
-
-struct ep_1_out {
- float depth [[depth(any)]];
-};
-
-float sub_func(float param) {
- return param;
-}
-
-fragment ep_1_out ep_1() {
- ep_1_out tint_out = {};
- tint_out.depth = sub_func(1.00000000f);
- return tint_out;
-}
-
-)");
-}
-
-TEST_F(MslGeneratorImplTest,
Emit_FunctionDecoration_Called_By_EntryPoints_NoUsedGlobals) {
ast::type::VoidType void_type;
ast::type::F32Type f32;
@@ -1006,101 +555,6 @@
)");
}
-TEST_F(MslGeneratorImplTest,
- Emit_Function_Called_By_EntryPoints_WithBuiltinGlobals_And_Params) {
- ast::type::VoidType void_type;
- ast::type::F32Type f32;
- ast::type::VectorType vec4(&f32, 4);
-
- auto coord_var =
- std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
- "coord", ast::StorageClass::kInput, &vec4));
-
- ast::VariableDecorationList decos;
- decos.push_back(
- std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragCoord));
- coord_var->set_decorations(std::move(decos));
-
- auto depth_var =
- std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
- "depth", ast::StorageClass::kOutput, &f32));
- decos.push_back(
- std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragDepth));
- depth_var->set_decorations(std::move(decos));
-
- Context ctx;
- ast::Module mod;
- TypeDeterminer td(&ctx, &mod);
- td.RegisterVariableForTesting(coord_var.get());
- td.RegisterVariableForTesting(depth_var.get());
-
- mod.AddGlobalVariable(std::move(coord_var));
- mod.AddGlobalVariable(std::move(depth_var));
-
- ast::VariableList params;
- params.push_back(std::make_unique<ast::Variable>(
- "param", ast::StorageClass::kFunction, &f32));
- auto sub_func =
- std::make_unique<ast::Function>("sub_func", std::move(params), &f32);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("depth"),
- std::make_unique<ast::MemberAccessorExpression>(
- std::make_unique<ast::IdentifierExpression>("coord"),
- std::make_unique<ast::IdentifierExpression>("x"))));
- body->append(std::make_unique<ast::ReturnStatement>(
- std::make_unique<ast::IdentifierExpression>("param")));
- sub_func->set_body(std::move(body));
-
- mod.AddFunction(std::move(sub_func));
-
- auto func_1 = std::make_unique<ast::Function>("frag_1_main",
- std::move(params), &void_type);
-
- ast::ExpressionList expr;
- expr.push_back(std::make_unique<ast::ScalarConstructorExpression>(
- std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-
- body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("depth"),
- std::make_unique<ast::CallExpression>(
- std::make_unique<ast::IdentifierExpression>("sub_func"),
- std::move(expr))));
- body->append(std::make_unique<ast::ReturnStatement>());
- func_1->set_body(std::move(body));
-
- mod.AddFunction(std::move(func_1));
-
- auto ep1 = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment,
- "ep_1", "frag_1_main");
- mod.AddEntryPoint(std::move(ep1));
-
- ASSERT_TRUE(td.Determine()) << td.error();
-
- GeneratorImpl g(&mod);
- ASSERT_TRUE(g.Generate()) << g.error();
- EXPECT_EQ(g.result(), R"(#include <metal_stdlib>
-
-struct ep_1_out {
- float depth [[depth(any)]];
-};
-
-float sub_func_ep_1(thread ep_1_out& tint_out, thread float4& coord, float param) {
- tint_out.depth = coord.x;
- return param;
-}
-
-fragment ep_1_out ep_1(float4 coord [[position]]) {
- ep_1_out tint_out = {};
- tint_out.depth = sub_func_ep_1(tint_out, coord, 1.00000000f);
- return tint_out;
-}
-
-)");
-}
-
TEST_F(
MslGeneratorImplTest,
Emit_FunctionDecoration_Called_By_EntryPoints_WithBuiltinGlobals_And_Params) {
@@ -1195,84 +649,6 @@
)");
}
-TEST_F(MslGeneratorImplTest, Emit_Function_Called_By_EntryPoint_With_Uniform) {
- ast::type::VoidType void_type;
- ast::type::F32Type f32;
- ast::type::VectorType vec4(&f32, 4);
-
- auto coord_var =
- std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
- "coord", ast::StorageClass::kUniform, &vec4));
-
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::BindingDecoration>(0));
- decos.push_back(std::make_unique<ast::SetDecoration>(1));
- coord_var->set_decorations(std::move(decos));
-
- Context ctx;
- ast::Module mod;
- TypeDeterminer td(&ctx, &mod);
- td.RegisterVariableForTesting(coord_var.get());
-
- mod.AddGlobalVariable(std::move(coord_var));
-
- ast::VariableList params;
- params.push_back(std::make_unique<ast::Variable>(
- "param", ast::StorageClass::kFunction, &f32));
- auto sub_func =
- std::make_unique<ast::Function>("sub_func", std::move(params), &f32);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::ReturnStatement>(
- std::make_unique<ast::MemberAccessorExpression>(
- std::make_unique<ast::IdentifierExpression>("coord"),
- std::make_unique<ast::IdentifierExpression>("x"))));
- sub_func->set_body(std::move(body));
-
- mod.AddFunction(std::move(sub_func));
-
- auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
- &void_type);
-
- ast::ExpressionList expr;
- expr.push_back(std::make_unique<ast::ScalarConstructorExpression>(
- std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-
- auto var =
- std::make_unique<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
- var->set_constructor(std::make_unique<ast::CallExpression>(
- std::make_unique<ast::IdentifierExpression>("sub_func"),
- std::move(expr)));
-
- body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::VariableDeclStatement>(std::move(var)));
- body->append(std::make_unique<ast::ReturnStatement>());
- func->set_body(std::move(body));
-
- mod.AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment, "",
- "frag_main");
- mod.AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td.Determine()) << td.error();
-
- GeneratorImpl g(&mod);
- ASSERT_TRUE(g.Generate()) << g.error();
- EXPECT_EQ(g.result(), R"(#include <metal_stdlib>
-
-float sub_func(constant float4& coord, float param) {
- return coord.x;
-}
-
-fragment void frag_main(constant float4& coord [[buffer(0)]]) {
- float v = sub_func(coord, 1.00000000f);
- return;
-}
-
-)");
-}
-
TEST_F(MslGeneratorImplTest,
Emit_FunctionDecoration_Called_By_EntryPoint_With_Uniform) {
ast::type::VoidType void_type;
@@ -1351,85 +727,6 @@
}
TEST_F(MslGeneratorImplTest,
- Emit_Function_Called_By_EntryPoint_With_StorageBuffer) {
- ast::type::VoidType void_type;
- ast::type::F32Type f32;
- ast::type::VectorType vec4(&f32, 4);
-
- auto coord_var =
- std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
- "coord", ast::StorageClass::kStorageBuffer, &vec4));
-
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::BindingDecoration>(0));
- decos.push_back(std::make_unique<ast::SetDecoration>(1));
- coord_var->set_decorations(std::move(decos));
-
- Context ctx;
- ast::Module mod;
- TypeDeterminer td(&ctx, &mod);
- td.RegisterVariableForTesting(coord_var.get());
-
- mod.AddGlobalVariable(std::move(coord_var));
-
- ast::VariableList params;
- params.push_back(std::make_unique<ast::Variable>(
- "param", ast::StorageClass::kFunction, &f32));
- auto sub_func =
- std::make_unique<ast::Function>("sub_func", std::move(params), &f32);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::ReturnStatement>(
- std::make_unique<ast::MemberAccessorExpression>(
- std::make_unique<ast::IdentifierExpression>("coord"),
- std::make_unique<ast::IdentifierExpression>("x"))));
- sub_func->set_body(std::move(body));
-
- mod.AddFunction(std::move(sub_func));
-
- auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
- &void_type);
-
- ast::ExpressionList expr;
- expr.push_back(std::make_unique<ast::ScalarConstructorExpression>(
- std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-
- auto var =
- std::make_unique<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
- var->set_constructor(std::make_unique<ast::CallExpression>(
- std::make_unique<ast::IdentifierExpression>("sub_func"),
- std::move(expr)));
-
- body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::VariableDeclStatement>(std::move(var)));
- body->append(std::make_unique<ast::ReturnStatement>());
- func->set_body(std::move(body));
-
- mod.AddFunction(std::move(func));
-
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment, "",
- "frag_main");
- mod.AddEntryPoint(std::move(ep));
-
- ASSERT_TRUE(td.Determine()) << td.error();
-
- GeneratorImpl g(&mod);
- ASSERT_TRUE(g.Generate()) << g.error();
- EXPECT_EQ(g.result(), R"(#include <metal_stdlib>
-
-float sub_func(device float4& coord, float param) {
- return coord.x;
-}
-
-fragment void frag_main(device float4& coord [[buffer(0)]]) {
- float v = sub_func(coord, 1.00000000f);
- return;
-}
-
-)");
-}
-
-TEST_F(MslGeneratorImplTest,
Emit_FunctionDecoration_Called_By_EntryPoint_With_StorageBuffer) {
ast::type::VoidType void_type;
ast::type::F32Type f32;
@@ -1506,184 +803,6 @@
)");
}
-TEST_F(MslGeneratorImplTest, Emit_Function_Called_Two_EntryPoints_WithGlobals) {
- ast::type::VoidType void_type;
- ast::type::F32Type f32;
-
- auto foo_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
-
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::LocationDecoration>(0));
- foo_var->set_decorations(std::move(decos));
-
- auto bar_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("bar", ast::StorageClass::kOutput, &f32));
- decos.push_back(std::make_unique<ast::LocationDecoration>(1));
- bar_var->set_decorations(std::move(decos));
-
- Context ctx;
- ast::Module mod;
- TypeDeterminer td(&ctx, &mod);
- td.RegisterVariableForTesting(foo_var.get());
- td.RegisterVariableForTesting(bar_var.get());
-
- mod.AddGlobalVariable(std::move(foo_var));
- mod.AddGlobalVariable(std::move(bar_var));
-
- ast::VariableList params;
- auto sub_func =
- std::make_unique<ast::Function>("sub_func", std::move(params), &f32);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("bar"),
- std::make_unique<ast::IdentifierExpression>("foo")));
- body->append(std::make_unique<ast::ReturnStatement>(
- std::make_unique<ast::IdentifierExpression>("foo")));
- sub_func->set_body(std::move(body));
-
- mod.AddFunction(std::move(sub_func));
-
- auto func_1 = std::make_unique<ast::Function>("frag_1_main",
- std::move(params), &void_type);
-
- body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("bar"),
- std::make_unique<ast::CallExpression>(
- std::make_unique<ast::IdentifierExpression>("sub_func"),
- ast::ExpressionList{})));
- body->append(std::make_unique<ast::ReturnStatement>());
- func_1->set_body(std::move(body));
-
- mod.AddFunction(std::move(func_1));
-
- auto ep1 = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment,
- "ep_1", "frag_1_main");
- auto ep2 = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment,
- "ep_2", "frag_1_main");
- mod.AddEntryPoint(std::move(ep1));
- mod.AddEntryPoint(std::move(ep2));
-
- ASSERT_TRUE(td.Determine()) << td.error();
-
- GeneratorImpl g(&mod);
- ASSERT_TRUE(g.Generate()) << g.error();
- EXPECT_EQ(g.result(), R"(#include <metal_stdlib>
-
-struct ep_1_in {
- float foo [[user(locn0)]];
-};
-
-struct ep_1_out {
- float bar [[color(1)]];
-};
-
-struct ep_2_in {
- float foo [[user(locn0)]];
-};
-
-struct ep_2_out {
- float bar [[color(1)]];
-};
-
-float sub_func_ep_1(thread ep_1_in& tint_in, thread ep_1_out& tint_out) {
- tint_out.bar = tint_in.foo;
- return tint_in.foo;
-}
-
-float sub_func_ep_2(thread ep_2_in& tint_in, thread ep_2_out& tint_out) {
- tint_out.bar = tint_in.foo;
- return tint_in.foo;
-}
-
-fragment ep_1_out ep_1(ep_1_in tint_in [[stage_in]]) {
- ep_1_out tint_out = {};
- tint_out.bar = sub_func_ep_1(tint_in, tint_out);
- return tint_out;
-}
-
-fragment ep_2_out ep_2(ep_2_in tint_in [[stage_in]]) {
- ep_2_out tint_out = {};
- tint_out.bar = sub_func_ep_2(tint_in, tint_out);
- return tint_out;
-}
-
-)");
-}
-
-TEST_F(MslGeneratorImplTest,
- Emit_Function_EntryPoints_WithGlobal_Nested_Return) {
- ast::type::VoidType void_type;
- ast::type::F32Type f32;
- ast::type::I32Type i32;
-
- auto bar_var = std::make_unique<ast::DecoratedVariable>(
- std::make_unique<ast::Variable>("bar", ast::StorageClass::kOutput, &f32));
- ast::VariableDecorationList decos;
- decos.push_back(std::make_unique<ast::LocationDecoration>(1));
- bar_var->set_decorations(std::move(decos));
-
- Context ctx;
- ast::Module mod;
- TypeDeterminer td(&ctx, &mod);
- td.RegisterVariableForTesting(bar_var.get());
- mod.AddGlobalVariable(std::move(bar_var));
-
- ast::VariableList params;
- auto func_1 = std::make_unique<ast::Function>("frag_1_main",
- std::move(params), &void_type);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("bar"),
- std::make_unique<ast::ScalarConstructorExpression>(
- std::make_unique<ast::FloatLiteral>(&f32, 1.0f))));
-
- auto list = std::make_unique<ast::BlockStatement>();
- list->append(std::make_unique<ast::ReturnStatement>());
-
- body->append(std::make_unique<ast::IfStatement>(
- std::make_unique<ast::BinaryExpression>(
- ast::BinaryOp::kEqual,
- std::make_unique<ast::ScalarConstructorExpression>(
- std::make_unique<ast::SintLiteral>(&i32, 1)),
- std::make_unique<ast::ScalarConstructorExpression>(
- std::make_unique<ast::SintLiteral>(&i32, 1))),
- std::move(list)));
-
- body->append(std::make_unique<ast::ReturnStatement>());
- func_1->set_body(std::move(body));
-
- mod.AddFunction(std::move(func_1));
-
- auto ep1 = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment,
- "ep_1", "frag_1_main");
- mod.AddEntryPoint(std::move(ep1));
-
- ASSERT_TRUE(td.Determine()) << td.error();
-
- GeneratorImpl g(&mod);
- ASSERT_TRUE(g.Generate()) << g.error();
- EXPECT_EQ(g.result(), R"(#include <metal_stdlib>
-
-struct ep_1_out {
- float bar [[color(1)]];
-};
-
-fragment ep_1_out ep_1() {
- ep_1_out tint_out = {};
- tint_out.bar = 1.00000000f;
- if ((1 == 1)) {
- return tint_out;
- }
- return tint_out;
-}
-
-)");
-}
-
TEST_F(MslGeneratorImplTest,
Emit_FunctionDecoration_EntryPoints_WithGlobal_Nested_Return) {
ast::type::VoidType void_type;
@@ -1754,117 +873,6 @@
}
TEST_F(MslGeneratorImplTest,
- Emit_Function_Called_Two_EntryPoints_WithoutGlobals) {
- ast::type::VoidType void_type;
- ast::type::F32Type f32;
-
- Context ctx;
- ast::Module mod;
- TypeDeterminer td(&ctx, &mod);
-
- ast::VariableList params;
- auto sub_func =
- std::make_unique<ast::Function>("sub_func", std::move(params), &f32);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::ReturnStatement>(
- std::make_unique<ast::ScalarConstructorExpression>(
- std::make_unique<ast::FloatLiteral>(&f32, 1.0))));
- sub_func->set_body(std::move(body));
-
- mod.AddFunction(std::move(sub_func));
-
- auto func_1 = std::make_unique<ast::Function>("frag_1_main",
- std::move(params), &void_type);
-
- auto var = std::make_unique<ast::Variable>(
- "foo", ast::StorageClass::kFunction, &f32);
- var->set_constructor(std::make_unique<ast::CallExpression>(
- std::make_unique<ast::IdentifierExpression>("sub_func"),
- ast::ExpressionList{}));
-
- body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::VariableDeclStatement>(std::move(var)));
- body->append(std::make_unique<ast::ReturnStatement>());
- func_1->set_body(std::move(body));
-
- mod.AddFunction(std::move(func_1));
-
- auto ep1 = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment,
- "ep_1", "frag_1_main");
- auto ep2 = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kFragment,
- "ep_2", "frag_1_main");
- mod.AddEntryPoint(std::move(ep1));
- mod.AddEntryPoint(std::move(ep2));
-
- ASSERT_TRUE(td.Determine()) << td.error();
-
- GeneratorImpl g(&mod);
- ASSERT_TRUE(g.Generate()) << g.error();
- EXPECT_EQ(g.result(), R"(#include <metal_stdlib>
-
-float sub_func() {
- return 1.00000000f;
-}
-
-fragment void ep_1() {
- float foo = sub_func();
- return;
-}
-
-fragment void ep_2() {
- float foo = sub_func();
- return;
-}
-
-)");
-}
-
-TEST_F(MslGeneratorImplTest, Emit_Function_EntryPoint_WithName) {
- ast::type::VoidType void_type;
-
- auto func = std::make_unique<ast::Function>("comp_main", ast::VariableList{},
- &void_type);
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kCompute,
- "my_main", "comp_main");
-
- ast::Module m;
- m.AddFunction(std::move(func));
- m.AddEntryPoint(std::move(ep));
-
- GeneratorImpl g(&m);
- ASSERT_TRUE(g.Generate()) << g.error();
- EXPECT_EQ(g.result(), R"(#include <metal_stdlib>
-
-kernel void my_main() {
-}
-
-)");
-}
-
-TEST_F(MslGeneratorImplTest, Emit_Function_EntryPoint_WithNameCollision) {
- ast::type::VoidType void_type;
-
- auto func = std::make_unique<ast::Function>("comp_main", ast::VariableList{},
- &void_type);
- auto ep = std::make_unique<ast::EntryPoint>(ast::PipelineStage::kCompute,
- "main", "comp_main");
-
- ast::Module m;
- m.AddFunction(std::move(func));
- m.AddEntryPoint(std::move(ep));
-
- GeneratorImpl g(&m);
- ASSERT_TRUE(g.Generate()) << g.error();
- EXPECT_EQ(g.result(), R"(#include <metal_stdlib>
-
-kernel void main_tint_0() {
-}
-
-)");
-}
-
-TEST_F(MslGeneratorImplTest,
Emit_FunctionDecoration_EntryPoint_WithNameCollision) {
ast::type::VoidType void_type;
diff --git a/src/writer/msl/generator_impl_test.cc b/src/writer/msl/generator_impl_test.cc
index af5600e..9f29067 100644
--- a/src/writer/msl/generator_impl_test.cc
+++ b/src/writer/msl/generator_impl_test.cc
@@ -17,11 +17,11 @@
#include <memory>
#include "gtest/gtest.h"
-#include "src/ast/entry_point.h"
#include "src/ast/function.h"
#include "src/ast/identifier_expression.h"
#include "src/ast/module.h"
#include "src/ast/pipeline_stage.h"
+#include "src/ast/stage_decoration.h"
#include "src/ast/struct.h"
#include "src/ast/struct_member.h"
#include "src/ast/struct_member_offset_decoration.h"
@@ -48,10 +48,12 @@
TEST_F(MslGeneratorImplTest, Generate) {
ast::type::VoidType void_type;
ast::Module m;
- m.AddFunction(std::make_unique<ast::Function>("my_func", ast::VariableList{},
- &void_type));
- m.AddEntryPoint(std::make_unique<ast::EntryPoint>(
- ast::PipelineStage::kCompute, "", "my_func"));
+
+ auto func = std::make_unique<ast::Function>("my_func", ast::VariableList{},
+ &void_type);
+ func->add_decoration(
+ std::make_unique<ast::StageDecoration>(ast::PipelineStage::kCompute));
+ m.AddFunction(std::move(func));
GeneratorImpl g(&m);
diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc
index a952234..8bfd9a1 100644
--- a/src/writer/spirv/builder.cc
+++ b/src/writer/spirv/builder.cc
@@ -185,19 +185,6 @@
}
}
- // Note, the entry points must be generated after the functions as they need
- // to be able to lookup the function information based on the name.
- for (const auto& ep : mod_->entry_points()) {
- if (!GenerateEntryPoint(ep.get())) {
- return false;
- }
- }
- for (const auto& ep : mod_->entry_points()) {
- if (!GenerateExecutionModes(ep.get())) {
- return false;
- }
- }
-
return true;
}
@@ -301,52 +288,6 @@
return true;
}
-bool Builder::GenerateEntryPoint(ast::EntryPoint* ep) {
- auto name = ep->name();
- if (name.empty()) {
- name = ep->function_name();
- }
- const auto id = id_for_entry_point(ep);
- if (id == 0) {
- return false;
- }
-
- auto stage = pipeline_stage_to_execution_model(ep->stage());
- if (stage == SpvExecutionModelMax) {
- error_ = "Unknown pipeline stage provided";
- return false;
- }
-
- OperandList operands = {Operand::Int(stage), Operand::Int(id),
- Operand::String(name)};
-
- auto* func = func_name_to_func_[ep->function_name()];
- if (func == nullptr) {
- error_ = "processing an entry point when the function has not been seen.";
- return false;
- }
-
- for (const auto* var : func->referenced_module_variables()) {
- // For SPIR-V 1.3 we only output Input/output variables. If we update to
- // SPIR-V 1.4 or later this should be all variables.
- if (var->storage_class() != ast::StorageClass::kInput &&
- var->storage_class() != ast::StorageClass::kOutput) {
- continue;
- }
-
- uint32_t var_id;
- if (!scope_stack_.get(var->name(), &var_id)) {
- error_ = "unable to find ID for global variable: " + var->name();
- return false;
- }
-
- operands.push_back(Operand::Int(var_id));
- }
- push_preamble(spv::Op::OpEntryPoint, operands);
-
- return true;
-}
-
bool Builder::GenerateEntryPoint(ast::Function* func, uint32_t id) {
auto stage = pipeline_stage_to_execution_model(func->pipeline_stage());
if (stage == SpvExecutionModelMax) {
@@ -378,32 +319,6 @@
return true;
}
-bool Builder::GenerateExecutionModes(ast::EntryPoint* ep) {
- const auto id = id_for_entry_point(ep);
- if (id == 0) {
- return false;
- }
-
- // WGSL fragment shader origin is upper left
- if (ep->stage() == ast::PipelineStage::kFragment) {
- push_preamble(
- spv::Op::OpExecutionMode,
- {Operand::Int(id), Operand::Int(SpvExecutionModeOriginUpperLeft)});
- } else if (ep->stage() == ast::PipelineStage::kCompute) {
- auto* func = func_name_to_func_[ep->function_name()];
-
- uint32_t x = 0;
- uint32_t y = 0;
- uint32_t z = 0;
- std::tie(x, y, z) = func->workgroup_size();
- push_preamble(spv::Op::OpExecutionMode,
- {Operand::Int(id), Operand::Int(SpvExecutionModeLocalSize),
- Operand::Int(x), Operand::Int(y), Operand::Int(z)});
- }
-
- return true;
-}
-
bool Builder::GenerateExecutionModes(ast::Function* func, uint32_t id) {
// WGSL fragment shader origin is upper left
if (func->pipeline_stage() == ast::PipelineStage::kFragment) {
diff --git a/src/writer/spirv/builder.h b/src/writer/spirv/builder.h
index 42d762e..2a467fc 100644
--- a/src/writer/spirv/builder.h
+++ b/src/writer/spirv/builder.h
@@ -185,19 +185,11 @@
/// @returns true if the statement was successfully generated
bool GenerateDiscardStatement(ast::DiscardStatement* stmt);
/// Generates an entry point instruction
- /// @param ep the entry point
- /// @returns true if the instruction was generated, false otherwise
- bool GenerateEntryPoint(ast::EntryPoint* ep);
- /// Generates an entry point instruction
/// @param func the function
/// @param id the id of the function
/// @returns true if the instruction was generated, false otherwise
bool GenerateEntryPoint(ast::Function* func, uint32_t id);
/// Generates execution modes for an entry point
- /// @param ep the entry point
- /// @returns false on failure
- bool GenerateExecutionModes(ast::EntryPoint* ep);
- /// Generates execution modes for an entry point
/// @param func the function
/// @param id the id of the function
/// @returns false on failure
@@ -424,19 +416,6 @@
return func_name_to_id_[name];
}
- /// Retrieves the id for an entry point function, or 0 if not found.
- /// Emits an error if not found.
- /// @param ep the entry point
- /// @returns 0 on error
- uint32_t id_for_entry_point(ast::EntryPoint* ep) {
- auto id = id_for_func_name(ep->function_name());
- if (id == 0) {
- error_ = "unable to find ID for function: " + ep->function_name();
- return 0;
- }
- return id;
- }
-
ast::Module* mod_;
std::string error_;
uint32_t next_id_ = 1;
diff --git a/src/writer/spirv/builder_entry_point_test.cc b/src/writer/spirv/builder_entry_point_test.cc
deleted file mode 100644
index c594edb..0000000
--- a/src/writer/spirv/builder_entry_point_test.cc
+++ /dev/null
@@ -1,242 +0,0 @@
-// Copyright 2020 The Tint Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <string>
-
-#include "gtest/gtest.h"
-#include "spirv/unified1/spirv.h"
-#include "spirv/unified1/spirv.hpp11"
-#include "src/ast/assignment_statement.h"
-#include "src/ast/entry_point.h"
-#include "src/ast/function.h"
-#include "src/ast/identifier_expression.h"
-#include "src/ast/pipeline_stage.h"
-#include "src/ast/type/f32_type.h"
-#include "src/ast/type/void_type.h"
-#include "src/ast/variable.h"
-#include "src/ast/workgroup_decoration.h"
-#include "src/context.h"
-#include "src/type_determiner.h"
-#include "src/writer/spirv/builder.h"
-#include "src/writer/spirv/spv_dump.h"
-
-namespace tint {
-namespace writer {
-namespace spirv {
-namespace {
-
-// TODO(dsinclair): These have all been ported to stage decorations and this
-// whole file can be deleted when we remove EntryPoint.
-
-using BuilderTest = testing::Test;
-
-TEST_F(BuilderTest, EntryPoint) {
- ast::type::VoidType void_type;
-
- ast::Function func("frag_main", {}, &void_type);
- ast::EntryPoint ep(ast::PipelineStage::kFragment, "main", "frag_main");
-
- ast::Module mod;
- Builder b(&mod);
- ASSERT_TRUE(b.GenerateFunction(&func)) << b.error();
- ASSERT_TRUE(b.GenerateEntryPoint(&ep)) << b.error();
-
- EXPECT_EQ(DumpInstructions(b.preamble()), R"(OpEntryPoint Fragment %3 "main"
-)");
-}
-
-TEST_F(BuilderTest, EntryPoint_WithoutName) {
- ast::type::VoidType void_type;
-
- ast::Function func("compute_main", {}, &void_type);
- ast::EntryPoint ep(ast::PipelineStage::kCompute, "", "compute_main");
-
- ast::Module mod;
- Builder b(&mod);
- ASSERT_TRUE(b.GenerateFunction(&func)) << b.error();
- ASSERT_TRUE(b.GenerateEntryPoint(&ep)) << b.error();
-
- EXPECT_EQ(DumpInstructions(b.preamble()),
- R"(OpEntryPoint GLCompute %3 "compute_main"
-)");
-}
-
-TEST_F(BuilderTest, EntryPoint_BadFunction) {
- ast::EntryPoint ep(ast::PipelineStage::kFragment, "main", "frag_main");
-
- ast::Module mod;
- Builder b(&mod);
- EXPECT_FALSE(b.GenerateEntryPoint(&ep));
- EXPECT_EQ(b.error(), "unable to find ID for function: frag_main");
-}
-
-struct EntryPointStageData {
- ast::PipelineStage stage;
- SpvExecutionModel model;
-};
-inline std::ostream& operator<<(std::ostream& out, EntryPointStageData data) {
- out << data.stage;
- return out;
-}
-using EntryPointStageTest = testing::TestWithParam<EntryPointStageData>;
-TEST_P(EntryPointStageTest, Emit) {
- auto params = GetParam();
-
- ast::type::VoidType void_type;
-
- ast::Function func("main", {}, &void_type);
- ast::EntryPoint ep(params.stage, "", "main");
-
- ast::Module mod;
- Builder b(&mod);
- ASSERT_TRUE(b.GenerateFunction(&func)) << b.error();
- ASSERT_TRUE(b.GenerateEntryPoint(&ep)) << b.error();
-
- auto preamble = b.preamble();
- ASSERT_EQ(preamble.size(), 1u);
- EXPECT_EQ(preamble[0].opcode(), spv::Op::OpEntryPoint);
-
- ASSERT_GE(preamble[0].operands().size(), 3u);
- EXPECT_EQ(preamble[0].operands()[0].to_i(), params.model);
-}
-INSTANTIATE_TEST_SUITE_P(
- BuilderTest,
- EntryPointStageTest,
- testing::Values(EntryPointStageData{ast::PipelineStage::kVertex,
- SpvExecutionModelVertex},
- EntryPointStageData{ast::PipelineStage::kFragment,
- SpvExecutionModelFragment},
- EntryPointStageData{ast::PipelineStage::kCompute,
- SpvExecutionModelGLCompute}));
-
-TEST_F(BuilderTest, EntryPoint_WithUnusedInterfaceIds) {
- ast::type::F32Type f32;
- ast::type::VoidType void_type;
-
- ast::Function func("main", {}, &void_type);
-
- auto v_in =
- std::make_unique<ast::Variable>("my_in", ast::StorageClass::kInput, &f32);
- auto v_out = std::make_unique<ast::Variable>(
- "my_out", ast::StorageClass::kOutput, &f32);
- auto v_wg = std::make_unique<ast::Variable>(
- "my_wg", ast::StorageClass::kWorkgroup, &f32);
- ast::EntryPoint ep(ast::PipelineStage::kVertex, "", "main");
-
- ast::Module mod;
- Builder b(&mod);
- EXPECT_TRUE(b.GenerateGlobalVariable(v_in.get())) << b.error();
- EXPECT_TRUE(b.GenerateGlobalVariable(v_out.get())) << b.error();
- EXPECT_TRUE(b.GenerateGlobalVariable(v_wg.get())) << b.error();
-
- mod.AddGlobalVariable(std::move(v_in));
- mod.AddGlobalVariable(std::move(v_out));
- mod.AddGlobalVariable(std::move(v_wg));
-
- ASSERT_TRUE(b.GenerateFunction(&func)) << b.error();
- ASSERT_TRUE(b.GenerateEntryPoint(&ep)) << b.error();
- EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "my_in"
-OpName %4 "my_out"
-OpName %7 "my_wg"
-OpName %11 "main"
-)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
-%2 = OpTypePointer Input %3
-%1 = OpVariable %2 Input
-%5 = OpTypePointer Output %3
-%6 = OpConstantNull %3
-%4 = OpVariable %5 Output %6
-%8 = OpTypePointer Workgroup %3
-%7 = OpVariable %8 Workgroup
-%10 = OpTypeVoid
-%9 = OpTypeFunction %10
-)");
- EXPECT_EQ(DumpInstructions(b.preamble()),
- R"(OpEntryPoint Vertex %11 "main"
-)");
-}
-
-TEST_F(BuilderTest, EntryPoint_WithUsedInterfaceIds) {
- ast::type::F32Type f32;
- ast::type::VoidType void_type;
-
- ast::Function func("main", {}, &void_type);
-
- auto body = std::make_unique<ast::BlockStatement>();
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("my_out"),
- std::make_unique<ast::IdentifierExpression>("my_in")));
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("my_wg"),
- std::make_unique<ast::IdentifierExpression>("my_wg")));
- // Add duplicate usages so we show they don't get output multiple times.
- body->append(std::make_unique<ast::AssignmentStatement>(
- std::make_unique<ast::IdentifierExpression>("my_out"),
- std::make_unique<ast::IdentifierExpression>("my_in")));
- func.set_body(std::move(body));
-
- auto v_in =
- std::make_unique<ast::Variable>("my_in", ast::StorageClass::kInput, &f32);
- auto v_out = std::make_unique<ast::Variable>(
- "my_out", ast::StorageClass::kOutput, &f32);
- auto v_wg = std::make_unique<ast::Variable>(
- "my_wg", ast::StorageClass::kWorkgroup, &f32);
- ast::EntryPoint ep(ast::PipelineStage::kVertex, "", "main");
-
- Context ctx;
- ast::Module mod;
- TypeDeterminer td(&ctx, &mod);
- td.RegisterVariableForTesting(v_in.get());
- td.RegisterVariableForTesting(v_out.get());
- td.RegisterVariableForTesting(v_wg.get());
-
- ASSERT_TRUE(td.DetermineFunction(&func)) << td.error();
-
- Builder b(&mod);
-
- EXPECT_TRUE(b.GenerateGlobalVariable(v_in.get())) << b.error();
- EXPECT_TRUE(b.GenerateGlobalVariable(v_out.get())) << b.error();
- EXPECT_TRUE(b.GenerateGlobalVariable(v_wg.get())) << b.error();
-
- mod.AddGlobalVariable(std::move(v_in));
- mod.AddGlobalVariable(std::move(v_out));
- mod.AddGlobalVariable(std::move(v_wg));
-
- ASSERT_TRUE(b.GenerateFunction(&func)) << b.error();
- ASSERT_TRUE(b.GenerateEntryPoint(&ep)) << b.error();
- EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "my_in"
-OpName %4 "my_out"
-OpName %7 "my_wg"
-OpName %11 "main"
-)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
-%2 = OpTypePointer Input %3
-%1 = OpVariable %2 Input
-%5 = OpTypePointer Output %3
-%6 = OpConstantNull %3
-%4 = OpVariable %5 Output %6
-%8 = OpTypePointer Workgroup %3
-%7 = OpVariable %8 Workgroup
-%10 = OpTypeVoid
-%9 = OpTypeFunction %10
-)");
- EXPECT_EQ(DumpInstructions(b.preamble()),
- R"(OpEntryPoint Vertex %11 "main" %4 %1
-)");
-}
-
-} // namespace
-} // namespace spirv
-} // namespace writer
-} // namespace tint
diff --git a/src/writer/wgsl/generator_impl.cc b/src/writer/wgsl/generator_impl.cc
index 8b9e63c..da4aed2 100644
--- a/src/writer/wgsl/generator_impl.cc
+++ b/src/writer/wgsl/generator_impl.cc
@@ -84,14 +84,6 @@
out_ << std::endl;
}
- for (const auto& ep : module.entry_points()) {
- if (!EmitEntryPoint(ep.get())) {
- return false;
- }
- }
- if (!module.entry_points().empty())
- out_ << std::endl;
-
for (auto* const alias : module.alias_types()) {
if (!EmitAliasType(alias)) {
return false;
@@ -132,27 +124,8 @@
out_ << std::endl;
}
- bool found_entry_point = false;
- std::string ep_function_name = "";
- for (const auto& ep : module.entry_points()) {
- std::string ep_name = ep->name();
- if (ep_name.empty()) {
- ep_name = ep->function_name();
- }
- ep_function_name = ep->function_name();
-
- if (ep->stage() != stage || ep_name != name) {
- continue;
- }
- if (!EmitEntryPoint(ep.get())) {
- return false;
- }
- found_entry_point = true;
- break;
- }
- out_ << std::endl;
-
- if (!found_entry_point) {
+ auto* func = module.FindFunctionByNameAndStage(name, stage);
+ if (func == nullptr) {
error_ = "Unable to find requested entry point: " + name;
return false;
}
@@ -178,12 +151,6 @@
}
}
- auto* func = module.FindFunctionByName(ep_function_name);
- if (!func) {
- error_ = "Unable to find entry point function: " + ep_function_name;
- return false;
- }
-
bool found_func_variable = false;
for (auto* var : func->referenced_module_variables()) {
if (!EmitVariable(var)) {
@@ -225,17 +192,6 @@
return true;
}
-bool GeneratorImpl::EmitEntryPoint(const ast::EntryPoint* ep) {
- make_indent();
- out_ << "entry_point " << ep->stage() << " ";
- if (!ep->name().empty() && ep->name() != ep->function_name()) {
- out_ << R"(as ")" << ep->name() << R"(" )";
- }
- out_ << "= " << ep->function_name() << ";" << std::endl;
-
- return true;
-}
-
bool GeneratorImpl::EmitExpression(ast::Expression* expr) {
if (expr->IsArrayAccessor()) {
return EmitArrayAccessor(expr->AsArrayAccessor());
diff --git a/src/writer/wgsl/generator_impl.h b/src/writer/wgsl/generator_impl.h
index e01b66b..1ae3853 100644
--- a/src/writer/wgsl/generator_impl.h
+++ b/src/writer/wgsl/generator_impl.h
@@ -20,7 +20,6 @@
#include "src/ast/array_accessor_expression.h"
#include "src/ast/constructor_expression.h"
-#include "src/ast/entry_point.h"
#include "src/ast/identifier_expression.h"
#include "src/ast/import.h"
#include "src/ast/module.h"
@@ -116,10 +115,6 @@
/// @param stmt the statement to emit
/// @returns true if the statement was emitted
bool EmitElse(ast::ElseStatement* stmt);
- /// Handles generating an entry_point command
- /// @param ep the entry point
- /// @returns true if the entry point was emitted
- bool EmitEntryPoint(const ast::EntryPoint* ep);
/// Handles generate an Expression
/// @param expr the expression
/// @returns true if the expression was emitted
diff --git a/src/writer/wgsl/generator_impl_entry_point_test.cc b/src/writer/wgsl/generator_impl_entry_point_test.cc
deleted file mode 100644
index bab9e91..0000000
--- a/src/writer/wgsl/generator_impl_entry_point_test.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2020 The Tint Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "gtest/gtest.h"
-#include "src/writer/wgsl/generator_impl.h"
-
-namespace tint {
-namespace writer {
-namespace wgsl {
-namespace {
-
-using WgslGeneratorImplTest = testing::Test;
-
-TEST_F(WgslGeneratorImplTest, EmitEntryPoint_NoName) {
- ast::EntryPoint ep(ast::PipelineStage::kFragment, "", "frag_main");
-
- GeneratorImpl g;
- ASSERT_TRUE(g.EmitEntryPoint(&ep)) << g.error();
- EXPECT_EQ(g.result(), R"(entry_point fragment = frag_main;
-)");
-}
-
-TEST_F(WgslGeneratorImplTest, EmitEntryPoint_WithName) {
- ast::EntryPoint ep(ast::PipelineStage::kFragment, "main", "frag_main");
-
- GeneratorImpl g;
- ASSERT_TRUE(g.EmitEntryPoint(&ep)) << g.error();
- EXPECT_EQ(g.result(), R"(entry_point fragment as "main" = frag_main;
-)");
-}
-
-} // namespace
-} // namespace wgsl
-} // namespace writer
-} // namespace tint
diff --git a/test/compute_boids.wgsl b/test/compute_boids.wgsl
index ba4d2de..16642d2 100644
--- a/test/compute_boids.wgsl
+++ b/test/compute_boids.wgsl
@@ -21,7 +21,8 @@
[[location(2)]] var<in> a_pos : vec2<f32>;
[[builtin(position)]] var<out> gl_Position : vec4<f32>;
-fn vtx_main() -> void {
+[[stage(vertex)]]
+fn vert_main() -> void {
var angle : f32 = -std::atan2(a_particleVel.x, a_particleVel.y);
var pos : vec2<f32> = vec2<f32>(
(a_pos.x * std::cos(angle)) - (a_pos.y * std::sin(angle)),
@@ -29,16 +30,15 @@
gl_Position = vec4<f32>(pos + a_particlePos, 0.0, 1.0);
return;
}
-entry_point vertex as "vert_main" = vtx_main;
# fragment shader
[[location(0)]] var<out> fragColor : vec4<f32>;
+[[stage(fragment)]]
fn frag_main() -> void {
fragColor = vec4<f32>(1.0, 1.0, 1.0, 1.0);
return;
}
-entry_point fragment as "frag_main" = frag_main;
# compute shader
type Particle = [[block]] struct {
@@ -67,7 +67,8 @@
[[builtin(global_invocation_id)]] var<in> gl_GlobalInvocationID : vec3<u32>;
# https://github.com/austinEng/Project6-Vulkan-Flocking/blob/master/data/shaders/computeparticles/particle.comp
-fn compute_main() -> void {
+[[stage(compute)]]
+fn comp_main() -> void {
var index : u32 = gl_GlobalInvocationID.x;
if (index >= 5) {
return;
@@ -149,5 +150,3 @@
return;
}
-entry_point compute as "comp_main" = compute_main;
-
diff --git a/test/cube.wgsl b/test/cube.wgsl
index 6dd5c0a..1a86a89 100644
--- a/test/cube.wgsl
+++ b/test/cube.wgsl
@@ -12,9 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-entry_point vertex = vtx_main;
-entry_point fragment = frag_main;
-
# Vertex shader
type Uniforms = [[block]] struct {
[[offset(0)]] modelViewProjectionMatrix : mat4x4<f32>;
@@ -27,6 +24,7 @@
[[location(0)]] var<out> vtxFragColor : vec4<f32>;
[[builtin(position)]] var<out> Position : vec4<f32>;
+[[stage(vertex)]]
fn vtx_main() -> void {
Position = uniforms.modelViewProjectionMatrix * cur_position;
vtxFragColor = color;
@@ -37,6 +35,7 @@
[[location(0)]] var<in> fragColor : vec4<f32>;
[[location(0)]] var<out> outColor : vec4<f32>;
+[[stage(fragment)]]
fn frag_main() -> void {
outColor = fragColor;
return;
diff --git a/test/simple.wgsl b/test/simple.wgsl
index e8ec8c6..ff5f38e 100644
--- a/test/simple.wgsl
+++ b/test/simple.wgsl
@@ -18,10 +18,10 @@
return;
}
+[[stage(fragment)]]
fn main() -> void {
var a : vec2<f32> = vec2<f32>();
gl_FragColor = vec4<f32>(0.4, 0.4, 0.8, 1.0);
bar();
return;
}
-entry_point fragment = main;
diff --git a/test/switch-case-selector-must-have-the-same-type-as-the-selector-expression-2.fail.wgsl b/test/switch-case-selector-must-have-the-same-type-as-the-selector-expression-2.fail.wgsl
index 288dede..aeb7c4b 100644
--- a/test/switch-case-selector-must-have-the-same-type-as-the-selector-expression-2.fail.wgsl
+++ b/test/switch-case-selector-must-have-the-same-type-as-the-selector-expression-2.fail.wgsl
@@ -1,6 +1,6 @@
# v-switch03: line 7: the case selector values must have the same type as the selector expression
-entry_point vertex = main;
+[[stage(vertex)]]
fn main() -> void {
var a: i32 = -2;
switch (a) {
diff --git a/test/switch-case-selector-must-have-the-same-type-as-the-selector-expression.fail.wgsl b/test/switch-case-selector-must-have-the-same-type-as-the-selector-expression.fail.wgsl
index 3bee45b..a1abbfd 100644
--- a/test/switch-case-selector-must-have-the-same-type-as-the-selector-expression.fail.wgsl
+++ b/test/switch-case-selector-must-have-the-same-type-as-the-selector-expression.fail.wgsl
@@ -1,6 +1,6 @@
# v-switch03: line 7: the case selector values must have the same type as the selector expression
-entry_point vertex = main;
+[[stage(vertex)]]
fn main() -> void {
var a: u32 = 2;
switch (a) {
diff --git a/test/switch-case-selector-value-must-be-unique.fail.wgsl b/test/switch-case-selector-value-must-be-unique.fail.wgsl
index 36efdc2..a16e800 100644
--- a/test/switch-case-selector-value-must-be-unique.fail.wgsl
+++ b/test/switch-case-selector-value-must-be-unique.fail.wgsl
@@ -1,7 +1,7 @@
# v-switch04: line 9: a literal value must not appear more than once in the case selectors for a
# switch statement: '0'
-entry_point vertex = main;
+[[stage(vertex)]]
fn main() -> void {
var a: u32 = 2;
switch (a) {
diff --git a/test/switch-fallthrough-must-not-be-last-stmt-of-last-clause.fail.wgsl b/test/switch-fallthrough-must-not-be-last-stmt-of-last-clause.fail.wgsl
index 99c1a53..0867b62 100644
--- a/test/switch-fallthrough-must-not-be-last-stmt-of-last-clause.fail.wgsl
+++ b/test/switch-fallthrough-must-not-be-last-stmt-of-last-clause.fail.wgsl
@@ -1,7 +1,7 @@
# v-switch05: line 9: a fallthrough statement must not appear as the last statement in last clause
# of a switch
-entry_point vertex = main;
+[[stage(vertex)]]
fn main() -> void {
var a: i32 = -2;
switch (a) {
diff --git a/test/switch-must-have-exactly-one-default-clause-2.fail.wgsl b/test/switch-must-have-exactly-one-default-clause-2.fail.wgsl
index b3178e1..d6720be 100644
--- a/test/switch-must-have-exactly-one-default-clause-2.fail.wgsl
+++ b/test/switch-must-have-exactly-one-default-clause-2.fail.wgsl
@@ -1,6 +1,6 @@
# v-0008: line 6: switch statement must have exactly one default clause
-entry_point vertex = main;
+[[stage(vertex)]]
fn main() -> void {
var a: i32 = 2;
switch (a) {
diff --git a/test/switch-must-have-exactly-one-default-clause.fail.wgsl b/test/switch-must-have-exactly-one-default-clause.fail.wgsl
index b0cfd2d..3d0adf2 100644
--- a/test/switch-must-have-exactly-one-default-clause.fail.wgsl
+++ b/test/switch-must-have-exactly-one-default-clause.fail.wgsl
@@ -1,6 +1,6 @@
# v-0008: line 6: switch statement must have exactly one default clause
-entry_point vertex = main;
+[[stage(vertex)]]
fn main() -> void {
var a: i32 = 2;
switch (a) {
diff --git a/test/switch-selector-expression-must-be-scalar-integer-type.fail.wgsl b/test/switch-selector-expression-must-be-scalar-integer-type.fail.wgsl
index da49514..2fc35a2 100644
--- a/test/switch-selector-expression-must-be-scalar-integer-type.fail.wgsl
+++ b/test/switch-selector-expression-must-be-scalar-integer-type.fail.wgsl
@@ -1,6 +1,6 @@
# v-switch01: line 6: switch statement selector expression must be of a scalar integer type
-entry_point vertex = main;
+[[stage(vertex)]]
fn main() -> void {
var a: f32 = 3.14;
switch (a) {
diff --git a/test/triangle.wgsl b/test/triangle.wgsl
index 44b0425..0159eb6 100644
--- a/test/triangle.wgsl
+++ b/test/triangle.wgsl
@@ -21,16 +21,17 @@
[[builtin(position)]] var<out> Position : vec4<f32>;
[[builtin(vertex_idx)]] var<in> VertexIndex : i32;
+[[stage(vertex)]]
fn vtx_main() -> void {
Position = vec4<f32>(pos[VertexIndex], 0.0, 1.0);
return;
}
-entry_point vertex as "main" = vtx_main;
# Fragment shader
[[location(0)]] var<out> outColor : vec4<f32>;
+
+[[stage(fragment)]]
fn frag_main() -> void {
outColor = vec4<f32>(1.0, 0.0, 0.0, 1.0);
return;
}
-entry_point fragment = frag_main;
diff --git a/test/undefined-variable-global-scope.wgsl b/test/undefined-variable-global-scope.wgsl
index 5fa9fb2..590ec9a 100644
--- a/test/undefined-variable-global-scope.wgsl
+++ b/test/undefined-variable-global-scope.wgsl
@@ -15,9 +15,9 @@
# Vertex shader
var<private> a : i32;
+[[stage(vertex)]]
fn main() -> void {
a = 2;
return;
}
-entry_point vertex as "main" = main;
diff --git a/test/undefined-variable-inner-block.wgsl b/test/undefined-variable-inner-block.wgsl
index 06fc420..0e7f509 100644
--- a/test/undefined-variable-inner-block.wgsl
+++ b/test/undefined-variable-inner-block.wgsl
@@ -12,9 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+[[stage(fragment)]]
fn main() -> void {
var a : f32 = 2.0;
{ a = 3.14;}
return;
}
-entry_point fragment = main;