diff --git a/BUILD.gn b/BUILD.gn index 37366c110f..084ee6fa1e 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -255,8 +255,6 @@ source_set("libtint_core_src") { "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 @@ source_set("tint_unittests_core_src") { "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 @@ source_set("tint_unittests_spv_writer_src") { "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 @@ source_set("tint_unittests_wgsl_reader_src") { "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 @@ source_set("tint_unittests_wgsl_writer_src") { "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 @@ source_set("tint_unittests_msl_writer_src") { "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 @@ source_set("tint_unittests_hlsl_writer_src") { "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 213cc9941a..15c84cd382 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -76,8 +76,6 @@ set(TINT_LIB_SRCS 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 @@ set(TINT_TEST_SRCS 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 @@ if(${TINT_BUILD_WGSL_READER}) 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 @@ if(${TINT_BUILD_SPV_WRITER}) 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 @@ if(${TINT_BUILD_WGSL_WRITER}) 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 @@ if(${TINT_BUILD_MSL_WRITER}) 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 @@ if (${TINT_BUILD_HLSL_WRITER}) 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 69a449395e..0000000000 --- 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 3b4086e2c3..0000000000 --- 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 -#include -#include -#include - -#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>; - -} // 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 0f34fb9f10..0000000000 --- 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 - -#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 ffb4132430..b650a78ef8 100644 --- a/src/ast/module.cc +++ b/src/ast/module.cc @@ -45,12 +45,14 @@ Function* Module::FindFunctionByName(const std::string& name) const { 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 @@ bool Module::IsValid() const { 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 @@ std::string Module::to_str() const { 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 7734026621..cb8f13a197 100644 --- a/src/ast/module.h +++ b/src/ast/module.h @@ -20,7 +20,6 @@ #include #include -#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 @@ class Module { /// @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 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 @@ class Module { /// @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 @@ class Module { ImportList imports_; VariableList global_variables_; - EntryPointList entry_points_; // The alias types are owned by the type manager std::vector alias_types_; FunctionList functions_; diff --git a/src/ast/module_test.cc b/src/ast/module_test.cc index 4cd0ebbaf3..e1cec9679b 100644 --- a/src/ast/module_test.cc +++ b/src/ast/module_test.cc @@ -18,7 +18,6 @@ #include #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 @@ TEST_F(ModuleTest, LookupFunction) { EXPECT_EQ(func_ptr, m.FindFunctionByName("main")); } -TEST_F(ModuleTest, IsEntryPoint) { - type::F32Type f32; - Module m; - - auto func = std::make_unique("other_func", VariableList{}, &f32); - m.AddFunction(std::move(func)); - - m.AddEntryPoint( - std::make_unique(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 @@ TEST_F(ModuleTest, IsValid_Invalid_GlobalVariable) { EXPECT_FALSE(m.IsValid()); } -TEST_F(ModuleTest, IsValid_EntryPoint) { - Module m; - m.AddEntryPoint( - std::make_unique(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()); - 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 9f2fe3da2c..69b9f43745 100644 --- a/src/ast/transform/vertex_pulling_transform.cc +++ b/src/ast/transform/vertex_pulling_transform.cc @@ -77,29 +77,15 @@ bool VertexPullingTransform::Run() { } // 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 070a4c45f4..caf4e4a734 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 @@ class VertexPullingTransformHelper { // Create basic module with an entry point and vertex function void InitBasicModule() { - mod()->AddEntryPoint(std::make_unique(PipelineStage::kVertex, - "main", "vtx_main")); - mod()->AddFunction(std::make_unique( - "vtx_main", VariableList{}, - ctx_.type_mgr().Get(std::make_unique()))); + auto func = std::make_unique( + "main", VariableList{}, + ctx_.type_mgr().Get(std::make_unique())); + func->add_decoration( + std::make_unique(ast::PipelineStage ::kVertex)); + mod()->AddFunction(std::move(func)); } // Set up the transformation, after building the module @@ -71,6 +74,7 @@ class VertexPullingTransformHelper { 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_InvalidEntryPoint) { } TEST_F(VertexPullingTransformTest, Error_EntryPointWrongStage) { - InitBasicModule(); - mod()->entry_points()[0]->set_pipeline_stage(PipelineStage::kFragment); + auto func = std::make_unique( + "main", VariableList{}, + ctx()->type_mgr().Get(std::make_unique())); + func->add_decoration( + std::make_unique(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 @@ TEST_F(VertexPullingTransformTest, BasicModule) { 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 @@ TEST_F(VertexPullingTransformTest, OneAttribute) { storage_buffer __struct_ } - EntryPoint{vertex as main = vtx_main} - Function vtx_main -> __void + Function main -> __void + StageDecoration{vertex} () { Block{ @@ -240,8 +240,8 @@ TEST_F(VertexPullingTransformTest, OneInstancedAttribute) { storage_buffer __struct_ } - EntryPoint{vertex as main = vtx_main} - Function vtx_main -> __void + Function main -> __void + StageDecoration{vertex} () { Block{ @@ -321,8 +321,8 @@ TEST_F(VertexPullingTransformTest, OneAttributeDifferentOutputSet) { storage_buffer __struct_ } - EntryPoint{vertex as main = vtx_main} - Function vtx_main -> __void + Function main -> __void + StageDecoration{vertex} () { Block{ @@ -454,8 +454,8 @@ TEST_F(VertexPullingTransformTest, ExistingVertexIndexAndInstanceIndex) { storage_buffer __struct_ } - EntryPoint{vertex as main = vtx_main} - Function vtx_main -> __void + Function main -> __void + StageDecoration{vertex} () { Block{ @@ -573,8 +573,8 @@ TEST_F(VertexPullingTransformTest, TwoAttributesSameBuffer) { storage_buffer __struct_ } - EntryPoint{vertex as main = vtx_main} - Function vtx_main -> __void + Function main -> __void + StageDecoration{vertex} () { Block{ @@ -777,8 +777,8 @@ TEST_F(VertexPullingTransformTest, FloatVectorAttributes) { 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 9a825b272b..76d71e5097 100644 --- a/src/reader/wgsl/lexer.cc +++ b/src/reader/wgsl/lexer.cc @@ -503,8 +503,6 @@ Token Lexer::check_keyword(const Source& source, const std::string& str) { 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 0254824cd2..1e90cdbf79 100644 --- a/src/reader/wgsl/lexer_test.cc +++ b/src/reader/wgsl/lexer_test.cc @@ -429,7 +429,6 @@ INSTANTIATE_TEST_SUITE_P( 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 cff1b50fb6..6a4162728d 100644 --- a/src/reader/wgsl/parser_impl.cc +++ b/src/reader/wgsl/parser_impl.cc @@ -206,7 +206,6 @@ void ParserImpl::translation_unit() { // | 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 @@ void ParserImpl::global_decl() { 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 @@ ast::VariableList ParserImpl::param_list() { 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 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(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 578b4fdc7e..25749586b3 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 @@ class ParserImpl { /// 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 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 ede75b3bdb..0000000000 --- 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 c04735b6e7..432f2e1d31 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 @@ TEST_F(ParserImplTest, GlobalDecl_GlobalConstant_MissingSemicolon) { 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 154a33a931..7b6a5a000e 100644 --- a/src/reader/wgsl/parser_impl_test.cc +++ b/src/reader/wgsl/parser_impl_test.cc @@ -34,7 +34,7 @@ import "GLSL.std.430" as glsl; [[location(0)]] var gl_FragColor : vec4; -entry_point vertex = main; +[[stage(vertex)]] fn main() -> void { gl_FragColor = vec4(.4, .2, .3, 1); } @@ -43,7 +43,6 @@ fn main() -> void { 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 767c236232..a67751e7e0 100644 --- a/src/reader/wgsl/parser_test.cc +++ b/src/reader/wgsl/parser_test.cc @@ -38,7 +38,7 @@ import "GLSL.std.430" as glsl; [[location(0)]] var gl_FragColor : vec4; -entry_point vertex = main; +[[stage(vertex)]] fn main() -> void { gl_FragColor = vec4(.4, .2, .3, 1); } @@ -47,7 +47,6 @@ fn main() -> void { 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 a5dbea5ced..7afd80c490 100644 --- a/src/reader/wgsl/token.cc +++ b/src/reader/wgsl/token.cc @@ -139,8 +139,6 @@ std::string Token::TypeToName(Type type) { 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 0f5f531f63..c67ef3484d 100644 --- a/src/reader/wgsl/token.h +++ b/src/reader/wgsl/token.h @@ -150,8 +150,6 @@ class Token { kElse, /// A 'elseif' kElseIf, - /// A 'entry_point' - kEntryPoint, /// A 'f32' kF32, /// A 'fallthrough' @@ -531,8 +529,6 @@ class Token { 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 7e62fcf308..7dbfaf15c7 100644 --- a/src/type_determiner.cc +++ b/src/type_determiner.cc @@ -209,14 +209,6 @@ bool TypeDeterminer::Determine() { return false; } - // 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()) { diff --git a/src/type_determiner_test.cc b/src/type_determiner_test.cc index 67821ad17d..f2ce9d64b0 100644 --- a/src/type_determiner_test.cc +++ b/src/type_determiner_test.cc @@ -4373,114 +4373,6 @@ INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest, 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("b", std::move(params), &f32); - auto* func_b_ptr = func_b.get(); - - auto body = std::make_unique(); - func_b->set_body(std::move(body)); - - auto func_c = std::make_unique("c", std::move(params), &f32); - auto* func_c_ptr = func_c.get(); - - body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("second"), - std::make_unique( - std::make_unique("b"), - ast::ExpressionList{}))); - func_c->set_body(std::move(body)); - - auto func_a = std::make_unique("a", std::move(params), &f32); - auto* func_a_ptr = func_a.get(); - - body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("first"), - std::make_unique( - std::make_unique("c"), - ast::ExpressionList{}))); - func_a->set_body(std::move(body)); - - auto ep_1_func = - std::make_unique("ep_1_func", std::move(params), &f32); - auto* ep_1_func_ptr = ep_1_func.get(); - - body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("call_a"), - std::make_unique( - std::make_unique("a"), - ast::ExpressionList{}))); - body->append(std::make_unique( - std::make_unique("call_b"), - std::make_unique( - std::make_unique("b"), - ast::ExpressionList{}))); - ep_1_func->set_body(std::move(body)); - - auto ep_2_func = - std::make_unique("ep_2_func", std::move(params), &f32); - auto* ep_2_func_ptr = ep_2_func.get(); - - body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("call_c"), - std::make_unique( - std::make_unique("c"), - ast::ExpressionList{}))); - ep_2_func->set_body(std::move(body)); - - auto ep_1 = std::make_unique(ast::PipelineStage::kVertex, - "ep_1", "ep_1_func"); - auto ep_2 = std::make_unique(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 ab827f21dc..145b345207 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 @@ TEST_F(ValidateFunctionTest, FunctionTypeMustMatchReturnStatementType_Pass) { 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 e64d9f1c41..2a8ce16815 100644 --- a/src/validator_impl.cc +++ b/src/validator_impl.cc @@ -49,7 +49,7 @@ bool ValidatorImpl::Validate(const ast::Module* module) { if (!CheckImports(module)) { return false; } - if (!ValidateFunctions(module, module->functions())) { + if (!ValidateFunctions(module->functions())) { return false; } @@ -82,8 +82,7 @@ bool ValidatorImpl::ValidateGlobalVariables( return true; } -bool ValidatorImpl::ValidateFunctions(const ast::Module* mod, - const ast::FunctionList& funcs) { +bool ValidatorImpl::ValidateFunctions(const ast::FunctionList& funcs) { ScopeStack entry_point_map; entry_point_map.push_scope(); @@ -135,7 +134,7 @@ bool ValidatorImpl::ValidateFunctions(const ast::Module* mod, 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 81e46f168b..64812923e8 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 @@ class ValidatorImpl { /// @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 @@ class ValidatorImpl { /// @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 b219595423..7fa9229d7f 100644 --- a/src/writer/hlsl/generator_impl.cc +++ b/src/writer/hlsl/generator_impl.cc @@ -134,12 +134,6 @@ bool GeneratorImpl::Generate(std::ostream& out) { } } - 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 @@ bool GeneratorImpl::Generate(std::ostream& out) { 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 @@ bool GeneratorImpl::EmitFunction(std::ostream& out, ast::Function* func) { 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 @@ bool GeneratorImpl::EmitFunctionInternal(std::ostream& out, 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> in_variables; - std::vector> 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> in_variables; std::vector> outvariables; @@ -1608,71 +1402,6 @@ std::string GeneratorImpl::builtin_to_attribute(ast::Builtin builtin) const { return ""; } -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 264c119ccb..798bf87bec 100644 --- a/src/writer/hlsl/generator_impl.h +++ b/src/writer/hlsl/generator_impl.h @@ -193,21 +193,11 @@ class GeneratorImpl { 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 184e7252d4..0000000000 --- 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 foo : f32; - // [[location(1)]] var 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( - std::make_unique("foo", ast::StorageClass::kInput, &f32)); - - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(0)); - foo_var->set_decorations(std::move(decos)); - - auto bar_var = std::make_unique( - std::make_unique("bar", ast::StorageClass::kInput, &i32)); - decos.push_back(std::make_unique(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("vtx_main", std::move(params), &f32); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("foo"), - std::make_unique("foo"))); - body->append(std::make_unique( - std::make_unique("bar"), - std::make_unique("bar"))); - func->set_body(std::move(body)); - - mod()->AddFunction(std::move(func)); - - auto ep = std::make_unique(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 foo : f32; - // [[location(1)]] var 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( - std::make_unique("foo", ast::StorageClass::kOutput, &f32)); - - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(0)); - foo_var->set_decorations(std::move(decos)); - - auto bar_var = std::make_unique( - std::make_unique("bar", ast::StorageClass::kOutput, &i32)); - decos.push_back(std::make_unique(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("vtx_main", std::move(params), &f32); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("foo"), - std::make_unique("foo"))); - body->append(std::make_unique( - std::make_unique("bar"), - std::make_unique("bar"))); - func->set_body(std::move(body)); - - mod()->AddFunction(std::move(func)); - - auto ep = std::make_unique(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 foo : f32; - // [[location(1)]] var 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( - std::make_unique("foo", ast::StorageClass::kInput, &f32)); - - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(0)); - foo_var->set_decorations(std::move(decos)); - - auto bar_var = std::make_unique( - std::make_unique("bar", ast::StorageClass::kInput, &i32)); - decos.push_back(std::make_unique(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("frag_main", std::move(params), &f32); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("foo"), - std::make_unique("foo"))); - body->append(std::make_unique( - std::make_unique("bar"), - std::make_unique("bar"))); - func->set_body(std::move(body)); - - mod()->AddFunction(std::move(func)); - - auto ep = std::make_unique(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 foo : f32; - // [[location(1)]] var 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( - std::make_unique("foo", ast::StorageClass::kOutput, &f32)); - - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(0)); - foo_var->set_decorations(std::move(decos)); - - auto bar_var = std::make_unique( - std::make_unique("bar", ast::StorageClass::kOutput, &i32)); - decos.push_back(std::make_unique(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("frag_main", std::move(params), &f32); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("foo"), - std::make_unique("foo"))); - body->append(std::make_unique( - std::make_unique("bar"), - std::make_unique("bar"))); - func->set_body(std::move(body)); - - mod()->AddFunction(std::move(func)); - - auto ep = std::make_unique(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 foo : f32; - // [[location(1)]] var bar : i32; - // - // -> Error, not allowed - - ast::type::F32Type f32; - ast::type::I32Type i32; - - auto foo_var = std::make_unique( - std::make_unique("foo", ast::StorageClass::kInput, &f32)); - - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(0)); - foo_var->set_decorations(std::move(decos)); - - auto bar_var = std::make_unique( - std::make_unique("bar", ast::StorageClass::kInput, &i32)); - decos.push_back(std::make_unique(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("comp_main", std::move(params), &f32); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("foo"), - std::make_unique("foo"))); - body->append(std::make_unique( - std::make_unique("bar"), - std::make_unique("bar"))); - func->set_body(std::move(body)); - - mod()->AddFunction(std::move(func)); - - auto ep = std::make_unique(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 foo : f32; - // [[location(1)]] var bar : i32; - // - // -> Error not allowed - - ast::type::F32Type f32; - ast::type::I32Type i32; - - auto foo_var = std::make_unique( - std::make_unique("foo", ast::StorageClass::kOutput, &f32)); - - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(0)); - foo_var->set_decorations(std::move(decos)); - - auto bar_var = std::make_unique( - std::make_unique("bar", ast::StorageClass::kOutput, &i32)); - decos.push_back(std::make_unique(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("comp_main", std::move(params), &f32); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("foo"), - std::make_unique("foo"))); - body->append(std::make_unique( - std::make_unique("bar"), - std::make_unique("bar"))); - func->set_body(std::move(body)); - - mod()->AddFunction(std::move(func)); - - auto ep = std::make_unique(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 coord : vec4; - // [[builtin(frag_depth)]] var depth : f32; - // - // struct main_in { - // vector 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(std::make_unique( - "coord", ast::StorageClass::kInput, &vec4)); - - ast::VariableDecorationList decos; - decos.push_back( - std::make_unique(ast::Builtin::kFragCoord)); - coord_var->set_decorations(std::move(decos)); - - auto depth_var = - std::make_unique(std::make_unique( - "depth", ast::StorageClass::kOutput, &f32)); - decos.push_back( - std::make_unique(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("frag_main", std::move(params), - &void_type); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("depth"), - std::make_unique( - std::make_unique("coord"), - std::make_unique("x")))); - func->set_body(std::move(body)); - - mod()->AddFunction(std::move(func)); - - auto ep = std::make_unique(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 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 4a65bef053..04eca180ee 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 4c25dd7c54..86e392f054 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_WithParams) { )"); } -TEST_F(HlslGeneratorImplTest_Function, Emit_Function_EntryPoint_NoName) { - ast::type::VoidType void_type; - - auto func = std::make_unique("frag_main", ast::VariableList{}, - &void_type); - auto ep = std::make_unique(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( - std::make_unique("foo", ast::StorageClass::kInput, &f32)); - - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(0)); - foo_var->set_decorations(std::move(decos)); - - auto bar_var = std::make_unique( - std::make_unique("bar", ast::StorageClass::kOutput, &f32)); - decos.push_back(std::make_unique(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("frag_main", std::move(params), - &void_type); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("bar"), - std::make_unique("foo"))); - body->append(std::make_unique()); - func->set_body(std::move(body)); - - mod()->AddFunction(std::move(func)); - - auto ep = std::make_unique(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; @@ -257,72 +181,6 @@ frag_main_out frag_main(frag_main_in tint_in) { )"); } -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(std::make_unique( - "coord", ast::StorageClass::kInput, &vec4)); - - ast::VariableDecorationList decos; - decos.push_back( - std::make_unique(ast::Builtin::kFragCoord)); - coord_var->set_decorations(std::move(decos)); - - auto depth_var = - std::make_unique(std::make_unique( - "depth", ast::StorageClass::kOutput, &f32)); - decos.push_back( - std::make_unique(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("frag_main", std::move(params), - &void_type); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("depth"), - std::make_unique( - std::make_unique("coord"), - std::make_unique("x")))); - body->append(std::make_unique()); - func->set_body(std::move(body)); - - mod()->AddFunction(std::move(func)); - - auto ep = std::make_unique(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 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; @@ -387,58 +245,6 @@ frag_main_out frag_main(frag_main_in tint_in) { )"); } -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(std::make_unique( - "coord", ast::StorageClass::kUniform, &vec4)); - - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(0)); - decos.push_back(std::make_unique(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("frag_main", std::move(params), - &void_type); - - auto var = - std::make_unique("v", ast::StorageClass::kFunction, &f32); - var->set_constructor(std::make_unique( - std::make_unique("coord"), - std::make_unique("x"))); - - auto body = std::make_unique(); - body->append(std::make_unique(std::move(var))); - body->append(std::make_unique()); - func->set_body(std::move(body)); - - mod()->AddFunction(std::move(func)); - - auto ep = std::make_unique(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 coord; -}; - -void frag_main() { - float v = coord.x; - return; -} - -)"); -} - TEST_F(HlslGeneratorImplTest_Function, Emit_FunctionDecoration_EntryPoint_With_Uniform) { ast::type::VoidType void_type; @@ -490,76 +296,6 @@ void frag_main() { )"); } -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( - "coord", &vec4, ast::StructMemberDecorationList{})); - - auto str = std::make_unique(); - str->set_members(std::move(members)); - - ast::type::StructType s(std::move(str)); - s.set_name("Uniforms"); - auto alias = std::make_unique("Uniforms", &s); - - auto coord_var = - std::make_unique(std::make_unique( - "uniforms", ast::StorageClass::kUniform, alias.get())); - - mod()->AddAliasType(alias.get()); - - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(0)); - decos.push_back(std::make_unique(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("frag_main", std::move(params), - &void_type); - - auto var = - std::make_unique("v", ast::StorageClass::kFunction, &f32); - var->set_constructor(std::make_unique( - std::make_unique( - std::make_unique("uniforms"), - std::make_unique("coord")), - std::make_unique("x"))); - - auto body = std::make_unique(); - body->append(std::make_unique(std::move(var))); - body->append(std::make_unique()); - func->set_body(std::move(body)); - - mod()->AddFunction(std::move(func)); - - auto ep = std::make_unique(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 coord; -}; - -ConstantBuffer 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; @@ -628,74 +364,6 @@ void frag_main() { )"); } -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(0)); - members.push_back( - std::make_unique("a", &i32, std::move(a_deco))); - - ast::StructMemberDecorationList b_deco; - b_deco.push_back(std::make_unique(4)); - members.push_back( - std::make_unique("b", &f32, std::move(b_deco))); - - auto str = std::make_unique(); - str->set_members(std::move(members)); - - ast::type::StructType s(std::move(str)); - s.set_name("Data"); - - auto coord_var = - std::make_unique(std::make_unique( - "coord", ast::StorageClass::kStorageBuffer, &s)); - - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(0)); - decos.push_back(std::make_unique(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("frag_main", std::move(params), - &void_type); - - auto var = - std::make_unique("v", ast::StorageClass::kFunction, &f32); - var->set_constructor(std::make_unique( - std::make_unique("coord"), - std::make_unique("b"))); - - auto body = std::make_unique(); - body->append(std::make_unique(std::move(var))); - body->append(std::make_unique()); - func->set_body(std::move(body)); - - mod()->AddFunction(std::move(func)); - - auto ep = std::make_unique(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; @@ -762,76 +430,6 @@ void frag_main() { )"); } -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(0)); - members.push_back( - std::make_unique("a", &i32, std::move(a_deco))); - - ast::StructMemberDecorationList b_deco; - b_deco.push_back(std::make_unique(4)); - members.push_back( - std::make_unique("b", &f32, std::move(b_deco))); - - auto str = std::make_unique(); - str->set_members(std::move(members)); - - ast::type::StructType s(std::move(str)); - s.set_name("Data"); - - auto coord_var = - std::make_unique(std::make_unique( - "coord", ast::StorageClass::kStorageBuffer, &s)); - - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(0)); - decos.push_back(std::make_unique(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("frag_main", std::move(params), - &void_type); - - auto assign = std::make_unique( - std::make_unique( - std::make_unique("coord"), - std::make_unique("b")), - std::make_unique( - std::make_unique(&f32, 2.0f))); - - auto body = std::make_unique(); - body->append(std::move(assign)); - body->append(std::make_unique()); - func->set_body(std::move(body)); - - mod()->AddFunction(std::move(func)); - - auto ep = std::make_unique(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; @@ -900,103 +498,6 @@ void frag_main() { )"); } -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( - std::make_unique("foo", ast::StorageClass::kInput, &f32)); - - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(0)); - foo_var->set_decorations(std::move(decos)); - - auto bar_var = std::make_unique( - std::make_unique("bar", ast::StorageClass::kOutput, &f32)); - decos.push_back(std::make_unique(1)); - bar_var->set_decorations(std::move(decos)); - - auto val_var = std::make_unique( - std::make_unique("val", ast::StorageClass::kOutput, &f32)); - decos.push_back(std::make_unique(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( - "param", ast::StorageClass::kFunction, &f32)); - auto sub_func = - std::make_unique("sub_func", std::move(params), &f32); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("bar"), - std::make_unique("foo"))); - body->append(std::make_unique( - std::make_unique("val"), - std::make_unique("param"))); - body->append(std::make_unique( - std::make_unique("foo"))); - sub_func->set_body(std::move(body)); - - mod()->AddFunction(std::move(sub_func)); - - auto func_1 = std::make_unique("frag_1_main", - std::move(params), &void_type); - - ast::ExpressionList expr; - expr.push_back(std::make_unique( - std::make_unique(&f32, 1.0f))); - - body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("bar"), - std::make_unique( - std::make_unique("sub_func"), - std::move(expr)))); - body->append(std::make_unique()); - func_1->set_body(std::move(body)); - - mod()->AddFunction(std::move(func_1)); - - auto ep1 = std::make_unique(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) { @@ -1093,79 +594,6 @@ ep_1_out ep_1(ep_1_in tint_in) { )"); } -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(std::make_unique( - "depth", ast::StorageClass::kOutput, &f32)); - - ast::VariableDecorationList decos; - decos.push_back( - std::make_unique(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( - "param", ast::StorageClass::kFunction, &f32)); - auto sub_func = - std::make_unique("sub_func", std::move(params), &f32); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("param"))); - sub_func->set_body(std::move(body)); - - mod()->AddFunction(std::move(sub_func)); - - auto func_1 = std::make_unique("frag_1_main", - std::move(params), &void_type); - - ast::ExpressionList expr; - expr.push_back(std::make_unique( - std::make_unique(&f32, 1.0f))); - - body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("depth"), - std::make_unique( - std::make_unique("sub_func"), - std::move(expr)))); - body->append(std::make_unique()); - func_1->set_body(std::move(body)); - - mod()->AddFunction(std::move(func_1)); - - auto ep1 = std::make_unique(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; @@ -1237,98 +665,6 @@ ep_1_out ep_1() { )"); } -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(std::make_unique( - "coord", ast::StorageClass::kInput, &vec4)); - - ast::VariableDecorationList decos; - decos.push_back( - std::make_unique(ast::Builtin::kFragCoord)); - coord_var->set_decorations(std::move(decos)); - - auto depth_var = - std::make_unique(std::make_unique( - "depth", ast::StorageClass::kOutput, &f32)); - decos.push_back( - std::make_unique(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( - "param", ast::StorageClass::kFunction, &f32)); - auto sub_func = - std::make_unique("sub_func", std::move(params), &f32); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("depth"), - std::make_unique( - std::make_unique("coord"), - std::make_unique("x")))); - body->append(std::make_unique( - std::make_unique("param"))); - sub_func->set_body(std::move(body)); - - mod()->AddFunction(std::move(sub_func)); - - auto func_1 = std::make_unique("frag_1_main", - std::move(params), &void_type); - - ast::ExpressionList expr; - expr.push_back(std::make_unique( - std::make_unique(&f32, 1.0f))); - - body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("depth"), - std::make_unique( - std::make_unique("sub_func"), - std::move(expr)))); - body->append(std::make_unique()); - func_1->set_body(std::move(body)); - - mod()->AddFunction(std::move(func_1)); - - auto ep1 = std::make_unique(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 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) { @@ -1420,82 +756,6 @@ ep_1_out ep_1(ep_1_in tint_in) { )"); } -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(std::make_unique( - "coord", ast::StorageClass::kUniform, &vec4)); - - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(0)); - decos.push_back(std::make_unique(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( - "param", ast::StorageClass::kFunction, &f32)); - auto sub_func = - std::make_unique("sub_func", std::move(params), &f32); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique( - std::make_unique("coord"), - std::make_unique("x")))); - sub_func->set_body(std::move(body)); - - mod()->AddFunction(std::move(sub_func)); - - auto func = std::make_unique("frag_main", std::move(params), - &void_type); - - ast::ExpressionList expr; - expr.push_back(std::make_unique( - std::make_unique(&f32, 1.0f))); - - auto var = - std::make_unique("v", ast::StorageClass::kFunction, &f32); - var->set_constructor(std::make_unique( - std::make_unique("sub_func"), - std::move(expr))); - - body = std::make_unique(); - body->append(std::make_unique(std::move(var))); - body->append(std::make_unique()); - func->set_body(std::move(body)); - - mod()->AddFunction(std::move(func)); - - auto ep = std::make_unique(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 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; @@ -1570,80 +830,6 @@ void frag_main() { )"); } -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(std::make_unique( - "coord", ast::StorageClass::kStorageBuffer, &vec4)); - - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(0)); - decos.push_back(std::make_unique(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( - "param", ast::StorageClass::kFunction, &f32)); - auto sub_func = - std::make_unique("sub_func", std::move(params), &f32); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique( - std::make_unique("coord"), - std::make_unique("x")))); - sub_func->set_body(std::move(body)); - - mod()->AddFunction(std::move(sub_func)); - - auto func = std::make_unique("frag_main", std::move(params), - &void_type); - - ast::ExpressionList expr; - expr.push_back(std::make_unique( - std::make_unique(&f32, 1.0f))); - - auto var = - std::make_unique("v", ast::StorageClass::kFunction, &f32); - var->set_constructor(std::make_unique( - std::make_unique("sub_func"), - std::move(expr))); - - body = std::make_unique(); - body->append(std::make_unique(std::move(var))); - body->append(std::make_unique()); - func->set_body(std::move(body)); - - mod()->AddFunction(std::move(func)); - - auto ep = std::make_unique(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; @@ -1716,171 +902,6 @@ void frag_main() { )"); } -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( - std::make_unique("foo", ast::StorageClass::kInput, &f32)); - - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(0)); - foo_var->set_decorations(std::move(decos)); - - auto bar_var = std::make_unique( - std::make_unique("bar", ast::StorageClass::kOutput, &f32)); - decos.push_back(std::make_unique(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("sub_func", std::move(params), &f32); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("bar"), - std::make_unique("foo"))); - body->append(std::make_unique( - std::make_unique("foo"))); - sub_func->set_body(std::move(body)); - - mod()->AddFunction(std::move(sub_func)); - - auto func_1 = std::make_unique("frag_1_main", - std::move(params), &void_type); - - body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("bar"), - std::make_unique( - std::make_unique("sub_func"), - ast::ExpressionList{}))); - body->append(std::make_unique()); - func_1->set_body(std::move(body)); - - mod()->AddFunction(std::move(func_1)); - - auto ep1 = std::make_unique(ast::PipelineStage::kFragment, - "ep_1", "frag_1_main"); - auto ep2 = std::make_unique(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( - std::make_unique("bar", ast::StorageClass::kOutput, &f32)); - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(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("frag_1_main", - std::move(params), &void_type); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("bar"), - std::make_unique( - std::make_unique(&f32, 1.0f)))); - - auto list = std::make_unique(); - list->append(std::make_unique()); - - body->append(std::make_unique( - std::make_unique( - ast::BinaryOp::kEqual, - std::make_unique( - std::make_unique(&i32, 1)), - std::make_unique( - std::make_unique(&i32, 1))), - std::move(list))); - - body->append(std::make_unique()); - func_1->set_body(std::move(body)); - - mod()->AddFunction(std::move(func_1)); - - auto ep1 = std::make_unique(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; @@ -1943,103 +964,6 @@ ep_1_out ep_1() { )"); } -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("sub_func", std::move(params), &f32); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique( - std::make_unique(&f32, 1.0)))); - sub_func->set_body(std::move(body)); - - mod()->AddFunction(std::move(sub_func)); - - auto func_1 = std::make_unique("frag_1_main", - std::move(params), &void_type); - - auto var = std::make_unique( - "foo", ast::StorageClass::kFunction, &f32); - var->set_constructor(std::make_unique( - std::make_unique("sub_func"), - ast::ExpressionList{})); - - body = std::make_unique(); - body->append(std::make_unique(std::move(var))); - body->append(std::make_unique()); - func_1->set_body(std::move(body)); - - mod()->AddFunction(std::move(func_1)); - - auto ep1 = std::make_unique(ast::PipelineStage::kFragment, - "ep_1", "frag_1_main"); - auto ep2 = std::make_unique(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("frag_main", ast::VariableList{}, - &void_type); - auto ep = std::make_unique(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("frag_main", ast::VariableList{}, - &void_type); - auto ep = std::make_unique(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, )"); } -TEST_F(HlslGeneratorImplTest_Function, Emit_Function_EntryPoint_Compute) { - ast::type::VoidType void_type; - - ast::VariableList params; - auto func = std::make_unique("comp_main", std::move(params), - &void_type); - - auto body = std::make_unique(); - body->append(std::make_unique()); - func->set_body(std::move(body)); - - mod()->AddFunction(std::move(func)); - - auto ep = std::make_unique(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; @@ -2111,35 +1008,6 @@ void main() { )"); } -TEST_F(HlslGeneratorImplTest_Function, - Emit_Function_EntryPoint_Compute_WithWorkgroup) { - ast::type::VoidType void_type; - - ast::VariableList params; - auto func = std::make_unique("comp_main", std::move(params), - &void_type); - func->add_decoration(std::make_unique(2u, 4u, 6u)); - - auto body = std::make_unique(); - body->append(std::make_unique()); - func->set_body(std::move(body)); - - mod()->AddFunction(std::move(func)); - - auto ep = std::make_unique(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 4055bb9f38..26b7003167 100644 --- a/src/writer/hlsl/generator_impl_test.cc +++ b/src/writer/hlsl/generator_impl_test.cc @@ -14,7 +14,6 @@ #include -#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 @@ using HlslGeneratorImplTest = TestHelper; TEST_F(HlslGeneratorImplTest, Generate) { ast::type::VoidType void_type; - mod()->AddFunction(std::make_unique( - "my_func", ast::VariableList{}, &void_type)); - mod()->AddEntryPoint(std::make_unique( - ast::PipelineStage::kFragment, "", "my_func")); + auto func = std::make_unique("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 34c9d6bdc8..c6d45f7cc3 100644 --- a/src/writer/msl/generator_impl.cc +++ b/src/writer/msl/generator_impl.cc @@ -124,12 +124,6 @@ bool GeneratorImpl::Generate() { } } - 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 @@ bool GeneratorImpl::Generate() { } } - 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 @@ bool GeneratorImpl::EmitLiteral(ast::Literal* lit) { 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> in_locations; - std::vector> - 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> in_locations; std::vector> @@ -1230,7 +1091,7 @@ bool GeneratorImpl::EmitFunction(ast::Function* func) { 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 @@ std::string GeneratorImpl::builtin_to_attribute(ast::Builtin builtin) const { 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 5852f30491..459cac5517 100644 --- a/src/writer/msl/generator_impl.h +++ b/src/writer/msl/generator_impl.h @@ -118,18 +118,10 @@ class GeneratorImpl : public TextGenerator { /// @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 74ad69acdd..0000000000 --- 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 foo : f32; - // [[location(1)]] var 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( - std::make_unique("foo", ast::StorageClass::kInput, &f32)); - - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(0)); - foo_var->set_decorations(std::move(decos)); - - auto bar_var = std::make_unique( - std::make_unique("bar", ast::StorageClass::kInput, &i32)); - decos.push_back(std::make_unique(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("vtx_main", std::move(params), &f32); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("foo"), - std::make_unique("foo"))); - body->append(std::make_unique( - std::make_unique("bar"), - std::make_unique("bar"))); - func->set_body(std::move(body)); - - mod.AddFunction(std::move(func)); - - auto ep = std::make_unique(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 foo : f32; - // [[location(1)]] var 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( - std::make_unique("foo", ast::StorageClass::kOutput, &f32)); - - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(0)); - foo_var->set_decorations(std::move(decos)); - - auto bar_var = std::make_unique( - std::make_unique("bar", ast::StorageClass::kOutput, &i32)); - decos.push_back(std::make_unique(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("vtx_main", std::move(params), &f32); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("foo"), - std::make_unique("foo"))); - body->append(std::make_unique( - std::make_unique("bar"), - std::make_unique("bar"))); - func->set_body(std::move(body)); - - mod.AddFunction(std::move(func)); - - auto ep = std::make_unique(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 foo : f32; - // [[location(1)]] var 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( - std::make_unique("foo", ast::StorageClass::kInput, &f32)); - - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(0)); - foo_var->set_decorations(std::move(decos)); - - auto bar_var = std::make_unique( - std::make_unique("bar", ast::StorageClass::kInput, &i32)); - decos.push_back(std::make_unique(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("frag_main", std::move(params), &f32); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("foo"), - std::make_unique("foo"))); - body->append(std::make_unique( - std::make_unique("bar"), - std::make_unique("bar"))); - func->set_body(std::move(body)); - - mod.AddFunction(std::move(func)); - - auto ep = std::make_unique(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 foo : f32; - // [[location(1)]] var 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( - std::make_unique("foo", ast::StorageClass::kOutput, &f32)); - - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(0)); - foo_var->set_decorations(std::move(decos)); - - auto bar_var = std::make_unique( - std::make_unique("bar", ast::StorageClass::kOutput, &i32)); - decos.push_back(std::make_unique(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("frag_main", std::move(params), &f32); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("foo"), - std::make_unique("foo"))); - body->append(std::make_unique( - std::make_unique("bar"), - std::make_unique("bar"))); - func->set_body(std::move(body)); - - mod.AddFunction(std::move(func)); - - auto ep = std::make_unique(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 foo : f32; - // [[location(1)]] var bar : i32; - // - // -> Error, not allowed - - ast::type::F32Type f32; - ast::type::I32Type i32; - - auto foo_var = std::make_unique( - std::make_unique("foo", ast::StorageClass::kInput, &f32)); - - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(0)); - foo_var->set_decorations(std::move(decos)); - - auto bar_var = std::make_unique( - std::make_unique("bar", ast::StorageClass::kInput, &i32)); - decos.push_back(std::make_unique(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("comp_main", std::move(params), &f32); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("foo"), - std::make_unique("foo"))); - body->append(std::make_unique( - std::make_unique("bar"), - std::make_unique("bar"))); - func->set_body(std::move(body)); - - mod.AddFunction(std::move(func)); - - auto ep = std::make_unique(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 foo : f32; - // [[location(1)]] var bar : i32; - // - // -> Error not allowed - - ast::type::F32Type f32; - ast::type::I32Type i32; - - auto foo_var = std::make_unique( - std::make_unique("foo", ast::StorageClass::kOutput, &f32)); - - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(0)); - foo_var->set_decorations(std::move(decos)); - - auto bar_var = std::make_unique( - std::make_unique("bar", ast::StorageClass::kOutput, &i32)); - decos.push_back(std::make_unique(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("comp_main", std::move(params), &f32); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("foo"), - std::make_unique("foo"))); - body->append(std::make_unique( - std::make_unique("bar"), - std::make_unique("bar"))); - func->set_body(std::move(body)); - - mod.AddFunction(std::move(func)); - - auto ep = std::make_unique(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 coord : vec4; - // [[builtin(frag_depth)]] var 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(std::make_unique( - "coord", ast::StorageClass::kInput, &vec4)); - - ast::VariableDecorationList decos; - decos.push_back( - std::make_unique(ast::Builtin::kFragCoord)); - coord_var->set_decorations(std::move(decos)); - - auto depth_var = - std::make_unique(std::make_unique( - "depth", ast::StorageClass::kOutput, &f32)); - decos.push_back( - std::make_unique(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("frag_main", std::move(params), - &void_type); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("depth"), - std::make_unique( - std::make_unique("coord"), - std::make_unique("x")))); - func->set_body(std::move(body)); - - mod.AddFunction(std::move(func)); - - auto ep = std::make_unique(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 f162b6b28b..564e286078 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_WithParams) { )"); } -TEST_F(MslGeneratorImplTest, Emit_Function_EntryPoint_NoName) { - ast::type::VoidType void_type; - - auto func = std::make_unique("frag_main", ast::VariableList{}, - &void_type); - auto ep = std::make_unique(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 - -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( - std::make_unique("foo", ast::StorageClass::kInput, &f32)); - - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(0)); - foo_var->set_decorations(std::move(decos)); - - auto bar_var = std::make_unique( - std::make_unique("bar", ast::StorageClass::kOutput, &f32)); - decos.push_back(std::make_unique(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("frag_main", std::move(params), - &void_type); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("bar"), - std::make_unique("foo"))); - body->append(std::make_unique()); - func->set_body(std::move(body)); - - mod.AddFunction(std::move(func)); - - auto ep = std::make_unique(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 - -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 @@ fragment frag_main_out frag_main(frag_main_in tint_in [[stage_in]]) { )"); } -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(std::make_unique( - "coord", ast::StorageClass::kInput, &vec4)); - - ast::VariableDecorationList decos; - decos.push_back( - std::make_unique(ast::Builtin::kFragCoord)); - coord_var->set_decorations(std::move(decos)); - - auto depth_var = - std::make_unique(std::make_unique( - "depth", ast::StorageClass::kOutput, &f32)); - decos.push_back( - std::make_unique(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("frag_main", std::move(params), - &void_type); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("depth"), - std::make_unique( - std::make_unique("coord"), - std::make_unique("x")))); - body->append(std::make_unique()); - func->set_body(std::move(body)); - - mod.AddFunction(std::move(func)); - - auto ep = std::make_unique(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 - -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 @@ fragment frag_main_out frag_main(float4 coord [[position]]) { )"); } -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(std::make_unique( - "coord", ast::StorageClass::kUniform, &vec4)); - - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(0)); - decos.push_back(std::make_unique(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("frag_main", std::move(params), - &void_type); - - auto var = - std::make_unique("v", ast::StorageClass::kFunction, &f32); - var->set_constructor(std::make_unique( - std::make_unique("coord"), - std::make_unique("x"))); - - auto body = std::make_unique(); - body->append(std::make_unique(std::move(var))); - body->append(std::make_unique()); - func->set_body(std::move(body)); - - mod.AddFunction(std::move(func)); - - auto ep = std::make_unique(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 - -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 @@ fragment void frag_main(constant float4& coord [[buffer(0)]]) { )"); } -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(std::make_unique( - "coord", ast::StorageClass::kStorageBuffer, &vec4)); - - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(0)); - decos.push_back(std::make_unique(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("frag_main", std::move(params), - &void_type); - - auto var = - std::make_unique("v", ast::StorageClass::kFunction, &f32); - var->set_constructor(std::make_unique( - std::make_unique("coord"), - std::make_unique("x"))); - - auto body = std::make_unique(); - body->append(std::make_unique(std::move(var))); - body->append(std::make_unique()); - func->set_body(std::move(body)); - - mod.AddFunction(std::move(func)); - - auto ep = std::make_unique(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 - -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 @@ fragment void frag_main(device float4& coord [[buffer(0)]]) { )"); } -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( - std::make_unique("foo", ast::StorageClass::kInput, &f32)); - - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(0)); - foo_var->set_decorations(std::move(decos)); - - auto bar_var = std::make_unique( - std::make_unique("bar", ast::StorageClass::kOutput, &f32)); - decos.push_back(std::make_unique(1)); - bar_var->set_decorations(std::move(decos)); - - auto val_var = std::make_unique( - std::make_unique("val", ast::StorageClass::kOutput, &f32)); - decos.push_back(std::make_unique(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( - "param", ast::StorageClass::kFunction, &f32)); - auto sub_func = - std::make_unique("sub_func", std::move(params), &f32); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("bar"), - std::make_unique("foo"))); - body->append(std::make_unique( - std::make_unique("val"), - std::make_unique("param"))); - body->append(std::make_unique( - std::make_unique("foo"))); - sub_func->set_body(std::move(body)); - - mod.AddFunction(std::move(sub_func)); - - auto func_1 = std::make_unique("frag_1_main", - std::move(params), &void_type); - - ast::ExpressionList expr; - expr.push_back(std::make_unique( - std::make_unique(&f32, 1.0f))); - - body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("bar"), - std::make_unique( - std::make_unique("sub_func"), - std::move(expr)))); - body->append(std::make_unique()); - func_1->set_body(std::move(body)); - - mod.AddFunction(std::move(func_1)); - - auto ep1 = std::make_unique(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 - -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) { @@ -848,86 +477,6 @@ fragment ep_1_out ep_1(ep_1_in tint_in [[stage_in]]) { )"); } -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(std::make_unique( - "depth", ast::StorageClass::kOutput, &f32)); - - ast::VariableDecorationList decos; - decos.push_back( - std::make_unique(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( - "param", ast::StorageClass::kFunction, &f32)); - auto sub_func = - std::make_unique("sub_func", std::move(params), &f32); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("param"))); - sub_func->set_body(std::move(body)); - - mod.AddFunction(std::move(sub_func)); - - auto func_1 = std::make_unique("frag_1_main", - std::move(params), &void_type); - - ast::ExpressionList expr; - expr.push_back(std::make_unique( - std::make_unique(&f32, 1.0f))); - - body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("depth"), - std::make_unique( - std::make_unique("sub_func"), - std::move(expr)))); - body->append(std::make_unique()); - func_1->set_body(std::move(body)); - - mod.AddFunction(std::move(func_1)); - - auto ep1 = std::make_unique(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 - -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; @@ -1006,101 +555,6 @@ fragment ep_1_out ep_1() { )"); } -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(std::make_unique( - "coord", ast::StorageClass::kInput, &vec4)); - - ast::VariableDecorationList decos; - decos.push_back( - std::make_unique(ast::Builtin::kFragCoord)); - coord_var->set_decorations(std::move(decos)); - - auto depth_var = - std::make_unique(std::make_unique( - "depth", ast::StorageClass::kOutput, &f32)); - decos.push_back( - std::make_unique(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( - "param", ast::StorageClass::kFunction, &f32)); - auto sub_func = - std::make_unique("sub_func", std::move(params), &f32); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("depth"), - std::make_unique( - std::make_unique("coord"), - std::make_unique("x")))); - body->append(std::make_unique( - std::make_unique("param"))); - sub_func->set_body(std::move(body)); - - mod.AddFunction(std::move(sub_func)); - - auto func_1 = std::make_unique("frag_1_main", - std::move(params), &void_type); - - ast::ExpressionList expr; - expr.push_back(std::make_unique( - std::make_unique(&f32, 1.0f))); - - body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("depth"), - std::make_unique( - std::make_unique("sub_func"), - std::move(expr)))); - body->append(std::make_unique()); - func_1->set_body(std::move(body)); - - mod.AddFunction(std::move(func_1)); - - auto ep1 = std::make_unique(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 - -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 @@ fragment ep_1_out ep_1(float4 coord [[position]]) { )"); } -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(std::make_unique( - "coord", ast::StorageClass::kUniform, &vec4)); - - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(0)); - decos.push_back(std::make_unique(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( - "param", ast::StorageClass::kFunction, &f32)); - auto sub_func = - std::make_unique("sub_func", std::move(params), &f32); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique( - std::make_unique("coord"), - std::make_unique("x")))); - sub_func->set_body(std::move(body)); - - mod.AddFunction(std::move(sub_func)); - - auto func = std::make_unique("frag_main", std::move(params), - &void_type); - - ast::ExpressionList expr; - expr.push_back(std::make_unique( - std::make_unique(&f32, 1.0f))); - - auto var = - std::make_unique("v", ast::StorageClass::kFunction, &f32); - var->set_constructor(std::make_unique( - std::make_unique("sub_func"), - std::move(expr))); - - body = std::make_unique(); - body->append(std::make_unique(std::move(var))); - body->append(std::make_unique()); - func->set_body(std::move(body)); - - mod.AddFunction(std::move(func)); - - auto ep = std::make_unique(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 - -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; @@ -1350,85 +726,6 @@ fragment void frag_main(constant float4& coord [[buffer(0)]]) { )"); } -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(std::make_unique( - "coord", ast::StorageClass::kStorageBuffer, &vec4)); - - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(0)); - decos.push_back(std::make_unique(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( - "param", ast::StorageClass::kFunction, &f32)); - auto sub_func = - std::make_unique("sub_func", std::move(params), &f32); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique( - std::make_unique("coord"), - std::make_unique("x")))); - sub_func->set_body(std::move(body)); - - mod.AddFunction(std::move(sub_func)); - - auto func = std::make_unique("frag_main", std::move(params), - &void_type); - - ast::ExpressionList expr; - expr.push_back(std::make_unique( - std::make_unique(&f32, 1.0f))); - - auto var = - std::make_unique("v", ast::StorageClass::kFunction, &f32); - var->set_constructor(std::make_unique( - std::make_unique("sub_func"), - std::move(expr))); - - body = std::make_unique(); - body->append(std::make_unique(std::move(var))); - body->append(std::make_unique()); - func->set_body(std::move(body)); - - mod.AddFunction(std::move(func)); - - auto ep = std::make_unique(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 - -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; @@ -1506,184 +803,6 @@ fragment void frag_main(device float4& coord [[buffer(0)]]) { )"); } -TEST_F(MslGeneratorImplTest, Emit_Function_Called_Two_EntryPoints_WithGlobals) { - ast::type::VoidType void_type; - ast::type::F32Type f32; - - auto foo_var = std::make_unique( - std::make_unique("foo", ast::StorageClass::kInput, &f32)); - - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(0)); - foo_var->set_decorations(std::move(decos)); - - auto bar_var = std::make_unique( - std::make_unique("bar", ast::StorageClass::kOutput, &f32)); - decos.push_back(std::make_unique(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("sub_func", std::move(params), &f32); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("bar"), - std::make_unique("foo"))); - body->append(std::make_unique( - std::make_unique("foo"))); - sub_func->set_body(std::move(body)); - - mod.AddFunction(std::move(sub_func)); - - auto func_1 = std::make_unique("frag_1_main", - std::move(params), &void_type); - - body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("bar"), - std::make_unique( - std::make_unique("sub_func"), - ast::ExpressionList{}))); - body->append(std::make_unique()); - func_1->set_body(std::move(body)); - - mod.AddFunction(std::move(func_1)); - - auto ep1 = std::make_unique(ast::PipelineStage::kFragment, - "ep_1", "frag_1_main"); - auto ep2 = std::make_unique(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 - -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( - std::make_unique("bar", ast::StorageClass::kOutput, &f32)); - ast::VariableDecorationList decos; - decos.push_back(std::make_unique(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("frag_1_main", - std::move(params), &void_type); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique("bar"), - std::make_unique( - std::make_unique(&f32, 1.0f)))); - - auto list = std::make_unique(); - list->append(std::make_unique()); - - body->append(std::make_unique( - std::make_unique( - ast::BinaryOp::kEqual, - std::make_unique( - std::make_unique(&i32, 1)), - std::make_unique( - std::make_unique(&i32, 1))), - std::move(list))); - - body->append(std::make_unique()); - func_1->set_body(std::move(body)); - - mod.AddFunction(std::move(func_1)); - - auto ep1 = std::make_unique(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 - -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; @@ -1753,117 +872,6 @@ fragment ep_1_out ep_1() { )"); } -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("sub_func", std::move(params), &f32); - - auto body = std::make_unique(); - body->append(std::make_unique( - std::make_unique( - std::make_unique(&f32, 1.0)))); - sub_func->set_body(std::move(body)); - - mod.AddFunction(std::move(sub_func)); - - auto func_1 = std::make_unique("frag_1_main", - std::move(params), &void_type); - - auto var = std::make_unique( - "foo", ast::StorageClass::kFunction, &f32); - var->set_constructor(std::make_unique( - std::make_unique("sub_func"), - ast::ExpressionList{})); - - body = std::make_unique(); - body->append(std::make_unique(std::move(var))); - body->append(std::make_unique()); - func_1->set_body(std::move(body)); - - mod.AddFunction(std::move(func_1)); - - auto ep1 = std::make_unique(ast::PipelineStage::kFragment, - "ep_1", "frag_1_main"); - auto ep2 = std::make_unique(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 - -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("comp_main", ast::VariableList{}, - &void_type); - auto ep = std::make_unique(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 - -kernel void my_main() { -} - -)"); -} - -TEST_F(MslGeneratorImplTest, Emit_Function_EntryPoint_WithNameCollision) { - ast::type::VoidType void_type; - - auto func = std::make_unique("comp_main", ast::VariableList{}, - &void_type); - auto ep = std::make_unique(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 - -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 af5600e6ff..9f29067706 100644 --- a/src/writer/msl/generator_impl_test.cc +++ b/src/writer/msl/generator_impl_test.cc @@ -17,11 +17,11 @@ #include #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 @@ using MslGeneratorImplTest = testing::Test; TEST_F(MslGeneratorImplTest, Generate) { ast::type::VoidType void_type; ast::Module m; - m.AddFunction(std::make_unique("my_func", ast::VariableList{}, - &void_type)); - m.AddEntryPoint(std::make_unique( - ast::PipelineStage::kCompute, "", "my_func")); + + auto func = std::make_unique("my_func", ast::VariableList{}, + &void_type); + func->add_decoration( + std::make_unique(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 a952234956..8bfd9a17d3 100644 --- a/src/writer/spirv/builder.cc +++ b/src/writer/spirv/builder.cc @@ -185,19 +185,6 @@ bool Builder::Build() { } } - // 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 @@ bool Builder::GenerateDiscardStatement(ast::DiscardStatement*) { 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 @@ bool Builder::GenerateEntryPoint(ast::Function* func, uint32_t id) { 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 42d762eb5a..2a467fcaa4 100644 --- a/src/writer/spirv/builder.h +++ b/src/writer/spirv/builder.h @@ -185,19 +185,11 @@ class Builder { /// @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 @@ class Builder { 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 c594edbb06..0000000000 --- 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 - -#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; -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("my_in", ast::StorageClass::kInput, &f32); - auto v_out = std::make_unique( - "my_out", ast::StorageClass::kOutput, &f32); - auto v_wg = std::make_unique( - "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(); - body->append(std::make_unique( - std::make_unique("my_out"), - std::make_unique("my_in"))); - body->append(std::make_unique( - std::make_unique("my_wg"), - std::make_unique("my_wg"))); - // Add duplicate usages so we show they don't get output multiple times. - body->append(std::make_unique( - std::make_unique("my_out"), - std::make_unique("my_in"))); - func.set_body(std::move(body)); - - auto v_in = - std::make_unique("my_in", ast::StorageClass::kInput, &f32); - auto v_out = std::make_unique( - "my_out", ast::StorageClass::kOutput, &f32); - auto v_wg = std::make_unique( - "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 8b9e63c6e2..da4aed20c1 100644 --- a/src/writer/wgsl/generator_impl.cc +++ b/src/writer/wgsl/generator_impl.cc @@ -84,14 +84,6 @@ bool GeneratorImpl::Generate(const ast::Module& module) { 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 @@ bool GeneratorImpl::GenerateEntryPoint(const ast::Module& module, 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 @@ bool GeneratorImpl::GenerateEntryPoint(const ast::Module& module, } } - 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 @@ bool GeneratorImpl::EmitAliasType(const ast::type::AliasType* alias) { 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 e01b66b620..1ae3853ccc 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 @@ class GeneratorImpl : public TextGenerator { /// @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 bab9e91f1b..0000000000 --- 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 ba4d2deb26..16642d2e7d 100644 --- a/test/compute_boids.wgsl +++ b/test/compute_boids.wgsl @@ -21,7 +21,8 @@ import "GLSL.std.450" as std; [[location(2)]] var a_pos : vec2; [[builtin(position)]] var gl_Position : vec4; -fn vtx_main() -> void { +[[stage(vertex)]] +fn vert_main() -> void { var angle : f32 = -std::atan2(a_particleVel.x, a_particleVel.y); var pos : vec2 = vec2( (a_pos.x * std::cos(angle)) - (a_pos.y * std::sin(angle)), @@ -29,16 +30,15 @@ fn vtx_main() -> void { gl_Position = vec4(pos + a_particlePos, 0.0, 1.0); return; } -entry_point vertex as "vert_main" = vtx_main; # fragment shader [[location(0)]] var fragColor : vec4; +[[stage(fragment)]] fn frag_main() -> void { fragColor = vec4(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 @@ type Particles = [[block]] struct { [[builtin(global_invocation_id)]] var gl_GlobalInvocationID : vec3; # 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 @@ fn compute_main() -> void { return; } -entry_point compute as "comp_main" = compute_main; - diff --git a/test/cube.wgsl b/test/cube.wgsl index 6dd5c0a8fa..1a86a89536 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; @@ -27,6 +24,7 @@ type Uniforms = [[block]] struct { [[location(0)]] var vtxFragColor : vec4; [[builtin(position)]] var Position : vec4; +[[stage(vertex)]] fn vtx_main() -> void { Position = uniforms.modelViewProjectionMatrix * cur_position; vtxFragColor = color; @@ -37,6 +35,7 @@ fn vtx_main() -> void { [[location(0)]] var fragColor : vec4; [[location(0)]] var outColor : vec4; +[[stage(fragment)]] fn frag_main() -> void { outColor = fragColor; return; diff --git a/test/simple.wgsl b/test/simple.wgsl index e8ec8c69e0..ff5f38e6a2 100644 --- a/test/simple.wgsl +++ b/test/simple.wgsl @@ -18,10 +18,10 @@ fn bar() -> void { return; } +[[stage(fragment)]] fn main() -> void { var a : vec2 = vec2(); gl_FragColor = vec4(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 288dede975..aeb7c4b336 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 3bee45b8a8..a1abbfdb36 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 36efdc21fa..a16e80002b 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 99c1a5392d..0867b62b2f 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 b3178e1d66..d6720bef1d 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 b0cfd2d508..3d0adf2b06 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 da4951466d..2fc35a2ab5 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 44b0425d3f..0159eb6d5a 100644 --- a/test/triangle.wgsl +++ b/test/triangle.wgsl @@ -21,16 +21,17 @@ const pos : array, 3> = array, 3>( [[builtin(position)]] var Position : vec4; [[builtin(vertex_idx)]] var VertexIndex : i32; +[[stage(vertex)]] fn vtx_main() -> void { Position = vec4(pos[VertexIndex], 0.0, 1.0); return; } -entry_point vertex as "main" = vtx_main; # Fragment shader [[location(0)]] var outColor : vec4; + +[[stage(fragment)]] fn frag_main() -> void { outColor = vec4(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 5fa9fb2314..590ec9aead 100644 --- a/test/undefined-variable-global-scope.wgsl +++ b/test/undefined-variable-global-scope.wgsl @@ -15,9 +15,9 @@ # Vertex shader var 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 06fc420004..0e7f509260 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;