From 110af53089fd97f0132bccb411da27d3f570b717 Mon Sep 17 00:00:00 2001 From: Ryan Harrison Date: Fri, 6 Nov 2020 17:53:45 +0000 Subject: [PATCH] [inspector] Extract ComparisonSampler resource binding information Adds in method to get resource binding information for comparison samplers along with tests. BUG=tint:257 Change-Id: I60f675347d2b9596308b1599d0a9b846615d547e Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/31980 Commit-Queue: David Neto Reviewed-by: David Neto --- src/inspector/inspector.cc | 24 ++++ src/inspector/inspector.h | 5 + src/inspector/inspector_test.cc | 201 ++++++++++++++++++++++++++++++++ 3 files changed, 230 insertions(+) diff --git a/src/inspector/inspector.cc b/src/inspector/inspector.cc index 43d11f7605..6af2d0232c 100644 --- a/src/inspector/inspector.cc +++ b/src/inspector/inspector.cc @@ -211,6 +211,30 @@ std::vector Inspector::GetSamplerResourceBindings( return result; } +std::vector Inspector::GetComparisonSamplerResourceBindings( + const std::string& entry_point) { + auto* func = FindEntryPointByName(entry_point); + if (!func) { + return {}; + } + + std::vector result; + + for (auto& rcs : func->referenced_comparison_sampler_variables()) { + ResourceBinding entry; + ast::Variable* var = nullptr; + ast::Function::BindingInfo binding_info; + std::tie(var, binding_info) = rcs; + + entry.bind_group = binding_info.set->value(); + entry.binding = binding_info.binding->value(); + + result.push_back(std::move(entry)); + } + + return result; +} + ast::Function* Inspector::FindEntryPointByName(const std::string& name) { auto* func = module_.FindFunctionByName(name); if (!func) { diff --git a/src/inspector/inspector.h b/src/inspector/inspector.h index d2e39a8ea7..7034a8a956 100644 --- a/src/inspector/inspector.h +++ b/src/inspector/inspector.h @@ -78,6 +78,11 @@ class Inspector { std::vector GetSamplerResourceBindings( 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 comparison samplers. + std::vector GetComparisonSamplerResourceBindings( + const std::string& entry_point); + private: const ast::Module& module_; std::string error_; diff --git a/src/inspector/inspector_test.cc b/src/inspector/inspector_test.cc index 5edfb124b8..d65a3ca7cf 100644 --- a/src/inspector/inspector_test.cc +++ b/src/inspector/inspector_test.cc @@ -42,6 +42,7 @@ #include "src/ast/type/access_control_type.h" #include "src/ast/type/array_type.h" #include "src/ast/type/bool_type.h" +#include "src/ast/type/depth_texture_type.h" #include "src/ast/type/f32_type.h" #include "src/ast/type/i32_type.h" #include "src/ast/type/matrix_type.h" @@ -454,6 +455,15 @@ class InspectorHelper { return std::make_unique(dim, type); } + /// Generates a DepthTextureType appropriate for the params + /// @param dim the dimensions of the texture + /// @param type the data type of the sampled texture + /// @returns the generated DepthTextureType + std::unique_ptr MakeDepthTextureType( + ast::type::TextureDimension dim) { + return std::make_unique(dim); + } + /// Adds a sampled texture variable to the module /// @param name the name of the variable /// @param type the type to use @@ -471,6 +481,20 @@ class InspectorHelper { name, ast::StorageClass::kUniformConstant, f32_type())); } + /// Adds a depth texture variable to the module + /// @param name the name of the variable + /// @param type the type to use + void AddDepthTexture(const std::string& name, ast::type::Type* type) { + mod()->AddGlobalVariable(std::make_unique( + name, ast::StorageClass::kUniformConstant, type)); + } + + /// Generates a function that references a specific sampler variable + /// @param func_name name of the function created + /// @param texture_name name of the texture to be sampled + /// @param sampler_name name of the sampler to use + /// @param coords_name name of the coords variable to use + /// @returns a function that references all of the values specified std::unique_ptr MakeSamplerReferenceBodyFunction( const std::string& func_name, const std::string& texture_name, @@ -507,6 +531,53 @@ class InspectorHelper { return func; } + /// Generates a function that references a specific comparison sampler + /// variable. + /// @param func_name name of the function created + /// @param texture_name name of the depth texture to use + /// @param sampler_name name of the sampler to use + /// @param coords_name name of the coords variable to use + /// @param depth_name name of the depth reference to use + /// @returns a function that references all of the values specified + std::unique_ptr MakeComparisonSamplerReferenceBodyFunction( + const std::string& func_name, + const std::string& texture_name, + const std::string& sampler_name, + const std::string& coords_name, + const std::string& depth_name) { + std::string result_name = "sampler_result"; + + auto body = std::make_unique(); + + auto call_result = std::make_unique( + "sampler_result", ast::StorageClass::kFunction, f32_type()); + body->append( + std::make_unique(std::move(call_result))); + + ast::ExpressionList call_params; + call_params.push_back( + std::make_unique(texture_name)); + call_params.push_back( + std::make_unique(sampler_name)); + call_params.push_back( + std::make_unique(coords_name)); + call_params.push_back( + std::make_unique(depth_name)); + auto call_expr = std::make_unique( + std::make_unique("textureSampleCompare"), + std::move(call_params)); + + body->append(std::make_unique( + std::make_unique("sampler_result"), + std::move(call_expr))); + body->append(std::make_unique()); + + auto func = std::make_unique(func_name, ast::VariableList(), + void_type()); + func->set_body(std::move(body)); + return func; + } + ast::Module* mod() { return &mod_; } TypeDeterminer* td() { return td_.get(); } Inspector* inspector() { return inspector_.get(); } @@ -556,6 +627,8 @@ class InspectorGetStorageBufferResourceBindingsTest : public InspectorTest {}; class InspectorGetReadOnlyStorageBufferResourceBindingsTest : public InspectorTest {}; class InspectorGetSamplerResourceBindingsTest : public InspectorTest {}; +class InspectorGetComparisonSamplerResourceBindingsTest : public InspectorTest { +}; TEST_F(InspectorGetEntryPointTest, NoFunctions) { auto result = inspector()->GetEntryPoints(); @@ -1616,6 +1689,134 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, UnknownEntryPoint) { ASSERT_TRUE(inspector()->has_error()) << inspector()->error(); } +TEST_F(InspectorGetSamplerResourceBindingsTest, SkipsComparisonSamplers) { + auto depth_texture_type = + MakeDepthTextureType(ast::type::TextureDimension::k2d); + AddDepthTexture("foo_texture", depth_texture_type.get()); + AddComparisonSampler("foo_sampler", 0, 1); + AddF32("foo_coords"); + AddF32("foo_depth"); + + auto func = MakeComparisonSamplerReferenceBodyFunction( + "ep", "foo_texture", "foo_sampler", "foo_coords", "foo_depth"); + func->add_decoration(std::make_unique( + ast::PipelineStage::kVertex, Source{})); + mod()->AddFunction(std::move(func)); + + ASSERT_TRUE(td()->Determine()) << td()->error(); + + auto result = inspector()->GetSamplerResourceBindings("ep"); + ASSERT_FALSE(inspector()->has_error()) << inspector()->error(); + + ASSERT_EQ(0u, result.size()); +} + +TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, Simple) { + auto depth_texture_type = + MakeDepthTextureType(ast::type::TextureDimension::k2d); + AddDepthTexture("foo_texture", depth_texture_type.get()); + AddComparisonSampler("foo_sampler", 0, 1); + AddF32("foo_coords"); + AddF32("foo_depth"); + + auto func = MakeComparisonSamplerReferenceBodyFunction( + "ep", "foo_texture", "foo_sampler", "foo_coords", "foo_depth"); + func->add_decoration(std::make_unique( + ast::PipelineStage::kVertex, Source{})); + mod()->AddFunction(std::move(func)); + + ASSERT_TRUE(td()->Determine()) << td()->error(); + + auto result = inspector()->GetComparisonSamplerResourceBindings("ep"); + ASSERT_FALSE(inspector()->has_error()) << inspector()->error(); + + ASSERT_EQ(1u, result.size()); + EXPECT_EQ(0u, result[0].bind_group); + EXPECT_EQ(1u, result[0].binding); +} + +TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, NoSampler) { + auto func = MakeEmptyBodyFunction("ep_func"); + func->add_decoration(std::make_unique( + ast::PipelineStage::kVertex, Source{})); + mod()->AddFunction(std::move(func)); + + ASSERT_TRUE(td()->Determine()) << td()->error(); + + auto result = inspector()->GetComparisonSamplerResourceBindings("ep_func"); + ASSERT_FALSE(inspector()->has_error()) << inspector()->error(); + + ASSERT_EQ(0u, result.size()); +} + +TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, InFunction) { + auto depth_texture_type = + MakeDepthTextureType(ast::type::TextureDimension::k2d); + AddDepthTexture("foo_texture", depth_texture_type.get()); + AddComparisonSampler("foo_sampler", 0, 1); + AddF32("foo_coords"); + AddF32("foo_depth"); + + auto foo_func = MakeComparisonSamplerReferenceBodyFunction( + "foo_func", "foo_texture", "foo_sampler", "foo_coords", "foo_depth"); + mod()->AddFunction(std::move(foo_func)); + + auto ep_func = MakeCallerBodyFunction("ep_func", "foo_func"); + ep_func->add_decoration(std::make_unique( + ast::PipelineStage::kVertex, Source{})); + mod()->AddFunction(std::move(ep_func)); + + ASSERT_TRUE(td()->Determine()) << td()->error(); + + auto result = inspector()->GetComparisonSamplerResourceBindings("ep_func"); + ASSERT_FALSE(inspector()->has_error()) << inspector()->error(); + + ASSERT_EQ(1u, result.size()); + EXPECT_EQ(0u, result[0].bind_group); + EXPECT_EQ(1u, result[0].binding); +} + +TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, UnknownEntryPoint) { + auto depth_texture_type = + MakeDepthTextureType(ast::type::TextureDimension::k2d); + AddDepthTexture("foo_texture", depth_texture_type.get()); + AddComparisonSampler("foo_sampler", 0, 1); + AddF32("foo_coords"); + AddF32("foo_depth"); + + auto func = MakeComparisonSamplerReferenceBodyFunction( + "ep", "foo_texture", "foo_sampler", "foo_coords", "foo_depth"); + func->add_decoration(std::make_unique( + ast::PipelineStage::kVertex, Source{})); + mod()->AddFunction(std::move(func)); + + ASSERT_TRUE(td()->Determine()) << td()->error(); + + auto result = inspector()->GetSamplerResourceBindings("foo"); + ASSERT_TRUE(inspector()->has_error()) << inspector()->error(); +} + +TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, SkipsSamplers) { + auto sampled_texture_type = + MakeSampledTextureType(ast::type::TextureDimension::k1d, f32_type()); + AddSampledTexture("foo_texture", sampled_texture_type.get(), 0, 0); + AddSampler("foo_sampler", 0, 1); + AddF32("foo_coords"); + + auto func = MakeSamplerReferenceBodyFunction("ep", "foo_texture", + "foo_sampler", "foo_coords"); + func->add_decoration(std::make_unique( + ast::PipelineStage::kVertex, Source{})); + mod()->AddFunction(std::move(func)); + + ASSERT_TRUE(td()->Determine()) << td()->error(); + + auto result = inspector()->GetComparisonSamplerResourceBindings("ep"); + ASSERT_FALSE(inspector()->has_error()) << inspector()->error(); + + ASSERT_EQ(0u, result.size()); +} + } // namespace } // namespace inspector } // namespace tint