[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:
parent
5e2d8af6ad
commit
939ff868e8
|
@ -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() {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue