[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'");
|
"'vtx_func'");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ValidateFunctionTest, PipelineStageNamePair_MustBeUnique_Fail) {
|
TEST_F(ValidateFunctionTest, PipelineStage_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; }
|
|
||||||
// [[stage(fragment)]]
|
// [[stage(fragment)]]
|
||||||
|
// [[stage(vertex)]]
|
||||||
// fn main() -> void { return; }
|
// fn main() -> void { return; }
|
||||||
ast::type::VoidType void_type;
|
ast::type::VoidType void_type;
|
||||||
ast::VariableList params;
|
ast::VariableList params;
|
||||||
auto func = std::make_unique<ast::Function>(
|
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>();
|
auto body = std::make_unique<ast::BlockStatement>();
|
||||||
body->append(std::make_unique<ast::ReturnStatement>());
|
body->append(std::make_unique<ast::ReturnStatement>());
|
||||||
func->set_body(std::move(body));
|
func->set_body(std::move(body));
|
||||||
func->add_decoration(std::make_unique<ast::StageDecoration>(
|
func->add_decoration(std::make_unique<ast::StageDecoration>(
|
||||||
ast::PipelineStage::kVertex, Source{}));
|
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>(
|
func->add_decoration(std::make_unique<ast::StageDecoration>(
|
||||||
ast::PipelineStage::kFragment, Source{}));
|
ast::PipelineStage::kFragment, Source{}));
|
||||||
mod()->AddFunction(std::move(func));
|
mod()->AddFunction(std::move(func));
|
||||||
|
|
||||||
EXPECT_TRUE(td()->Determine()) << td()->error();
|
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) {
|
TEST_F(ValidateFunctionTest, OnePipelineStageFunctionMustBePresent_Pass) {
|
||||||
|
|
|
@ -51,7 +51,9 @@ bool ValidatorImpl::Validate(const ast::Module* module) {
|
||||||
if (!ValidateFunctions(module->functions())) {
|
if (!ValidateFunctions(module->functions())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!ValidateEntryPoint(module->functions())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
function_stack_.pop_scope();
|
function_stack_.pop_scope();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -82,49 +84,13 @@ bool ValidatorImpl::ValidateGlobalVariables(
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ValidatorImpl::ValidateFunctions(const ast::FunctionList& funcs) {
|
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) {
|
for (const auto& func : funcs) {
|
||||||
// The entry points will be checked later to see if their duplicated
|
if (function_stack_.has(func->name())) {
|
||||||
if (function_stack_.has(func->name()) &&
|
|
||||||
!entry_point_map.has(func->name())) {
|
|
||||||
set_error(func->source(),
|
set_error(func->source(),
|
||||||
"v-0016: function names must be unique '" + func->name() + "'");
|
"v-0016: function names must be unique '" + func->name() + "'");
|
||||||
return false;
|
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());
|
function_stack_.set(func->name(), func.get());
|
||||||
current_function_ = func.get();
|
current_function_ = func.get();
|
||||||
if (!ValidateFunction(func.get())) {
|
if (!ValidateFunction(func.get())) {
|
||||||
|
@ -133,13 +99,47 @@ bool ValidatorImpl::ValidateFunctions(const ast::FunctionList& funcs) {
|
||||||
current_function_ = nullptr;
|
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{},
|
set_error(Source{},
|
||||||
"v-0003: At least one of vertex, fragment or compute shader must "
|
"v-0003: At least one of vertex, fragment or compute shader must "
|
||||||
"be present");
|
"be present");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,6 +113,10 @@ class ValidatorImpl {
|
||||||
/// @param c the case statement to check
|
/// @param c the case statement to check
|
||||||
/// @returns true if the valdiation was successful
|
/// @returns true if the valdiation was successful
|
||||||
bool ValidateCase(const ast::CaseStatement* c);
|
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:
|
private:
|
||||||
std::string error_;
|
std::string error_;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
break-outside-for-or-switch.fail.wgsl
|
break-outside-for-or-switch.fail.wgsl
|
||||||
continue-outside-for.fail.wgsl
|
continue-outside-for.fail.wgsl
|
||||||
duplicate-entry-point.fail.wgsl
|
|
||||||
duplicate-stuct-name-v2.fail.wgsl
|
duplicate-stuct-name-v2.fail.wgsl
|
||||||
duplicate-stuct-name.fail.wgsl
|
duplicate-stuct-name.fail.wgsl
|
||||||
duplicate-var-name-within-func.fail.wgsl
|
duplicate-var-name-within-func.fail.wgsl
|
||||||
|
|
Loading…
Reference in New Issue