[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
|
/// The entry point stage
|
||||||
ast::PipelineStage stage = ast::PipelineStage::kNone;
|
ast::PipelineStage stage = ast::PipelineStage::kNone;
|
||||||
/// The workgroup x size
|
/// The workgroup x size
|
||||||
uint32_t workgroup_size_x;
|
uint32_t workgroup_size_x = 0;
|
||||||
/// The workgroup y size
|
/// The workgroup y size
|
||||||
uint32_t workgroup_size_y;
|
uint32_t workgroup_size_y = 0;
|
||||||
/// The workgroup z size
|
/// 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.
|
/// List of the input variable accessed via this entry point.
|
||||||
std::vector<StageVariable> input_variables;
|
std::vector<StageVariable> input_variables;
|
||||||
/// List of the output variable accessed via this entry point.
|
/// List of the output variable accessed via this entry point.
|
||||||
std::vector<StageVariable> output_variables;
|
std::vector<StageVariable> output_variables;
|
||||||
/// List of the pipeline overridable constants accessed via this entry point.
|
/// List of the pipeline overridable constants accessed via this entry point.
|
||||||
std::vector<OverridableConstant> overridable_constants;
|
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
|
/// @returns the size of the workgroup in {x,y,z} format
|
||||||
std::tuple<uint32_t, uint32_t, uint32_t> workgroup_size() {
|
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.output_variables);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entry_point.sample_mask_used = ContainsSampleMaskBuiltin(
|
||||||
|
sem->ReturnType(), func->return_type_decorations());
|
||||||
|
|
||||||
for (auto* var : sem->ReferencedModuleVariables()) {
|
for (auto* var : sem->ReferencedModuleVariables()) {
|
||||||
auto* decl = var->Declaration();
|
auto* decl = var->Declaration();
|
||||||
|
|
||||||
|
@ -535,6 +538,31 @@ void Inspector::AddEntryPointInOutVariables(
|
||||||
variables.push_back(stage_variable);
|
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(
|
std::vector<ResourceBinding> Inspector::GetStorageBufferResourceBindingsImpl(
|
||||||
const std::string& entry_point,
|
const std::string& entry_point,
|
||||||
bool read_only) {
|
bool read_only) {
|
||||||
|
|
|
@ -151,6 +151,12 @@ class Inspector {
|
||||||
const ast::DecorationList& decorations,
|
const ast::DecorationList& decorations,
|
||||||
std::vector<StageVariable>& variables) const;
|
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 entry_point name of the entry point to get information about.
|
||||||
/// @param read_only if true get only read-only bindings, if false get
|
/// @param read_only if true get only read-only bindings, if false get
|
||||||
/// write-only bindings.
|
/// write-only bindings.
|
||||||
|
|
|
@ -1559,6 +1559,50 @@ TEST_F(InspectorGetEntryPointTest, NonOverridableConstantSkipped) {
|
||||||
EXPECT_EQ(0u, result[0].overridable_constants.size());
|
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
|
// TODO(rharrison): Reenable once GetRemappedNameForEntryPoint isn't a pass
|
||||||
// through
|
// through
|
||||||
TEST_F(InspectorGetRemappedNameForEntryPointTest, DISABLED_NoFunctions) {
|
TEST_F(InspectorGetRemappedNameForEntryPointTest, DISABLED_NoFunctions) {
|
||||||
|
|
Loading…
Reference in New Issue