[validation] Update entry points validation v-0020
Remove irrelevant unit tests Add/Update ValdiateEntryPoints function Update known failure file Bug: tint:296 Change-Id: I7d5c9c96fcca29f3e0a4c0315eb8ce869160a3ea Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/32220 Reviewed-by: David Neto <dneto@google.com> Commit-Queue: David Neto <dneto@google.com>
This commit is contained in:
parent
1bbafa3445
commit
3b04058d19
|
@ -316,65 +316,27 @@ TEST_F(ValidateFunctionTest, Function_WithPipelineStage_WithParams_Fail) {
|
|||
"'vtx_func'");
|
||||
}
|
||||
|
||||
TEST_F(ValidateFunctionTest, PipelineStageNamePair_MustBeUnique_Fail) {
|
||||
// [[stage(vertex)]]
|
||||
// fn main() -> void { return ;}
|
||||
// [[stage(vertex)]]
|
||||
// fn main() -> void { return; }
|
||||
ast::type::VoidType void_type;
|
||||
ast::VariableList params;
|
||||
auto func = std::make_unique<ast::Function>(
|
||||
Source{Source::Location{5, 6}}, "main", std::move(params), &void_type);
|
||||
auto body = std::make_unique<ast::BlockStatement>();
|
||||
body->append(std::make_unique<ast::ReturnStatement>());
|
||||
func->set_body(std::move(body));
|
||||
func->add_decoration(std::make_unique<ast::StageDecoration>(
|
||||
ast::PipelineStage::kVertex, Source{}));
|
||||
mod()->AddFunction(std::move(func));
|
||||
|
||||
func = std::make_unique<ast::Function>(Source{Source::Location{12, 34}},
|
||||
"main", std::move(params), &void_type);
|
||||
body = std::make_unique<ast::BlockStatement>();
|
||||
body->append(std::make_unique<ast::ReturnStatement>());
|
||||
func->set_body(std::move(body));
|
||||
func->add_decoration(std::make_unique<ast::StageDecoration>(
|
||||
ast::PipelineStage::kVertex, Source{}));
|
||||
mod()->AddFunction(std::move(func));
|
||||
|
||||
EXPECT_TRUE(td()->Determine()) << td()->error();
|
||||
EXPECT_FALSE(v()->Validate(mod()));
|
||||
EXPECT_EQ(v()->error(),
|
||||
"12:34: v-0020: The pair of <entry point name, pipeline stage> "
|
||||
"must be unique");
|
||||
}
|
||||
|
||||
TEST_F(ValidateFunctionTest, PipelineStageNamePair_MustBeUnique_Pass) {
|
||||
// [[stage(vertex)]]
|
||||
// fn main() -> void { return; }
|
||||
TEST_F(ValidateFunctionTest, PipelineStage_MustBeUnique_Fail) {
|
||||
// [[stage(fragment)]]
|
||||
// [[stage(vertex)]]
|
||||
// fn main() -> void { return; }
|
||||
ast::type::VoidType void_type;
|
||||
ast::VariableList params;
|
||||
auto func = std::make_unique<ast::Function>(
|
||||
Source{Source::Location{5, 6}}, "main", std::move(params), &void_type);
|
||||
Source{Source::Location{12, 34}}, "main", std::move(params), &void_type);
|
||||
auto body = std::make_unique<ast::BlockStatement>();
|
||||
body->append(std::make_unique<ast::ReturnStatement>());
|
||||
func->set_body(std::move(body));
|
||||
func->add_decoration(std::make_unique<ast::StageDecoration>(
|
||||
ast::PipelineStage::kVertex, Source{}));
|
||||
mod()->AddFunction(std::move(func));
|
||||
|
||||
func = std::make_unique<ast::Function>(Source{Source::Location{12, 34}},
|
||||
"main", std::move(params), &void_type);
|
||||
body = std::make_unique<ast::BlockStatement>();
|
||||
body->append(std::make_unique<ast::ReturnStatement>());
|
||||
func->set_body(std::move(body));
|
||||
func->add_decoration(std::make_unique<ast::StageDecoration>(
|
||||
ast::PipelineStage::kFragment, Source{}));
|
||||
mod()->AddFunction(std::move(func));
|
||||
|
||||
EXPECT_TRUE(td()->Determine()) << td()->error();
|
||||
EXPECT_TRUE(v()->Validate(mod())) << v()->error();
|
||||
EXPECT_FALSE(v()->Validate(mod()));
|
||||
EXPECT_EQ(
|
||||
v()->error(),
|
||||
"12:34: v-0020: only one stage decoration permitted per entry point");
|
||||
}
|
||||
|
||||
TEST_F(ValidateFunctionTest, OnePipelineStageFunctionMustBePresent_Pass) {
|
||||
|
|
|
@ -51,7 +51,9 @@ bool ValidatorImpl::Validate(const ast::Module* module) {
|
|||
if (!ValidateFunctions(module->functions())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ValidateEntryPoint(module->functions())) {
|
||||
return false;
|
||||
}
|
||||
function_stack_.pop_scope();
|
||||
|
||||
return true;
|
||||
|
@ -82,49 +84,13 @@ bool ValidatorImpl::ValidateGlobalVariables(
|
|||
}
|
||||
|
||||
bool ValidatorImpl::ValidateFunctions(const ast::FunctionList& funcs) {
|
||||
ScopeStack<ast::PipelineStage> entry_point_map;
|
||||
entry_point_map.push_scope();
|
||||
|
||||
size_t pipeline_count = 0;
|
||||
for (const auto& func : funcs) {
|
||||
// The entry points will be checked later to see if their duplicated
|
||||
if (function_stack_.has(func->name()) &&
|
||||
!entry_point_map.has(func->name())) {
|
||||
if (function_stack_.has(func->name())) {
|
||||
set_error(func->source(),
|
||||
"v-0016: function names must be unique '" + func->name() + "'");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (func->IsEntryPoint()) {
|
||||
pipeline_count++;
|
||||
|
||||
if (!func->return_type()->IsVoid()) {
|
||||
set_error(func->source(),
|
||||
"v-0024: Entry point function must return void: '" +
|
||||
func->name() + "'");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (func->params().size() != 0) {
|
||||
set_error(func->source(),
|
||||
"v-0023: Entry point function must accept no parameters: '" +
|
||||
func->name() + "'");
|
||||
return false;
|
||||
}
|
||||
|
||||
ast::PipelineStage pipeline_stage;
|
||||
if (entry_point_map.get(func->name(), &pipeline_stage)) {
|
||||
if (pipeline_stage == func->pipeline_stage()) {
|
||||
set_error(
|
||||
func->source(),
|
||||
"v-0020: The pair of <entry point name, pipeline stage> must "
|
||||
"be unique");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
entry_point_map.set(func->name(), func->pipeline_stage());
|
||||
}
|
||||
|
||||
function_stack_.set(func->name(), func.get());
|
||||
current_function_ = func.get();
|
||||
if (!ValidateFunction(func.get())) {
|
||||
|
@ -133,13 +99,47 @@ bool ValidatorImpl::ValidateFunctions(const ast::FunctionList& funcs) {
|
|||
current_function_ = nullptr;
|
||||
}
|
||||
|
||||
if (pipeline_count == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ValidatorImpl::ValidateEntryPoint(const ast::FunctionList& funcs) {
|
||||
auto shader_is_present = false;
|
||||
for (const auto& func : funcs) {
|
||||
if (func->IsEntryPoint()) {
|
||||
shader_is_present = true;
|
||||
if (!func->params().empty()) {
|
||||
set_error(func->source(),
|
||||
"v-0023: Entry point function must accept no parameters: '" +
|
||||
func->name() + "'");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!func->return_type()->IsVoid()) {
|
||||
set_error(func->source(),
|
||||
"v-0024: Entry point function must return void: '" +
|
||||
func->name() + "'");
|
||||
return false;
|
||||
}
|
||||
auto stage_deco_count = 0;
|
||||
for (const auto& deco : func->decorations()) {
|
||||
if (deco->IsStage()) {
|
||||
stage_deco_count++;
|
||||
}
|
||||
}
|
||||
if (stage_deco_count > 1) {
|
||||
set_error(
|
||||
func->source(),
|
||||
"v-0020: only one stage decoration permitted per entry point");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!shader_is_present) {
|
||||
set_error(Source{},
|
||||
"v-0003: At least one of vertex, fragment or compute shader must "
|
||||
"be present");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -113,6 +113,10 @@ class ValidatorImpl {
|
|||
/// @param c the case statement to check
|
||||
/// @returns true if the valdiation was successful
|
||||
bool ValidateCase(const ast::CaseStatement* c);
|
||||
/// Validates entry points
|
||||
/// @param funcs the functions to check
|
||||
/// @returns true if the valdiation was successful
|
||||
bool ValidateEntryPoint(const ast::FunctionList& funcs);
|
||||
|
||||
private:
|
||||
std::string error_;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
break-outside-for-or-switch.fail.wgsl
|
||||
continue-outside-for.fail.wgsl
|
||||
duplicate-entry-point.fail.wgsl
|
||||
duplicate-stuct-name-v2.fail.wgsl
|
||||
duplicate-stuct-name.fail.wgsl
|
||||
duplicate-var-name-within-func.fail.wgsl
|
||||
|
|
Loading…
Reference in New Issue