[inspector] Report if sample_mask is returned by the entry point

BUG=tint:424

Change-Id: Ic378173ac4e6697b57102db611cdc0b29b25c72a
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/56302
Auto-Submit: Ryan Harrison <rharrison@chromium.org>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Reviewed-by: James Price <jrprice@google.com>
This commit is contained in:
Ryan Harrison 2021-06-30 15:23:30 +00:00 committed by Tint LUCI CQ
parent 5e2d8af6ad
commit 939ff868e8
4 changed files with 83 additions and 3 deletions

View File

@ -69,17 +69,19 @@ struct EntryPoint {
/// The entry point stage
ast::PipelineStage stage = ast::PipelineStage::kNone;
/// The workgroup x size
uint32_t workgroup_size_x;
uint32_t workgroup_size_x = 0;
/// The workgroup y size
uint32_t workgroup_size_y;
uint32_t workgroup_size_y = 0;
/// The workgroup z size
uint32_t workgroup_size_z;
uint32_t workgroup_size_z = 0;
/// List of the input variable accessed via this entry point.
std::vector<StageVariable> input_variables;
/// List of the output variable accessed via this entry point.
std::vector<StageVariable> output_variables;
/// List of the pipeline overridable constants accessed via this entry point.
std::vector<OverridableConstant> overridable_constants;
/// Does the entry point use the sample_mask builtin
bool sample_mask_used = false;
/// @returns the size of the workgroup in {x,y,z} format
std::tuple<uint32_t, uint32_t, uint32_t> workgroup_size() {

View File

@ -100,6 +100,9 @@ std::vector<EntryPoint> Inspector::GetEntryPoints() {
entry_point.output_variables);
}
entry_point.sample_mask_used = ContainsSampleMaskBuiltin(
sem->ReturnType(), func->return_type_decorations());
for (auto* var : sem->ReferencedModuleVariables()) {
auto* decl = var->Declaration();
@ -535,6 +538,31 @@ void Inspector::AddEntryPointInOutVariables(
variables.push_back(stage_variable);
}
bool Inspector::ContainsSampleMaskBuiltin(
sem::Type* type,
const ast::DecorationList& decorations) const {
auto* unwrapped_type = type->UnwrapRef();
if (auto* struct_ty = unwrapped_type->As<sem::Struct>()) {
// Recurse into members.
for (auto* member : struct_ty->Members()) {
if (ContainsSampleMaskBuiltin(member->Type(),
member->Declaration()->decorations())) {
return true;
}
}
return false;
}
// Base case: check for [[builtin(sample_mask)]]
auto* builtin = ast::GetDecoration<ast::BuiltinDecoration>(decorations);
if (!builtin || builtin->value() != ast::Builtin::kSampleMask) {
return false;
}
return true;
}
std::vector<ResourceBinding> Inspector::GetStorageBufferResourceBindingsImpl(
const std::string& entry_point,
bool read_only) {

View File

@ -151,6 +151,12 @@ class Inspector {
const ast::DecorationList& decorations,
std::vector<StageVariable>& variables) const;
/// Recursively determine if the type contains [[builtin(sample_mask)]]
/// If `type` is a struct, recurse into members to check for the decoration.
/// Otherwise, check `decorations` for the decoration.
bool ContainsSampleMaskBuiltin(sem::Type* type,
const ast::DecorationList& decorations) const;
/// @param entry_point name of the entry point to get information about.
/// @param read_only if true get only read-only bindings, if false get
/// write-only bindings.

View File

@ -1559,6 +1559,50 @@ TEST_F(InspectorGetEntryPointTest, NonOverridableConstantSkipped) {
EXPECT_EQ(0u, result[0].overridable_constants.size());
}
TEST_F(InspectorGetEntryPointTest, SampleMaskNotReferenced) {
MakeEmptyBodyFunction("ep_func", {Stage(ast::PipelineStage::kFragment)});
Inspector& inspector = Build();
auto result = inspector.GetEntryPoints();
ASSERT_EQ(1u, result.size());
EXPECT_FALSE(result[0].sample_mask_used);
}
TEST_F(InspectorGetEntryPointTest, SampleMaskSimpleReferenced) {
auto* in_var =
Param("in_var", ty.u32(), {Builtin(ast::Builtin::kSampleMask)});
Func("ep_func", {in_var}, ty.u32(), {Return("in_var")},
{Stage(ast::PipelineStage::kFragment)},
{Builtin(ast::Builtin::kSampleMask)});
Inspector& inspector = Build();
auto result = inspector.GetEntryPoints();
ASSERT_EQ(1u, result.size());
EXPECT_TRUE(result[0].sample_mask_used);
}
TEST_F(InspectorGetEntryPointTest, SampleMaskStructReferenced) {
ast::StructMemberList members;
members.push_back(Member("inner_sample_mask", ty.u32(),
{Builtin(ast::Builtin::kSampleMask)}));
Structure("out_struct", members, {});
Func("ep_func", {}, ty.type_name("out_struct"),
{Decl(Var("out_var", ty.type_name("out_struct"))), Return("out_var")},
{Stage(ast::PipelineStage::kFragment)}, {});
Inspector& inspector = Build();
auto result = inspector.GetEntryPoints();
ASSERT_EQ(1u, result.size());
EXPECT_TRUE(result[0].sample_mask_used);
}
// TODO(rharrison): Reenable once GetRemappedNameForEntryPoint isn't a pass
// through
TEST_F(InspectorGetRemappedNameForEntryPointTest, DISABLED_NoFunctions) {