Add In/Out variables to returned EntryPoint
BUG=tint:257 Change-Id: Iec0dca854dfa6380991c04544848c24f21496a93 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/29524 Commit-Queue: Ryan Harrison <rharrison@chromium.org> Reviewed-by: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
parent
1a63c49b4e
commit
5118c07261
|
@ -113,6 +113,8 @@ class Function : public Node {
|
||||||
/// is not already included.
|
/// is not already included.
|
||||||
/// @param var the module variable to add
|
/// @param var the module variable to add
|
||||||
void add_referenced_module_variable(Variable* var);
|
void add_referenced_module_variable(Variable* var);
|
||||||
|
/// Note: If this function calls other functions, the return will also include
|
||||||
|
/// all of the referenced variables from the callees.
|
||||||
/// @returns the referenced module variables
|
/// @returns the referenced module variables
|
||||||
const std::vector<Variable*>& referenced_module_variables() const {
|
const std::vector<Variable*>& referenced_module_variables() const {
|
||||||
return referenced_module_vars_;
|
return referenced_module_vars_;
|
||||||
|
|
|
@ -14,22 +14,41 @@
|
||||||
|
|
||||||
#include "src/inspector.h"
|
#include "src/inspector.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include "src/ast/function.h"
|
#include "src/ast/function.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace inspector {
|
namespace inspector {
|
||||||
|
|
||||||
|
EntryPoint::EntryPoint() = default;
|
||||||
|
EntryPoint::EntryPoint(EntryPoint&) = default;
|
||||||
|
EntryPoint::EntryPoint(EntryPoint&&) = default;
|
||||||
|
EntryPoint::~EntryPoint() = default;
|
||||||
|
|
||||||
Inspector::Inspector(const ast::Module& module) : module_(module) {}
|
Inspector::Inspector(const ast::Module& module) : module_(module) {}
|
||||||
|
|
||||||
Inspector::~Inspector() = default;
|
Inspector::~Inspector() = default;
|
||||||
|
|
||||||
std::vector<EntryPoint> Inspector::GetEntryPoints() {
|
std::vector<EntryPoint> Inspector::GetEntryPoints() {
|
||||||
std::vector<EntryPoint> result;
|
std::vector<EntryPoint> result;
|
||||||
|
|
||||||
for (const auto& func : module_.functions()) {
|
for (const auto& func : module_.functions()) {
|
||||||
if (func->IsEntryPoint()) {
|
if (func->IsEntryPoint()) {
|
||||||
uint32_t x, y, z;
|
EntryPoint entry_point;
|
||||||
std::tie(x, y, z) = func->workgroup_size();
|
entry_point.name = func->name();
|
||||||
result.push_back({func->name(), func->pipeline_stage(), x, y, z});
|
entry_point.stage = func->pipeline_stage();
|
||||||
|
std::tie(entry_point.workgroup_size_x, entry_point.workgroup_size_y,
|
||||||
|
entry_point.workgroup_size_z) = func->workgroup_size();
|
||||||
|
|
||||||
|
for (auto* var : func->referenced_module_variables()) {
|
||||||
|
if (var->storage_class() == ast::StorageClass::kInput) {
|
||||||
|
entry_point.input_variables.push_back(var->name());
|
||||||
|
} else {
|
||||||
|
entry_point.output_variables.push_back(var->name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.push_back(std::move(entry_point));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,12 @@ namespace inspector {
|
||||||
|
|
||||||
/// Container of reflection data for an entry point in the shader.
|
/// Container of reflection data for an entry point in the shader.
|
||||||
struct EntryPoint {
|
struct EntryPoint {
|
||||||
|
/// Constructors
|
||||||
|
EntryPoint();
|
||||||
|
EntryPoint(EntryPoint&);
|
||||||
|
EntryPoint(EntryPoint&&);
|
||||||
|
~EntryPoint();
|
||||||
|
|
||||||
/// The entry point name
|
/// The entry point name
|
||||||
std::string name;
|
std::string name;
|
||||||
/// The entry point stage
|
/// The entry point stage
|
||||||
|
@ -38,6 +44,10 @@ struct EntryPoint {
|
||||||
uint32_t workgroup_size_y;
|
uint32_t workgroup_size_y;
|
||||||
/// The workgroup z size
|
/// The workgroup z size
|
||||||
uint32_t workgroup_size_z;
|
uint32_t workgroup_size_z;
|
||||||
|
/// List of the input variable accessed via this entry point.
|
||||||
|
std::vector<std::string> input_variables;
|
||||||
|
/// List of the output variable accessed via this entry point.
|
||||||
|
std::vector<std::string> output_variables;
|
||||||
|
|
||||||
/// @returns the size of the workgroup in {x,y,z} format
|
/// @returns the size of the workgroup in {x,y,z} format
|
||||||
std::tuple<uint32_t, uint32_t, uint32_t> workgroup_size() {
|
std::tuple<uint32_t, uint32_t, uint32_t> workgroup_size() {
|
||||||
|
|
|
@ -15,12 +15,19 @@
|
||||||
#include "src/inspector.h"
|
#include "src/inspector.h"
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
#include "src/ast/assignment_statement.h"
|
||||||
|
#include "src/ast/call_expression.h"
|
||||||
|
#include "src/ast/call_statement.h"
|
||||||
#include "src/ast/function.h"
|
#include "src/ast/function.h"
|
||||||
|
#include "src/ast/identifier_expression.h"
|
||||||
#include "src/ast/pipeline_stage.h"
|
#include "src/ast/pipeline_stage.h"
|
||||||
|
#include "src/ast/return_statement.h"
|
||||||
#include "src/ast/stage_decoration.h"
|
#include "src/ast/stage_decoration.h"
|
||||||
|
#include "src/ast/type/u32_type.h"
|
||||||
#include "src/ast/type/void_type.h"
|
#include "src/ast/type/void_type.h"
|
||||||
#include "src/ast/workgroup_decoration.h"
|
#include "src/ast/workgroup_decoration.h"
|
||||||
#include "src/context.h"
|
#include "src/context.h"
|
||||||
|
#include "src/type_determiner.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace inspector {
|
namespace inspector {
|
||||||
|
@ -29,33 +36,135 @@ namespace {
|
||||||
class InspectorHelper {
|
class InspectorHelper {
|
||||||
public:
|
public:
|
||||||
InspectorHelper()
|
InspectorHelper()
|
||||||
: mod_(std::make_unique<ast::Module>()),
|
: td_(std::make_unique<TypeDeterminer>(&ctx_, &mod_)),
|
||||||
inspector_(std::make_unique<Inspector>(*mod_)) {}
|
inspector_(std::make_unique<Inspector>(mod_)) {}
|
||||||
|
|
||||||
void AddFunction(const std::string& name, ast::PipelineStage stage) {
|
/// Generates an empty function
|
||||||
auto func = std::make_unique<ast::Function>(
|
/// @param name name of the function created
|
||||||
name, ast::VariableList{},
|
/// @returns a function object
|
||||||
ctx_.type_mgr().Get(std::make_unique<ast::type::VoidType>()));
|
std::unique_ptr<ast::Function> GenerateEmptyBodyFunction(std::string name) {
|
||||||
if (stage != ast::PipelineStage::kNone) {
|
auto body = std::make_unique<ast::BlockStatement>();
|
||||||
func->add_decoration(std::make_unique<ast::StageDecoration>(stage));
|
body->append(std::make_unique<ast::ReturnStatement>());
|
||||||
|
std::unique_ptr<ast::Function> func =
|
||||||
|
std::make_unique<ast::Function>(name, ast::VariableList(), void_type());
|
||||||
|
func->set_body(std::move(body));
|
||||||
|
return func;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generates a function that calls another
|
||||||
|
/// @param caller name of the function created
|
||||||
|
/// @param callee name of the function to be called
|
||||||
|
/// @returns a function object
|
||||||
|
std::unique_ptr<ast::Function> GenerateCallerBodyFunction(
|
||||||
|
std::string caller,
|
||||||
|
std::string callee) {
|
||||||
|
auto body = std::make_unique<ast::BlockStatement>();
|
||||||
|
auto ident_expr = std::make_unique<ast::IdentifierExpression>(callee);
|
||||||
|
auto call_expr = std::make_unique<ast::CallExpression>(
|
||||||
|
std::move(ident_expr), ast::ExpressionList());
|
||||||
|
body->append(std::make_unique<ast::CallStatement>(std::move(call_expr)));
|
||||||
|
body->append(std::make_unique<ast::ReturnStatement>());
|
||||||
|
std::unique_ptr<ast::Function> func = std::make_unique<ast::Function>(
|
||||||
|
caller, ast::VariableList(), void_type());
|
||||||
|
func->set_body(std::move(body));
|
||||||
|
return func;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add In/Out variables to the global variables
|
||||||
|
/// @param inout_vars tuples of {in, out} that will be added as entries to the
|
||||||
|
/// global variables
|
||||||
|
void CreateInOutVariables(
|
||||||
|
std::vector<std::tuple<std::string, std::string>> inout_vars) {
|
||||||
|
for (auto inout : inout_vars) {
|
||||||
|
std::string in, out;
|
||||||
|
std::tie(in, out) = inout;
|
||||||
|
auto in_var = std::make_unique<ast::Variable>(
|
||||||
|
in, ast::StorageClass::kInput, u32_type());
|
||||||
|
auto out_var = std::make_unique<ast::Variable>(
|
||||||
|
out, ast::StorageClass::kOutput, u32_type());
|
||||||
|
mod()->AddGlobalVariable(std::move(in_var));
|
||||||
|
mod()->AddGlobalVariable(std::move(out_var));
|
||||||
}
|
}
|
||||||
last_function_ = func.get();
|
|
||||||
mod()->AddFunction(std::move(func));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddWorkGroupSizeToLastFunction(uint32_t x, uint32_t y, uint32_t z) {
|
/// Generates a function that references in/out variables
|
||||||
last_function_->add_decoration(
|
/// @param name name of the function created
|
||||||
std::make_unique<ast::WorkgroupDecoration>(x, y, z));
|
/// @param inout_vars tuples of {in, out} that will be converted into out = in
|
||||||
|
/// calls in the function body
|
||||||
|
/// @returns a function object
|
||||||
|
std::unique_ptr<ast::Function> GenerateInOutVariableBodyFunction(
|
||||||
|
std::string name,
|
||||||
|
std::vector<std::tuple<std::string, std::string>> inout_vars) {
|
||||||
|
auto body = std::make_unique<ast::BlockStatement>();
|
||||||
|
for (auto inout : inout_vars) {
|
||||||
|
std::string in, out;
|
||||||
|
std::tie(in, out) = inout;
|
||||||
|
body->append(std::make_unique<ast::AssignmentStatement>(
|
||||||
|
std::make_unique<ast::IdentifierExpression>(out),
|
||||||
|
std::make_unique<ast::IdentifierExpression>(in)));
|
||||||
|
}
|
||||||
|
body->append(std::make_unique<ast::ReturnStatement>());
|
||||||
|
auto func =
|
||||||
|
std::make_unique<ast::Function>(name, ast::VariableList(), void_type());
|
||||||
|
func->set_body(std::move(body));
|
||||||
|
return func;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::Module* mod() { return mod_.get(); }
|
/// Generates a function that references in/out variables and calls another
|
||||||
|
/// function.
|
||||||
|
/// @param caller name of the function created
|
||||||
|
/// @param callee name of the function to be called
|
||||||
|
/// @param inout_vars tuples of {in, out} that will be converted into out = in
|
||||||
|
/// calls in the function body
|
||||||
|
/// @returns a function object
|
||||||
|
std::unique_ptr<ast::Function> GenerateInOutVariableCallerBodyFunction(
|
||||||
|
std::string caller,
|
||||||
|
std::string callee,
|
||||||
|
std::vector<std::tuple<std::string, std::string>> inout_vars) {
|
||||||
|
auto body = std::make_unique<ast::BlockStatement>();
|
||||||
|
for (auto inout : inout_vars) {
|
||||||
|
std::string in, out;
|
||||||
|
std::tie(in, out) = inout;
|
||||||
|
body->append(std::make_unique<ast::AssignmentStatement>(
|
||||||
|
std::make_unique<ast::IdentifierExpression>(out),
|
||||||
|
std::make_unique<ast::IdentifierExpression>(in)));
|
||||||
|
}
|
||||||
|
auto ident_expr = std::make_unique<ast::IdentifierExpression>(callee);
|
||||||
|
auto call_expr = std::make_unique<ast::CallExpression>(
|
||||||
|
std::move(ident_expr), ast::ExpressionList());
|
||||||
|
body->append(std::make_unique<ast::CallStatement>(std::move(call_expr)));
|
||||||
|
body->append(std::make_unique<ast::ReturnStatement>());
|
||||||
|
auto func = std::make_unique<ast::Function>(caller, ast::VariableList(),
|
||||||
|
void_type());
|
||||||
|
func->set_body(std::move(body));
|
||||||
|
return func;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ContainsString(const std::vector<std::string>& vec,
|
||||||
|
const std::string& str) {
|
||||||
|
for (auto& s : vec) {
|
||||||
|
if (s == str) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ast::Module* mod() { return &mod_; }
|
||||||
|
TypeDeterminer* td() { return td_.get(); }
|
||||||
Inspector* inspector() { return inspector_.get(); }
|
Inspector* inspector() { return inspector_.get(); }
|
||||||
|
|
||||||
|
ast::type::VoidType* void_type() { return &void_type_; }
|
||||||
|
ast::type::U32Type* u32_type() { return &u32_type_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Context ctx_;
|
Context ctx_;
|
||||||
std::unique_ptr<ast::Module> mod_;
|
ast::Module mod_;
|
||||||
|
std::unique_ptr<TypeDeterminer> td_;
|
||||||
std::unique_ptr<Inspector> inspector_;
|
std::unique_ptr<Inspector> inspector_;
|
||||||
ast::Function* last_function_;
|
|
||||||
|
ast::type::VoidType void_type_;
|
||||||
|
ast::type::U32Type u32_type_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class InspectorTest : public InspectorHelper, public testing::Test {};
|
class InspectorTest : public InspectorHelper, public testing::Test {};
|
||||||
|
@ -70,7 +179,7 @@ TEST_F(InspectorGetEntryPointTest, NoFunctions) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(InspectorGetEntryPointTest, NoEntryPoints) {
|
TEST_F(InspectorGetEntryPointTest, NoEntryPoints) {
|
||||||
AddFunction("foo", ast::PipelineStage::kNone);
|
mod()->AddFunction(GenerateEmptyBodyFunction("foo"));
|
||||||
|
|
||||||
auto result = inspector()->GetEntryPoints();
|
auto result = inspector()->GetEntryPoints();
|
||||||
ASSERT_FALSE(inspector()->has_error());
|
ASSERT_FALSE(inspector()->has_error());
|
||||||
|
@ -79,24 +188,34 @@ TEST_F(InspectorGetEntryPointTest, NoEntryPoints) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(InspectorGetEntryPointTest, OneEntryPoint) {
|
TEST_F(InspectorGetEntryPointTest, OneEntryPoint) {
|
||||||
AddFunction("foo", ast::PipelineStage::kVertex);
|
auto foo = GenerateEmptyBodyFunction("foo");
|
||||||
|
foo->add_decoration(
|
||||||
|
std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
|
||||||
|
mod()->AddFunction(std::move(foo));
|
||||||
|
|
||||||
auto result = inspector()->GetEntryPoints();
|
auto result = inspector()->GetEntryPoints();
|
||||||
ASSERT_FALSE(inspector()->has_error());
|
ASSERT_FALSE(inspector()->has_error());
|
||||||
|
|
||||||
EXPECT_EQ(1u, result.size());
|
ASSERT_EQ(1u, result.size());
|
||||||
EXPECT_EQ("foo", result[0].name);
|
EXPECT_EQ("foo", result[0].name);
|
||||||
EXPECT_EQ(ast::PipelineStage::kVertex, result[0].stage);
|
EXPECT_EQ(ast::PipelineStage::kVertex, result[0].stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(InspectorGetEntryPointTest, MultipleEntryPoints) {
|
TEST_F(InspectorGetEntryPointTest, MultipleEntryPoints) {
|
||||||
AddFunction("foo", ast::PipelineStage::kVertex);
|
auto foo = GenerateEmptyBodyFunction("foo");
|
||||||
AddFunction("bar", ast::PipelineStage::kCompute);
|
foo->add_decoration(
|
||||||
|
std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
|
||||||
|
mod()->AddFunction(std::move(foo));
|
||||||
|
|
||||||
|
auto bar = GenerateEmptyBodyFunction("bar");
|
||||||
|
bar->add_decoration(
|
||||||
|
std::make_unique<ast::StageDecoration>(ast::PipelineStage::kCompute));
|
||||||
|
mod()->AddFunction(std::move(bar));
|
||||||
|
|
||||||
auto result = inspector()->GetEntryPoints();
|
auto result = inspector()->GetEntryPoints();
|
||||||
ASSERT_FALSE(inspector()->has_error());
|
ASSERT_FALSE(inspector()->has_error());
|
||||||
|
|
||||||
EXPECT_EQ(2u, result.size());
|
ASSERT_EQ(2u, result.size());
|
||||||
EXPECT_EQ("foo", result[0].name);
|
EXPECT_EQ("foo", result[0].name);
|
||||||
EXPECT_EQ(ast::PipelineStage::kVertex, result[0].stage);
|
EXPECT_EQ(ast::PipelineStage::kVertex, result[0].stage);
|
||||||
EXPECT_EQ("bar", result[1].name);
|
EXPECT_EQ("bar", result[1].name);
|
||||||
|
@ -104,22 +223,34 @@ TEST_F(InspectorGetEntryPointTest, MultipleEntryPoints) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(InspectorGetEntryPointTest, MixFunctionsAndEntryPoints) {
|
TEST_F(InspectorGetEntryPointTest, MixFunctionsAndEntryPoints) {
|
||||||
AddFunction("foo", ast::PipelineStage::kVertex);
|
auto func = GenerateEmptyBodyFunction("func");
|
||||||
AddFunction("func", ast::PipelineStage::kNone);
|
mod()->AddFunction(std::move(func));
|
||||||
AddFunction("bar", ast::PipelineStage::kCompute);
|
|
||||||
|
auto foo = GenerateCallerBodyFunction("foo", "func");
|
||||||
|
foo->add_decoration(
|
||||||
|
std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
|
||||||
|
mod()->AddFunction(std::move(foo));
|
||||||
|
|
||||||
|
auto bar = GenerateCallerBodyFunction("bar", "func");
|
||||||
|
bar->add_decoration(
|
||||||
|
std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
|
||||||
|
mod()->AddFunction(std::move(bar));
|
||||||
|
|
||||||
auto result = inspector()->GetEntryPoints();
|
auto result = inspector()->GetEntryPoints();
|
||||||
EXPECT_FALSE(inspector()->has_error());
|
EXPECT_FALSE(inspector()->has_error());
|
||||||
|
|
||||||
EXPECT_EQ(2u, result.size());
|
ASSERT_EQ(2u, result.size());
|
||||||
EXPECT_EQ("foo", result[0].name);
|
EXPECT_EQ("foo", result[0].name);
|
||||||
EXPECT_EQ(ast::PipelineStage::kVertex, result[0].stage);
|
EXPECT_EQ(ast::PipelineStage::kVertex, result[0].stage);
|
||||||
EXPECT_EQ("bar", result[1].name);
|
EXPECT_EQ("bar", result[1].name);
|
||||||
EXPECT_EQ(ast::PipelineStage::kCompute, result[1].stage);
|
EXPECT_EQ(ast::PipelineStage::kFragment, result[1].stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(InspectorGetEntryPointTest, DefaultWorkgroupSize) {
|
TEST_F(InspectorGetEntryPointTest, DefaultWorkgroupSize) {
|
||||||
AddFunction("foo", ast::PipelineStage::kVertex);
|
auto foo = GenerateCallerBodyFunction("foo", "func");
|
||||||
|
foo->add_decoration(
|
||||||
|
std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
|
||||||
|
mod()->AddFunction(std::move(foo));
|
||||||
|
|
||||||
auto result = inspector()->GetEntryPoints();
|
auto result = inspector()->GetEntryPoints();
|
||||||
ASSERT_FALSE(inspector()->has_error());
|
ASSERT_FALSE(inspector()->has_error());
|
||||||
|
@ -133,8 +264,12 @@ TEST_F(InspectorGetEntryPointTest, DefaultWorkgroupSize) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(InspectorGetEntryPointTest, NonDefaultWorkgroupSize) {
|
TEST_F(InspectorGetEntryPointTest, NonDefaultWorkgroupSize) {
|
||||||
AddFunction("foo", ast::PipelineStage::kCompute);
|
auto foo = GenerateEmptyBodyFunction("foo");
|
||||||
AddWorkGroupSizeToLastFunction(8u, 2u, 1u);
|
foo->add_decoration(
|
||||||
|
std::make_unique<ast::StageDecoration>(ast::PipelineStage::kCompute));
|
||||||
|
foo->add_decoration(std::make_unique<ast::WorkgroupDecoration>(8u, 2u, 1u));
|
||||||
|
mod()->AddFunction(std::move(foo));
|
||||||
|
|
||||||
auto result = inspector()->GetEntryPoints();
|
auto result = inspector()->GetEntryPoints();
|
||||||
ASSERT_FALSE(inspector()->has_error());
|
ASSERT_FALSE(inspector()->has_error());
|
||||||
|
|
||||||
|
@ -146,6 +281,219 @@ TEST_F(InspectorGetEntryPointTest, NonDefaultWorkgroupSize) {
|
||||||
EXPECT_EQ(1u, z);
|
EXPECT_EQ(1u, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(InspectorGetEntryPointTest, NoInOutVariables) {
|
||||||
|
auto func = GenerateEmptyBodyFunction("func");
|
||||||
|
mod()->AddFunction(std::move(func));
|
||||||
|
|
||||||
|
auto foo = GenerateCallerBodyFunction("foo", "func");
|
||||||
|
foo->add_decoration(
|
||||||
|
std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
|
||||||
|
mod()->AddFunction(std::move(foo));
|
||||||
|
|
||||||
|
auto result = inspector()->GetEntryPoints();
|
||||||
|
ASSERT_FALSE(inspector()->has_error());
|
||||||
|
|
||||||
|
ASSERT_EQ(1u, result.size());
|
||||||
|
EXPECT_EQ(0u, result[0].input_variables.size());
|
||||||
|
EXPECT_EQ(0u, result[0].output_variables.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(InspectorGetEntryPointTest, EntryPointInOutVariables) {
|
||||||
|
CreateInOutVariables({{"in_var", "out_var"}});
|
||||||
|
|
||||||
|
auto foo = GenerateInOutVariableBodyFunction("foo", {{"in_var", "out_var"}});
|
||||||
|
foo->add_decoration(
|
||||||
|
std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
|
||||||
|
mod()->AddFunction(std::move(foo));
|
||||||
|
|
||||||
|
ASSERT_TRUE(td()->Determine()) << td()->error();
|
||||||
|
|
||||||
|
auto result = inspector()->GetEntryPoints();
|
||||||
|
ASSERT_FALSE(inspector()->has_error());
|
||||||
|
|
||||||
|
ASSERT_EQ(1u, result.size());
|
||||||
|
|
||||||
|
ASSERT_EQ(1u, result[0].input_variables.size());
|
||||||
|
EXPECT_EQ("in_var", result[0].input_variables[0]);
|
||||||
|
ASSERT_EQ(1u, result[0].output_variables.size());
|
||||||
|
EXPECT_EQ("out_var", result[0].output_variables[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(InspectorGetEntryPointTest, FunctionInOutVariables) {
|
||||||
|
CreateInOutVariables({{"in_var", "out_var"}});
|
||||||
|
|
||||||
|
auto func =
|
||||||
|
GenerateInOutVariableBodyFunction("func", {{"in_var", "out_var"}});
|
||||||
|
mod()->AddFunction(std::move(func));
|
||||||
|
|
||||||
|
auto foo = GenerateCallerBodyFunction("foo", "func");
|
||||||
|
foo->add_decoration(
|
||||||
|
std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
|
||||||
|
mod()->AddFunction(std::move(foo));
|
||||||
|
|
||||||
|
ASSERT_TRUE(td()->Determine()) << td()->error();
|
||||||
|
|
||||||
|
auto result = inspector()->GetEntryPoints();
|
||||||
|
ASSERT_FALSE(inspector()->has_error());
|
||||||
|
|
||||||
|
ASSERT_EQ(1u, result.size());
|
||||||
|
|
||||||
|
ASSERT_EQ(1u, result[0].input_variables.size());
|
||||||
|
EXPECT_EQ("in_var", result[0].input_variables[0]);
|
||||||
|
ASSERT_EQ(1u, result[0].output_variables.size());
|
||||||
|
EXPECT_EQ("out_var", result[0].output_variables[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(InspectorGetEntryPointTest, RepeatedInOutVariables) {
|
||||||
|
CreateInOutVariables({{"in_var", "out_var"}});
|
||||||
|
|
||||||
|
auto func =
|
||||||
|
GenerateInOutVariableBodyFunction("func", {{"in_var", "out_var"}});
|
||||||
|
mod()->AddFunction(std::move(func));
|
||||||
|
|
||||||
|
auto foo = GenerateInOutVariableCallerBodyFunction("foo", "func",
|
||||||
|
{{"in_var", "out_var"}});
|
||||||
|
foo->add_decoration(
|
||||||
|
std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
|
||||||
|
mod()->AddFunction(std::move(foo));
|
||||||
|
|
||||||
|
ASSERT_TRUE(td()->Determine()) << td()->error();
|
||||||
|
|
||||||
|
auto result = inspector()->GetEntryPoints();
|
||||||
|
ASSERT_FALSE(inspector()->has_error());
|
||||||
|
|
||||||
|
ASSERT_EQ(1u, result.size());
|
||||||
|
|
||||||
|
ASSERT_EQ(1u, result[0].input_variables.size());
|
||||||
|
EXPECT_EQ("in_var", result[0].input_variables[0]);
|
||||||
|
ASSERT_EQ(1u, result[0].output_variables.size());
|
||||||
|
EXPECT_EQ("out_var", result[0].output_variables[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(InspectorGetEntryPointTest, EntryPointMultipleInOutVariables) {
|
||||||
|
CreateInOutVariables({{"in_var", "out_var"}, {"in2_var", "out2_var"}});
|
||||||
|
|
||||||
|
auto foo = GenerateInOutVariableBodyFunction(
|
||||||
|
"foo", {{"in_var", "out_var"}, {"in2_var", "out2_var"}});
|
||||||
|
foo->add_decoration(
|
||||||
|
std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
|
||||||
|
mod()->AddFunction(std::move(foo));
|
||||||
|
|
||||||
|
ASSERT_TRUE(td()->Determine()) << td()->error();
|
||||||
|
|
||||||
|
auto result = inspector()->GetEntryPoints();
|
||||||
|
ASSERT_FALSE(inspector()->has_error());
|
||||||
|
|
||||||
|
ASSERT_EQ(1u, result.size());
|
||||||
|
|
||||||
|
ASSERT_EQ(2u, result[0].input_variables.size());
|
||||||
|
EXPECT_TRUE(ContainsString(result[0].input_variables, "in_var"));
|
||||||
|
EXPECT_TRUE(ContainsString(result[0].input_variables, "in2_var"));
|
||||||
|
ASSERT_EQ(2u, result[0].output_variables.size());
|
||||||
|
EXPECT_TRUE(ContainsString(result[0].output_variables, "out_var"));
|
||||||
|
EXPECT_TRUE(ContainsString(result[0].output_variables, "out2_var"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(InspectorGetEntryPointTest, FunctionMultipleInOutVariables) {
|
||||||
|
CreateInOutVariables({{"in_var", "out_var"}, {"in2_var", "out2_var"}});
|
||||||
|
|
||||||
|
auto func = GenerateInOutVariableBodyFunction(
|
||||||
|
"func", {{"in_var", "out_var"}, {"in2_var", "out2_var"}});
|
||||||
|
mod()->AddFunction(std::move(func));
|
||||||
|
|
||||||
|
auto foo = GenerateCallerBodyFunction("foo", "func");
|
||||||
|
foo->add_decoration(
|
||||||
|
std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
|
||||||
|
mod()->AddFunction(std::move(foo));
|
||||||
|
|
||||||
|
ASSERT_TRUE(td()->Determine()) << td()->error();
|
||||||
|
|
||||||
|
auto result = inspector()->GetEntryPoints();
|
||||||
|
ASSERT_FALSE(inspector()->has_error());
|
||||||
|
|
||||||
|
ASSERT_EQ(1u, result.size());
|
||||||
|
|
||||||
|
ASSERT_EQ(2u, result[0].input_variables.size());
|
||||||
|
EXPECT_TRUE(ContainsString(result[0].input_variables, "in_var"));
|
||||||
|
EXPECT_TRUE(ContainsString(result[0].input_variables, "in2_var"));
|
||||||
|
ASSERT_EQ(2u, result[0].output_variables.size());
|
||||||
|
EXPECT_TRUE(ContainsString(result[0].output_variables, "out_var"));
|
||||||
|
EXPECT_TRUE(ContainsString(result[0].output_variables, "out2_var"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(InspectorGetEntryPointTest, MultipleEntryPointsInOutVariables) {
|
||||||
|
CreateInOutVariables({{"in_var", "out_var"}, {"in2_var", "out2_var"}});
|
||||||
|
|
||||||
|
auto foo = GenerateInOutVariableBodyFunction("foo", {{"in_var", "out2_var"}});
|
||||||
|
foo->add_decoration(
|
||||||
|
std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
|
||||||
|
mod()->AddFunction(std::move(foo));
|
||||||
|
|
||||||
|
auto bar = GenerateInOutVariableBodyFunction("bar", {{"in2_var", "out_var"}});
|
||||||
|
bar->add_decoration(
|
||||||
|
std::make_unique<ast::StageDecoration>(ast::PipelineStage::kCompute));
|
||||||
|
mod()->AddFunction(std::move(bar));
|
||||||
|
|
||||||
|
ASSERT_TRUE(td()->Determine()) << td()->error();
|
||||||
|
|
||||||
|
auto result = inspector()->GetEntryPoints();
|
||||||
|
ASSERT_FALSE(inspector()->has_error());
|
||||||
|
|
||||||
|
ASSERT_EQ(2u, result.size());
|
||||||
|
|
||||||
|
ASSERT_EQ("foo", result[0].name);
|
||||||
|
ASSERT_EQ(1u, result[0].input_variables.size());
|
||||||
|
EXPECT_EQ("in_var", result[0].input_variables[0]);
|
||||||
|
ASSERT_EQ(1u, result[0].output_variables.size());
|
||||||
|
EXPECT_EQ("out2_var", result[0].output_variables[0]);
|
||||||
|
|
||||||
|
ASSERT_EQ("bar", result[1].name);
|
||||||
|
ASSERT_EQ(1u, result[1].input_variables.size());
|
||||||
|
EXPECT_EQ("in2_var", result[1].input_variables[0]);
|
||||||
|
ASSERT_EQ(1u, result[1].output_variables.size());
|
||||||
|
EXPECT_EQ("out_var", result[1].output_variables[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(InspectorGetEntryPointTest, MultipleEntryPointsSharedInOutVariables) {
|
||||||
|
CreateInOutVariables({{"in_var", "out_var"}, {"in2_var", "out2_var"}});
|
||||||
|
|
||||||
|
auto func =
|
||||||
|
GenerateInOutVariableBodyFunction("func", {{"in2_var", "out2_var"}});
|
||||||
|
mod()->AddFunction(std::move(func));
|
||||||
|
|
||||||
|
auto foo = GenerateInOutVariableCallerBodyFunction("foo", "func",
|
||||||
|
{{"in_var", "out_var"}});
|
||||||
|
foo->add_decoration(
|
||||||
|
std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
|
||||||
|
mod()->AddFunction(std::move(foo));
|
||||||
|
|
||||||
|
auto bar = GenerateCallerBodyFunction("bar", "func");
|
||||||
|
bar->add_decoration(
|
||||||
|
std::make_unique<ast::StageDecoration>(ast::PipelineStage::kCompute));
|
||||||
|
mod()->AddFunction(std::move(bar));
|
||||||
|
|
||||||
|
ASSERT_TRUE(td()->Determine()) << td()->error();
|
||||||
|
|
||||||
|
auto result = inspector()->GetEntryPoints();
|
||||||
|
ASSERT_FALSE(inspector()->has_error());
|
||||||
|
|
||||||
|
ASSERT_EQ(2u, result.size());
|
||||||
|
|
||||||
|
ASSERT_EQ("foo", result[0].name);
|
||||||
|
EXPECT_EQ(2u, result[0].input_variables.size());
|
||||||
|
EXPECT_TRUE(ContainsString(result[0].input_variables, "in_var"));
|
||||||
|
EXPECT_TRUE(ContainsString(result[0].input_variables, "in2_var"));
|
||||||
|
EXPECT_EQ(2u, result[0].output_variables.size());
|
||||||
|
EXPECT_TRUE(ContainsString(result[0].output_variables, "out_var"));
|
||||||
|
EXPECT_TRUE(ContainsString(result[0].output_variables, "out2_var"));
|
||||||
|
|
||||||
|
ASSERT_EQ("bar", result[1].name);
|
||||||
|
EXPECT_EQ(1u, result[1].input_variables.size());
|
||||||
|
EXPECT_EQ("in2_var", result[1].input_variables[0]);
|
||||||
|
EXPECT_EQ(1u, result[1].output_variables.size());
|
||||||
|
EXPECT_EQ("out2_var", result[1].output_variables[0]);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace inspector
|
} // namespace inspector
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
Loading…
Reference in New Issue