From 04d93c88a06b32ee2cb0f2fe4a95678659d93f3e Mon Sep 17 00:00:00 2001 From: Ryan Harrison Date: Wed, 3 Mar 2021 13:46:43 +0000 Subject: [PATCH] Add inspector support for DepthTexture reflection BUG=tint:527 Change-Id: I4f017993ffa85515b5b646bd9cf15c4b6d50c441 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/43700 Auto-Submit: Ryan Harrison Reviewed-by: Ben Clayton Commit-Queue: Ben Clayton --- src/inspector/inspector.cc | 31 +++++++++++++ src/inspector/inspector.h | 6 +++ src/inspector/inspector_test.cc | 82 +++++++++++++++++++++++++++++---- src/semantic/function.h | 5 ++ src/semantic/sem_function.cc | 77 +++++++++++++++++-------------- 5 files changed, 156 insertions(+), 45 deletions(-) diff --git a/src/inspector/inspector.cc b/src/inspector/inspector.cc index 088f5b1037..f0b302e21a 100644 --- a/src/inspector/inspector.cc +++ b/src/inspector/inspector.cc @@ -33,6 +33,7 @@ #include "src/semantic/variable.h" #include "src/type/access_control_type.h" #include "src/type/array_type.h" +#include "src/type/depth_texture_type.h" #include "src/type/f32_type.h" #include "src/type/i32_type.h" #include "src/type/matrix_type.h" @@ -343,6 +344,7 @@ std::vector Inspector::GetResourceBindings( GetSampledTextureResourceBindings(entry_point)); AppendResourceBindings(&result, GetMultisampledTextureResourceBindings(entry_point)); + AppendResourceBindings(&result, GetDepthTextureResourceBindings(entry_point)); return result; } @@ -470,6 +472,35 @@ Inspector::GetWriteOnlyStorageTextureResourceBindings( return GetStorageTextureResourceBindingsImpl(entry_point, false); } +std::vector Inspector::GetDepthTextureResourceBindings( + const std::string& entry_point) { + auto* func = FindEntryPointByName(entry_point); + if (!func) { + return {}; + } + + std::vector result; + auto* func_sem = program_->Sem().Get(func); + for (auto& ref : func_sem->ReferencedDepthTextureVariables()) { + auto* var = ref.first; + auto* decl = var->Declaration(); + auto binding_info = ref.second; + + ResourceBinding entry; + entry.resource_type = ResourceBinding::ResourceType::kDepthTexture; + entry.bind_group = binding_info.group->value(); + entry.binding = binding_info.binding->value(); + + auto* texture_type = decl->type()->UnwrapIfNeeded()->As(); + entry.dim = TypeTextureDimensionToResourceBindingTextureDimension( + texture_type->dim()); + + result.push_back(entry); + } + + return result; +} + ast::Function* Inspector::FindEntryPointByName(const std::string& name) { auto* func = program_->AST().Functions().Find(program_->Symbols().Get(name)); if (!func) { diff --git a/src/inspector/inspector.h b/src/inspector/inspector.h index f706ae3a75..96f85e7c1c 100644 --- a/src/inspector/inspector.h +++ b/src/inspector/inspector.h @@ -104,6 +104,7 @@ struct ResourceBinding { kMulitsampledTexture, kReadOnlyStorageTexture, kWriteOnlyStorageTexture, + kDepthTexture, }; /// Type of resource that is bound. @@ -198,6 +199,11 @@ class Inspector { std::vector GetWriteOnlyStorageTextureResourceBindings( const std::string& entry_point); + /// @param entry_point name of the entry point to get information about. + /// @returns vector of all of the bindings for depth textures. + std::vector GetDepthTextureResourceBindings( + const std::string& entry_point); + private: const Program* program_; std::string error_; diff --git a/src/inspector/inspector_test.cc b/src/inspector/inspector_test.cc index f50a83f164..9557bbcf4b 100644 --- a/src/inspector/inspector_test.cc +++ b/src/inspector/inspector_test.cc @@ -463,8 +463,13 @@ class InspectorHelper : public ProgramBuilder { /// Adds a depth texture variable to the program /// @param name the name of the variable /// @param type the type to use - void AddDepthTexture(const std::string& name, type::Type* type) { - Global(name, type, ast::StorageClass::kUniformConstant); + /// @param group the binding/group to use for the depth texture + /// @param binding the binding number to use for the depth texture + void AddDepthTexture(const std::string& name, + type::Type* type, + uint32_t group, + uint32_t binding) { + AddBinding(name, type, ast::StorageClass::kUniformConstant, group, binding); } /// Generates a function that references a specific sampler variable @@ -759,6 +764,13 @@ class InspectorGetMultisampledTextureResourceBindingsTestWithParam public testing::TestWithParam {}; class InspectorGetStorageTextureResourceBindingsTest : public InspectorHelper, public testing::Test {}; +struct GetDepthTextureTestParams { + type::TextureDimension type_dim; + inspector::ResourceBinding::TextureDimension inspector_dim; +}; +class InspectorGetDepthTextureResourceBindingsTestWithParam + : public InspectorHelper, + public testing::TestWithParam {}; typedef std::tuple DimensionParams; @@ -1428,8 +1440,8 @@ TEST_F(InspectorGetResourceBindingsTest, Simple) { auto* cs_depth_texture_type = MakeDepthTextureType(type::TextureDimension::k2d); - AddDepthTexture("cs_texture", cs_depth_texture_type); - AddComparisonSampler("cs_var", 3, 1); + AddDepthTexture("cs_texture", cs_depth_texture_type, 3, 1); + AddComparisonSampler("cs_var", 3, 2); AddGlobalVariable("cs_coords", ty.vec2()); AddGlobalVariable("cs_depth", ty.f32()); MakeComparisonSamplerReferenceBodyFunction( @@ -1445,7 +1457,7 @@ TEST_F(InspectorGetResourceBindingsTest, Simple) { auto result = inspector.GetResourceBindings("ep_func"); ASSERT_FALSE(inspector.has_error()) << inspector.error(); - ASSERT_EQ(6u, result.size()); + ASSERT_EQ(7u, result.size()); EXPECT_EQ(ResourceBinding::ResourceType::kUniformBuffer, result[0].resource_type); @@ -1469,12 +1481,17 @@ TEST_F(InspectorGetResourceBindingsTest, Simple) { EXPECT_EQ(ResourceBinding::ResourceType::kComparisonSampler, result[4].resource_type); EXPECT_EQ(3u, result[4].bind_group); - EXPECT_EQ(1u, result[4].binding); + EXPECT_EQ(2u, result[4].binding); EXPECT_EQ(ResourceBinding::ResourceType::kSampledTexture, result[5].resource_type); EXPECT_EQ(2u, result[5].bind_group); EXPECT_EQ(0u, result[5].binding); + + EXPECT_EQ(ResourceBinding::ResourceType::kDepthTexture, + result[6].resource_type); + EXPECT_EQ(3u, result[6].bind_group); + EXPECT_EQ(1u, result[6].binding); } TEST_F(InspectorGetUniformBufferResourceBindingsTest, MissingEntryPoint) { @@ -2118,7 +2135,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, UnknownEntryPoint) { TEST_F(InspectorGetSamplerResourceBindingsTest, SkipsComparisonSamplers) { auto* depth_texture_type = MakeDepthTextureType(type::TextureDimension::k2d); - AddDepthTexture("foo_texture", depth_texture_type); + AddDepthTexture("foo_texture", depth_texture_type, 0, 0); AddComparisonSampler("foo_sampler", 0, 1); AddGlobalVariable("foo_coords", ty.vec2()); AddGlobalVariable("foo_depth", ty.f32()); @@ -2139,7 +2156,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, SkipsComparisonSamplers) { TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, Simple) { auto* depth_texture_type = MakeDepthTextureType(type::TextureDimension::k2d); - AddDepthTexture("foo_texture", depth_texture_type); + AddDepthTexture("foo_texture", depth_texture_type, 0, 0); AddComparisonSampler("foo_sampler", 0, 1); AddGlobalVariable("foo_coords", ty.vec2()); AddGlobalVariable("foo_depth", ty.f32()); @@ -2178,7 +2195,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, NoSampler) { TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, InFunction) { auto* depth_texture_type = MakeDepthTextureType(type::TextureDimension::k2d); - AddDepthTexture("foo_texture", depth_texture_type); + AddDepthTexture("foo_texture", depth_texture_type, 0, 0); AddComparisonSampler("foo_sampler", 0, 1); AddGlobalVariable("foo_coords", ty.vec2()); AddGlobalVariable("foo_depth", ty.f32()); @@ -2207,7 +2224,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, InFunction) { TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, UnknownEntryPoint) { auto* depth_texture_type = MakeDepthTextureType(type::TextureDimension::k2d); - AddDepthTexture("foo_texture", depth_texture_type); + AddDepthTexture("foo_texture", depth_texture_type, 0, 0); AddComparisonSampler("foo_sampler", 0, 1); AddGlobalVariable("foo_coords", ty.vec2()); AddGlobalVariable("foo_depth", ty.f32()); @@ -2685,6 +2702,51 @@ INSTANTIATE_TEST_SUITE_P( ResourceBinding::ImageFormat::kRgba32Float, ResourceBinding::SampledKind::kFloat)))); +TEST_P(InspectorGetDepthTextureResourceBindingsTestWithParam, + textureDimensions) { + auto* depth_texture_type = MakeDepthTextureType(GetParam().type_dim); + AddDepthTexture("dt", depth_texture_type, 0, 0); + AddGlobalVariable("dt_level", ty.i32()); + + Func("ep", ast::VariableList(), ty.void_(), + ast::StatementList{ + create( + Call("textureDimensions", "dt", "dt_level")), + }, + ast::FunctionDecorationList{ + create(ast::PipelineStage::kVertex), + }); + + Inspector& inspector = Build(); + + auto result = inspector.GetDepthTextureResourceBindings("ep"); + ASSERT_FALSE(inspector.has_error()) << inspector.error(); + + EXPECT_EQ(ResourceBinding::ResourceType::kDepthTexture, + result[0].resource_type); + ASSERT_EQ(1u, result.size()); + EXPECT_EQ(0u, result[0].bind_group); + EXPECT_EQ(0u, result[0].binding); + EXPECT_EQ(GetParam().inspector_dim, result[0].dim); +} + +INSTANTIATE_TEST_SUITE_P( + InspectorGetDepthTextureResourceBindingsTest, + InspectorGetDepthTextureResourceBindingsTestWithParam, + testing::Values( + GetDepthTextureTestParams{ + type::TextureDimension::k2d, + inspector::ResourceBinding::TextureDimension::k2d}, + GetDepthTextureTestParams{ + type::TextureDimension::k2dArray, + inspector::ResourceBinding::TextureDimension::k2dArray}, + GetDepthTextureTestParams{ + type::TextureDimension::kCube, + inspector::ResourceBinding::TextureDimension::kCube}, + GetDepthTextureTestParams{ + type::TextureDimension::kCubeArray, + inspector::ResourceBinding::TextureDimension::kCubeArray})); + } // namespace } // namespace inspector } // namespace tint diff --git a/src/semantic/function.h b/src/semantic/function.h index 08904ff404..c8d119cc89 100644 --- a/src/semantic/function.h +++ b/src/semantic/function.h @@ -126,6 +126,11 @@ class Function : public Castable { /// @returns the referenced storage textures VariableBindings ReferencedStorageTextureVariables() const; + /// Retrieves any referenced depth texture variables. Note, the variables + /// must be decorated with both binding and group decorations. + /// @returns the referenced storage textures + VariableBindings ReferencedDepthTextureVariables() const; + /// Retrieves any locally referenced builtin variables /// @returns the pairs. std::vector> diff --git a/src/semantic/sem_function.cc b/src/semantic/sem_function.cc index 13c8e8c8f4..83c90c3549 100644 --- a/src/semantic/sem_function.cc +++ b/src/semantic/sem_function.cc @@ -22,6 +22,7 @@ #include "src/ast/variable.h" #include "src/ast/variable_decoration.h" #include "src/semantic/variable.h" +#include "src/type/depth_texture_type.h" #include "src/type/multisampled_texture_type.h" #include "src/type/sampled_texture_type.h" #include "src/type/storage_texture_type.h" @@ -43,6 +44,21 @@ ParameterList GetParameters(ast::Function* ast) { return parameters; } +std::tuple GetBindingAndGroup( + const Variable* var) { + ast::BindingDecoration* binding = nullptr; + ast::GroupDecoration* group = nullptr; + for (auto* deco : var->Declaration()->decorations()) { + if (auto* b = deco->As()) { + binding = b; + } + if (auto* s = deco->As()) { + group = s; + } + } + return {binding, group}; +} + } // namespace Function::Function(ast::Function* declaration, @@ -82,13 +98,7 @@ Function::VariableBindings Function::ReferencedUniformVariables() const { ast::BindingDecoration* binding = nullptr; ast::GroupDecoration* group = nullptr; - for (auto* deco : var->Declaration()->decorations()) { - if (auto* b = deco->As()) { - binding = b; - } else if (auto* g = deco->As()) { - group = g; - } - } + std::tie(binding, group) = GetBindingAndGroup(var); if (binding == nullptr || group == nullptr) { continue; } @@ -108,13 +118,7 @@ Function::VariableBindings Function::ReferencedStorageBufferVariables() const { ast::BindingDecoration* binding = nullptr; ast::GroupDecoration* group = nullptr; - for (auto* deco : var->Declaration()->decorations()) { - if (auto* b = deco->As()) { - binding = b; - } else if (auto* s = deco->As()) { - group = s; - } - } + std::tie(binding, group) = GetBindingAndGroup(var); if (binding == nullptr || group == nullptr) { continue; } @@ -169,13 +173,29 @@ Function::VariableBindings Function::ReferencedStorageTextureVariables() const { ast::BindingDecoration* binding = nullptr; ast::GroupDecoration* group = nullptr; - for (auto* deco : var->Declaration()->decorations()) { - if (auto* b = deco->As()) { - binding = b; - } else if (auto* s = deco->As()) { - group = s; - } + std::tie(binding, group) = GetBindingAndGroup(var); + if (binding == nullptr || group == nullptr) { + continue; } + + ret.push_back({var, BindingInfo{binding, group}}); + } + return ret; +} + +Function::VariableBindings Function::ReferencedDepthTextureVariables() const { + VariableBindings ret; + + for (auto* var : ReferencedModuleVariables()) { + auto* unwrapped_type = var->Declaration()->type()->UnwrapIfNeeded(); + auto* storage_texture = unwrapped_type->As(); + if (storage_texture == nullptr) { + continue; + } + + ast::BindingDecoration* binding = nullptr; + ast::GroupDecoration* group = nullptr; + std::tie(binding, group) = GetBindingAndGroup(var); if (binding == nullptr || group == nullptr) { continue; } @@ -222,14 +242,7 @@ Function::VariableBindings Function::ReferencedSamplerVariablesImpl( ast::BindingDecoration* binding = nullptr; ast::GroupDecoration* group = nullptr; - for (auto* deco : var->Declaration()->decorations()) { - if (auto* b = deco->As()) { - binding = b; - } - if (auto* s = deco->As()) { - group = s; - } - } + std::tie(binding, group) = GetBindingAndGroup(var); if (binding == nullptr || group == nullptr) { continue; } @@ -259,13 +272,7 @@ Function::VariableBindings Function::ReferencedSampledTextureVariablesImpl( ast::BindingDecoration* binding = nullptr; ast::GroupDecoration* group = nullptr; - for (auto* deco : var->Declaration()->decorations()) { - if (auto* b = deco->As()) { - binding = b; - } else if (auto* s = deco->As()) { - group = s; - } - } + std::tie(binding, group) = GetBindingAndGroup(var); if (binding == nullptr || group == nullptr) { continue; }