[validator] Remove requirement to have an entry point

The SPIR-V and HLSL sanitizing transforms add an empty one if
necessary.

Fixed: tint:679
Change-Id: Ic98ff3109d7381b1fbc2de68d95d57e15c7a67c0
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/46700
Commit-Queue: Ben Clayton <bclayton@google.com>
Auto-Submit: James Price <jrprice@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
James Price
2021-04-01 22:07:37 +00:00
committed by Commit Bot service account
parent 1fe1a5e641
commit 2f04dc94ce
9 changed files with 61 additions and 32 deletions

View File

@@ -16,6 +16,7 @@
#include <utility>
#include "src/ast/stage_decoration.h"
#include "src/ast/variable_decl_statement.h"
#include "src/program_builder.h"
#include "src/semantic/expression.h"
@@ -32,6 +33,7 @@ Transform::Output Hlsl::Run(const Program* in, const DataMap&) {
ProgramBuilder out;
CloneContext ctx(&out, in);
PromoteArrayInitializerToConstVar(ctx);
AddEmptyEntryPoint(ctx);
ctx.Clone();
return Output{Program(std::move(out))};
}
@@ -105,5 +107,16 @@ void Hlsl::PromoteArrayInitializerToConstVar(CloneContext& ctx) const {
}
}
void Hlsl::AddEmptyEntryPoint(CloneContext& ctx) const {
for (auto* func : ctx.src->AST().Functions()) {
if (func->IsEntryPoint()) {
return;
}
}
ctx.dst->Func(
"_tint_unused_entry_point", {}, ctx.dst->ty.void_(), {},
{ctx.dst->create<ast::StageDecoration>(ast::PipelineStage::kVertex)});
}
} // namespace transform
} // namespace tint

View File

@@ -44,6 +44,8 @@ class Hlsl : public Transform {
/// the array usage statement.
/// See crbug.com/tint/406 for more details
void PromoteArrayInitializerToConstVar(CloneContext& ctx) const;
/// Add an empty shader entry point if none exist in the module.
void AddEmptyEntryPoint(CloneContext& ctx) const;
};
} // namespace transform

View File

@@ -143,6 +143,20 @@ fn main() -> void {
EXPECT_EQ(expect, str(got));
}
TEST_F(HlslTest, AddEmptyEntryPoint) {
auto* src = R"()";
auto* expect = R"(
[[stage(vertex)]]
fn _tint_unused_entry_point() -> void {
}
)";
auto got = Run<Hlsl>(src);
EXPECT_EQ(expect, str(got));
}
} // namespace
} // namespace transform
} // namespace tint

View File

@@ -19,6 +19,7 @@
#include "src/ast/call_statement.h"
#include "src/ast/return_statement.h"
#include "src/ast/stage_decoration.h"
#include "src/program_builder.h"
#include "src/semantic/function.h"
#include "src/semantic/statement.h"
@@ -42,6 +43,7 @@ Transform::Output Spirv::Run(const Program* in, const DataMap&) {
ProgramBuilder out2;
CloneContext ctx2(&out2, &tmp);
HandleSampleMaskBuiltins(ctx2);
AddEmptyEntryPoint(ctx2);
ctx2.Clone();
return Output{Program(std::move(out2))};
@@ -234,6 +236,17 @@ void Spirv::HandleSampleMaskBuiltins(CloneContext& ctx) const {
}
}
void Spirv::AddEmptyEntryPoint(CloneContext& ctx) const {
for (auto* func : ctx.src->AST().Functions()) {
if (func->IsEntryPoint()) {
return;
}
}
ctx.dst->Func(
"_tint_unused_entry_point", {}, ctx.dst->ty.void_(), {},
{ctx.dst->create<ast::StageDecoration>(ast::PipelineStage::kCompute)});
}
Symbol Spirv::HoistToInputVariables(
CloneContext& ctx,
const ast::Function* func,

View File

@@ -47,6 +47,8 @@ class Spirv : public Transform {
void HandleEntryPointIOTypes(CloneContext& ctx) const;
/// Change type of sample mask builtin variables to single element arrays.
void HandleSampleMaskBuiltins(CloneContext& ctx) const;
/// Add an empty shader entry point if none exist in the module.
void AddEmptyEntryPoint(CloneContext& ctx) const;
/// Recursively create module-scope input variables for `ty` and add
/// function-scope variables for structs to `func`.

View File

@@ -833,6 +833,20 @@ fn main() -> void {
EXPECT_EQ(expect, str(got));
}
TEST_F(SpirvTest, AddEmptyEntryPoint) {
auto* src = R"()";
auto* expect = R"(
[[stage(compute)]]
fn _tint_unused_entry_point() -> void {
}
)";
auto got = Run<Spirv>(src);
EXPECT_EQ(expect, str(got));
}
// Test that different transforms within the sanitizer interact correctly.
TEST_F(SpirvTest, MultipleTransforms) {
auto* src = R"(