diff --git a/src/BUILD.gn b/src/BUILD.gn index 9b7a2b2de7..5de73b285c 100644 --- a/src/BUILD.gn +++ b/src/BUILD.gn @@ -470,6 +470,9 @@ libtint_source_set("libtint_core_all_src") { "inspector/entry_point.h", "inspector/inspector.cc", "inspector/inspector.h", + "inspector/resource_binding.cc", + "inspector/resource_binding.h", + "inspector/sampler_texture_pair.h", "inspector/scalar.cc", "inspector/scalar.h", "intrinsic_table.cc", diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4a07807df7..97d8f9d34b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -217,6 +217,9 @@ set(TINT_LIB_SRCS inspector/entry_point.h inspector/inspector.cc inspector/inspector.h + inspector/resource_binding.cc + inspector/resource_binding.h + inspector/sampler_texture_pair.h inspector/scalar.cc inspector/scalar.h intrinsic_table.cc diff --git a/src/inspector/inspector.cc b/src/inspector/inspector.cc index 8fe3b3246d..a757d55acd 100644 --- a/src/inspector/inspector.cc +++ b/src/inspector/inspector.cc @@ -17,6 +17,7 @@ #include #include "src/ast/bool_literal.h" +#include "src/ast/call_expression.h" #include "src/ast/float_literal.h" #include "src/ast/module.h" #include "src/ast/override_decoration.h" @@ -24,12 +25,14 @@ #include "src/ast/sint_literal.h" #include "src/ast/uint_literal.h" #include "src/sem/array.h" +#include "src/sem/call.h" #include "src/sem/f32_type.h" #include "src/sem/function.h" #include "src/sem/i32_type.h" #include "src/sem/matrix_type.h" #include "src/sem/multisampled_texture_type.h" #include "src/sem/sampled_texture_type.h" +#include "src/sem/statement.h" #include "src/sem/storage_texture_type.h" #include "src/sem/struct.h" #include "src/sem/u32_type.h" @@ -53,131 +56,6 @@ void AppendResourceBindings(std::vector* dest, dest->insert(dest->end(), orig.begin(), orig.end()); } -ResourceBinding::TextureDimension -TypeTextureDimensionToResourceBindingTextureDimension( - const ast::TextureDimension& type_dim) { - switch (type_dim) { - case ast::TextureDimension::k1d: - return ResourceBinding::TextureDimension::k1d; - case ast::TextureDimension::k2d: - return ResourceBinding::TextureDimension::k2d; - case ast::TextureDimension::k2dArray: - return ResourceBinding::TextureDimension::k2dArray; - case ast::TextureDimension::k3d: - return ResourceBinding::TextureDimension::k3d; - case ast::TextureDimension::kCube: - return ResourceBinding::TextureDimension::kCube; - case ast::TextureDimension::kCubeArray: - return ResourceBinding::TextureDimension::kCubeArray; - case ast::TextureDimension::kNone: - return ResourceBinding::TextureDimension::kNone; - } - return ResourceBinding::TextureDimension::kNone; -} - -ResourceBinding::SampledKind BaseTypeToSampledKind(const sem::Type* base_type) { - if (!base_type) { - return ResourceBinding::SampledKind::kUnknown; - } - - if (auto* at = base_type->As()) { - base_type = const_cast(at->ElemType()); - } else if (auto* mt = base_type->As()) { - base_type = mt->type(); - } else if (auto* vt = base_type->As()) { - base_type = vt->type(); - } - - if (base_type->Is()) { - return ResourceBinding::SampledKind::kFloat; - } else if (base_type->Is()) { - return ResourceBinding::SampledKind::kUInt; - } else if (base_type->Is()) { - return ResourceBinding::SampledKind::kSInt; - } else { - return ResourceBinding::SampledKind::kUnknown; - } -} - -ResourceBinding::ImageFormat TypeImageFormatToResourceBindingImageFormat( - const ast::ImageFormat& image_format) { - switch (image_format) { - case ast::ImageFormat::kR8Unorm: - return ResourceBinding::ImageFormat::kR8Unorm; - case ast::ImageFormat::kR8Snorm: - return ResourceBinding::ImageFormat::kR8Snorm; - case ast::ImageFormat::kR8Uint: - return ResourceBinding::ImageFormat::kR8Uint; - case ast::ImageFormat::kR8Sint: - return ResourceBinding::ImageFormat::kR8Sint; - case ast::ImageFormat::kR16Uint: - return ResourceBinding::ImageFormat::kR16Uint; - case ast::ImageFormat::kR16Sint: - return ResourceBinding::ImageFormat::kR16Sint; - case ast::ImageFormat::kR16Float: - return ResourceBinding::ImageFormat::kR16Float; - case ast::ImageFormat::kRg8Unorm: - return ResourceBinding::ImageFormat::kRg8Unorm; - case ast::ImageFormat::kRg8Snorm: - return ResourceBinding::ImageFormat::kRg8Snorm; - case ast::ImageFormat::kRg8Uint: - return ResourceBinding::ImageFormat::kRg8Uint; - case ast::ImageFormat::kRg8Sint: - return ResourceBinding::ImageFormat::kRg8Sint; - case ast::ImageFormat::kR32Uint: - return ResourceBinding::ImageFormat::kR32Uint; - case ast::ImageFormat::kR32Sint: - return ResourceBinding::ImageFormat::kR32Sint; - case ast::ImageFormat::kR32Float: - return ResourceBinding::ImageFormat::kR32Float; - case ast::ImageFormat::kRg16Uint: - return ResourceBinding::ImageFormat::kRg16Uint; - case ast::ImageFormat::kRg16Sint: - return ResourceBinding::ImageFormat::kRg16Sint; - case ast::ImageFormat::kRg16Float: - return ResourceBinding::ImageFormat::kRg16Float; - case ast::ImageFormat::kRgba8Unorm: - return ResourceBinding::ImageFormat::kRgba8Unorm; - case ast::ImageFormat::kRgba8UnormSrgb: - return ResourceBinding::ImageFormat::kRgba8UnormSrgb; - case ast::ImageFormat::kRgba8Snorm: - return ResourceBinding::ImageFormat::kRgba8Snorm; - case ast::ImageFormat::kRgba8Uint: - return ResourceBinding::ImageFormat::kRgba8Uint; - case ast::ImageFormat::kRgba8Sint: - return ResourceBinding::ImageFormat::kRgba8Sint; - case ast::ImageFormat::kBgra8Unorm: - return ResourceBinding::ImageFormat::kBgra8Unorm; - case ast::ImageFormat::kBgra8UnormSrgb: - return ResourceBinding::ImageFormat::kBgra8UnormSrgb; - case ast::ImageFormat::kRgb10A2Unorm: - return ResourceBinding::ImageFormat::kRgb10A2Unorm; - case ast::ImageFormat::kRg11B10Float: - return ResourceBinding::ImageFormat::kRg11B10Float; - case ast::ImageFormat::kRg32Uint: - return ResourceBinding::ImageFormat::kRg32Uint; - case ast::ImageFormat::kRg32Sint: - return ResourceBinding::ImageFormat::kRg32Sint; - case ast::ImageFormat::kRg32Float: - return ResourceBinding::ImageFormat::kRg32Float; - case ast::ImageFormat::kRgba16Uint: - return ResourceBinding::ImageFormat::kRgba16Uint; - case ast::ImageFormat::kRgba16Sint: - return ResourceBinding::ImageFormat::kRgba16Sint; - case ast::ImageFormat::kRgba16Float: - return ResourceBinding::ImageFormat::kRgba16Float; - case ast::ImageFormat::kRgba32Uint: - return ResourceBinding::ImageFormat::kRgba32Uint; - case ast::ImageFormat::kRgba32Sint: - return ResourceBinding::ImageFormat::kRgba32Sint; - case ast::ImageFormat::kRgba32Float: - return ResourceBinding::ImageFormat::kRgba32Float; - case ast::ImageFormat::kNone: - return ResourceBinding::ImageFormat::kNone; - } - return ResourceBinding::ImageFormat::kNone; -} - } // namespace Inspector::Inspector(const Program* program) : program_(program) {} @@ -459,6 +337,8 @@ std::vector Inspector::GetSamplerResourceBindings( return {}; } + GenerateSamplerTargets(); + std::vector result; auto* func_sem = program_->Sem().Get(func); @@ -483,6 +363,8 @@ std::vector Inspector::GetComparisonSamplerResourceBindings( return {}; } + GenerateSamplerTargets(); + std::vector result; auto* func_sem = program_->Sem().Get(func); @@ -577,6 +459,22 @@ std::vector Inspector::GetExternalTextureResourceBindings( return result; } +std::vector Inspector::GetSamplerTextureUses( + const std::string& entry_point) { + auto* func = FindEntryPointByName(entry_point); + if (!func) { + return {}; + } + + GenerateSamplerTargets(); + + auto it = sampler_targets_->find(entry_point); + if (it == sampler_targets_->end()) { + return {}; + } + return it->second; +} + ast::Function* Inspector::FindEntryPointByName(const std::string& name) { auto* func = program_->AST().Functions().Find(program_->Symbols().Get(name)); if (!func) { @@ -758,5 +656,76 @@ std::vector Inspector::GetStorageTextureResourceBindingsImpl( return result; } +void Inspector::GenerateSamplerTargets() { + // Do not re-generate, since |program_| should not change during the lifetime + // of the inspector. + if (sampler_targets_ != nullptr) { + return; + } + + sampler_targets_ = std::make_unique< + std::unordered_map>>(); + + auto& sem = program_->Sem(); + + for (auto* node : program_->ASTNodes().Objects()) { + auto* c = node->As(); + if (!c) { + continue; + } + + auto* call = sem.Get(c); + if (!call) { + continue; + } + + auto* i = call->Target()->As(); + if (!i) { + continue; + } + + const auto& params = i->Parameters(); + int sampler_index = sem::IndexOf(params, sem::ParameterUsage::kSampler); + if (sampler_index == -1) { + continue; + } + + int texture_index = sem::IndexOf(params, sem::ParameterUsage::kTexture); + if (texture_index == -1) { + continue; + } + + auto* call_func = call->Stmt()->Function(); + std::vector entry_points; + if (call_func->IsEntryPoint()) { + entry_points = {call_func->symbol()}; + } else { + entry_points = sem.Get(call_func)->AncestorEntryPoints(); + } + + if (entry_points.empty()) { + continue; + } + + auto* s = c->params()[sampler_index]; + auto* sampler = sem.Get(s)->Variable(); + sem::BindingPoint sampler_binding_point = { + sampler->Declaration()->binding_point().group->value(), + sampler->Declaration()->binding_point().binding->value()}; + + auto* t = c->params()[texture_index]; + auto* texture = sem.Get(t)->Variable(); + sem::BindingPoint texture_binding_point = { + texture->Declaration()->binding_point().group->value(), + texture->Declaration()->binding_point().binding->value()}; + + for (auto entry_point : entry_points) { + const auto& ep_name = program_->Symbols().NameFor(entry_point); + (*sampler_targets_)[ep_name].add( + {sampler_binding_point, texture_binding_point}); + } + } +} + } // namespace inspector } // namespace tint diff --git a/src/inspector/inspector.h b/src/inspector/inspector.h index 8d937408dd..954907f8ec 100644 --- a/src/inspector/inspector.h +++ b/src/inspector/inspector.h @@ -19,113 +19,19 @@ #include #include #include +#include #include #include "src/inspector/entry_point.h" +#include "src/inspector/resource_binding.h" +#include "src/inspector/sampler_texture_pair.h" #include "src/inspector/scalar.h" #include "src/program.h" +#include "src/utils/unique_vector.h" namespace tint { namespace inspector { -/// Container for information about how a resource is bound -struct ResourceBinding { - /// The dimensionality of a texture - enum class TextureDimension { - /// Invalid texture - kNone = -1, - /// 1 dimensional texture - k1d, - /// 2 dimensional texture - k2d, - /// 2 dimensional array texture - k2dArray, - /// 3 dimensional texture - k3d, - /// cube texture - kCube, - /// cube array texture - kCubeArray, - }; - - /// Component type of the texture's data. Same as the Sampled Type parameter - /// in SPIR-V OpTypeImage. - enum class SampledKind { kUnknown = -1, kFloat, kUInt, kSInt }; - - /// Enumerator of texture image formats - enum class ImageFormat { - kNone = -1, - kR8Unorm, - kR8Snorm, - kR8Uint, - kR8Sint, - kR16Uint, - kR16Sint, - kR16Float, - kRg8Unorm, - kRg8Snorm, - kRg8Uint, - kRg8Sint, - kR32Uint, - kR32Sint, - kR32Float, - kRg16Uint, - kRg16Sint, - kRg16Float, - kRgba8Unorm, - kRgba8UnormSrgb, - kRgba8Snorm, - kRgba8Uint, - kRgba8Sint, - kBgra8Unorm, - kBgra8UnormSrgb, - kRgb10A2Unorm, - kRg11B10Float, - kRg32Uint, - kRg32Sint, - kRg32Float, - kRgba16Uint, - kRgba16Sint, - kRgba16Float, - kRgba32Uint, - kRgba32Sint, - kRgba32Float, - }; - - /// kXXX maps to entries returned by GetXXXResourceBindings call. - enum class ResourceType { - kUniformBuffer, - kStorageBuffer, - kReadOnlyStorageBuffer, - kSampler, - kComparisonSampler, - kSampledTexture, - kMultisampledTexture, - kReadOnlyStorageTexture, - kWriteOnlyStorageTexture, - kDepthTexture, - kExternalTexture - }; - - /// Type of resource that is bound. - ResourceType resource_type; - /// Bind group the binding belongs - uint32_t bind_group; - /// Identifier to identify this binding within the bind group - uint32_t binding; - /// Size for this binding, in bytes, if defined. - uint64_t size; - /// Size for this binding without trailing structure padding, in bytes, if - /// defined. - uint64_t size_no_padding; - /// Dimensionality of this binding, if defined. - TextureDimension dim; - /// Kind of data being sampled, if defined. - SampledKind sampled_kind; - /// Format of data, if defined. - ImageFormat image_format; -}; - /// Extracts information from a program class Inspector { public: @@ -215,9 +121,18 @@ class Inspector { std::vector GetExternalTextureResourceBindings( const std::string& entry_point); + /// @param entry_point name of the entry point to get information about. + /// @returns vector of all of the sampler/texture sampling pairs that are used + /// by that entry point. + std::vector GetSamplerTextureUses( + const std::string& entry_point); + private: const Program* program_; std::string error_; + std::unique_ptr< + std::unordered_map>> + sampler_targets_; /// @param name name of the entry point to find /// @returns a pointer to the entry point if it exists, otherwise returns @@ -259,6 +174,9 @@ class Inspector { std::vector GetStorageTextureResourceBindingsImpl( const std::string& entry_point, bool read_only); + + /// Constructes |sampler_targets_| if it hasn't already been instantiated. + void GenerateSamplerTargets(); }; } // namespace inspector diff --git a/src/inspector/inspector_test.cc b/src/inspector/inspector_test.cc index f7c9b94154..cdeceef841 100644 --- a/src/inspector/inspector_test.cc +++ b/src/inspector/inspector_test.cc @@ -475,11 +475,10 @@ class InspectorHelper : public ProgramBuilder { std::string result_name = "sampler_result"; ast::StatementList stmts; - stmts.emplace_back(Decl(Var("sampler_result", ty.vec(base_type, 4)))); + stmts.emplace_back(Decl(Var(result_name, ty.vec(base_type, 4)))); - stmts.emplace_back( - Assign("sampler_result", - Call("textureSample", texture_name, sampler_name, coords_name))); + stmts.emplace_back(Assign(result_name, Call("textureSample", texture_name, + sampler_name, coords_name))); stmts.emplace_back(Return()); return Func(func_name, ast::VariableList(), ty.void_(), stmts, decorations); @@ -737,6 +736,9 @@ class InspectorGetStorageTextureResourceBindingsTestWithParam class InspectorGetExternalTextureResourceBindingsTest : public InspectorHelper, public testing::Test {}; +class InspectorGetSamplerTextureUsesTest : public InspectorHelper, + public testing::Test {}; + TEST_F(InspectorGetEntryPointTest, NoFunctions) { Inspector& inspector = Build(); @@ -3073,6 +3075,96 @@ TEST_F(InspectorGetExternalTextureResourceBindingsTest, Simple) { EXPECT_EQ(0u, result[0].binding); } +TEST_F(InspectorGetSamplerTextureUsesTest, None) { + MakeEmptyBodyFunction("ep_func", ast::DecorationList{ + Stage(ast::PipelineStage::kFragment), + }); + + Inspector& inspector = Build(); + + auto result = inspector.GetSamplerTextureUses("ep_func"); + ASSERT_FALSE(inspector.has_error()) << inspector.error(); + + ASSERT_EQ(0u, result.size()); +} + +TEST_F(InspectorGetSamplerTextureUsesTest, Simple) { + auto* sampled_texture_type = + MakeSampledTextureType(ast::TextureDimension::k1d, ty.f32()); + AddSampledTexture("foo_texture", sampled_texture_type, 0, 10); + AddSampler("foo_sampler", 0, 1); + AddGlobalVariable("foo_coords", ty.f32()); + + MakeSamplerReferenceBodyFunction("ep_func", "foo_texture", "foo_sampler", + "foo_coords", ty.f32(), + ast::DecorationList{ + Stage(ast::PipelineStage::kFragment), + }); + + Inspector& inspector = Build(); + + auto result = inspector.GetSamplerTextureUses("ep_func"); + ASSERT_FALSE(inspector.has_error()) << inspector.error(); + + ASSERT_EQ(1u, result.size()); + + EXPECT_EQ(0u, result[0].sampler_binding_point.group); + EXPECT_EQ(1u, result[0].sampler_binding_point.binding); + EXPECT_EQ(0u, result[0].texture_binding_point.group); + EXPECT_EQ(10u, result[0].texture_binding_point.binding); +} + +TEST_F(InspectorGetSamplerTextureUsesTest, MultipleCalls) { + auto* sampled_texture_type = + MakeSampledTextureType(ast::TextureDimension::k1d, ty.f32()); + AddSampledTexture("foo_texture", sampled_texture_type, 0, 10); + AddSampler("foo_sampler", 0, 1); + AddGlobalVariable("foo_coords", ty.f32()); + + MakeSamplerReferenceBodyFunction("ep_func", "foo_texture", "foo_sampler", + "foo_coords", ty.f32(), + ast::DecorationList{ + Stage(ast::PipelineStage::kFragment), + }); + + Inspector& inspector = Build(); + + auto result_0 = inspector.GetSamplerTextureUses("ep_func"); + ASSERT_FALSE(inspector.has_error()) << inspector.error(); + + auto result_1 = inspector.GetSamplerTextureUses("ep_func"); + ASSERT_FALSE(inspector.has_error()) << inspector.error(); + + EXPECT_EQ(result_0, result_1); +} + +TEST_F(InspectorGetSamplerTextureUsesTest, InFunction) { + auto* sampled_texture_type = + MakeSampledTextureType(ast::TextureDimension::k1d, ty.f32()); + AddSampledTexture("foo_texture", sampled_texture_type, 0, 0); + AddSampler("foo_sampler", 0, 1); + AddGlobalVariable("foo_coords", ty.f32()); + + MakeSamplerReferenceBodyFunction("foo_func", "foo_texture", "foo_sampler", + "foo_coords", ty.f32(), {}); + + MakeCallerBodyFunction("ep_func", {"foo_func"}, + ast::DecorationList{ + Stage(ast::PipelineStage::kFragment), + }); + + Inspector& inspector = Build(); + + auto result = inspector.GetSamplerTextureUses("ep_func"); + ASSERT_FALSE(inspector.has_error()) << inspector.error(); + + ASSERT_EQ(1u, result.size()); + EXPECT_EQ(0u, result[0].sampler_binding_point.group); + EXPECT_EQ(1u, result[0].sampler_binding_point.binding); + EXPECT_EQ(0u, result[0].texture_binding_point.group); + EXPECT_EQ(0u, result[0].texture_binding_point.binding); +} + } // namespace } // namespace inspector } // namespace tint diff --git a/src/inspector/resource_binding.cc b/src/inspector/resource_binding.cc new file mode 100644 index 0000000000..8519140308 --- /dev/null +++ b/src/inspector/resource_binding.cc @@ -0,0 +1,154 @@ +// Copyright 2021 The Tint Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "src/inspector/resource_binding.h" + +#include "src/sem/array.h" +#include "src/sem/f32_type.h" +#include "src/sem/i32_type.h" +#include "src/sem/matrix_type.h" +#include "src/sem/type.h" +#include "src/sem/u32_type.h" +#include "src/sem/vector_type.h" + +namespace tint { +namespace inspector { + +ResourceBinding::TextureDimension +TypeTextureDimensionToResourceBindingTextureDimension( + const ast::TextureDimension& type_dim) { + switch (type_dim) { + case ast::TextureDimension::k1d: + return ResourceBinding::TextureDimension::k1d; + case ast::TextureDimension::k2d: + return ResourceBinding::TextureDimension::k2d; + case ast::TextureDimension::k2dArray: + return ResourceBinding::TextureDimension::k2dArray; + case ast::TextureDimension::k3d: + return ResourceBinding::TextureDimension::k3d; + case ast::TextureDimension::kCube: + return ResourceBinding::TextureDimension::kCube; + case ast::TextureDimension::kCubeArray: + return ResourceBinding::TextureDimension::kCubeArray; + case ast::TextureDimension::kNone: + return ResourceBinding::TextureDimension::kNone; + } + return ResourceBinding::TextureDimension::kNone; +} + +ResourceBinding::SampledKind BaseTypeToSampledKind(const sem::Type* base_type) { + if (!base_type) { + return ResourceBinding::SampledKind::kUnknown; + } + + if (auto* at = base_type->As()) { + base_type = const_cast(at->ElemType()); + } else if (auto* mt = base_type->As()) { + base_type = mt->type(); + } else if (auto* vt = base_type->As()) { + base_type = vt->type(); + } + + if (base_type->Is()) { + return ResourceBinding::SampledKind::kFloat; + } else if (base_type->Is()) { + return ResourceBinding::SampledKind::kUInt; + } else if (base_type->Is()) { + return ResourceBinding::SampledKind::kSInt; + } else { + return ResourceBinding::SampledKind::kUnknown; + } +} + +ResourceBinding::ImageFormat TypeImageFormatToResourceBindingImageFormat( + const ast::ImageFormat& image_format) { + switch (image_format) { + case ast::ImageFormat::kR8Unorm: + return ResourceBinding::ImageFormat::kR8Unorm; + case ast::ImageFormat::kR8Snorm: + return ResourceBinding::ImageFormat::kR8Snorm; + case ast::ImageFormat::kR8Uint: + return ResourceBinding::ImageFormat::kR8Uint; + case ast::ImageFormat::kR8Sint: + return ResourceBinding::ImageFormat::kR8Sint; + case ast::ImageFormat::kR16Uint: + return ResourceBinding::ImageFormat::kR16Uint; + case ast::ImageFormat::kR16Sint: + return ResourceBinding::ImageFormat::kR16Sint; + case ast::ImageFormat::kR16Float: + return ResourceBinding::ImageFormat::kR16Float; + case ast::ImageFormat::kRg8Unorm: + return ResourceBinding::ImageFormat::kRg8Unorm; + case ast::ImageFormat::kRg8Snorm: + return ResourceBinding::ImageFormat::kRg8Snorm; + case ast::ImageFormat::kRg8Uint: + return ResourceBinding::ImageFormat::kRg8Uint; + case ast::ImageFormat::kRg8Sint: + return ResourceBinding::ImageFormat::kRg8Sint; + case ast::ImageFormat::kR32Uint: + return ResourceBinding::ImageFormat::kR32Uint; + case ast::ImageFormat::kR32Sint: + return ResourceBinding::ImageFormat::kR32Sint; + case ast::ImageFormat::kR32Float: + return ResourceBinding::ImageFormat::kR32Float; + case ast::ImageFormat::kRg16Uint: + return ResourceBinding::ImageFormat::kRg16Uint; + case ast::ImageFormat::kRg16Sint: + return ResourceBinding::ImageFormat::kRg16Sint; + case ast::ImageFormat::kRg16Float: + return ResourceBinding::ImageFormat::kRg16Float; + case ast::ImageFormat::kRgba8Unorm: + return ResourceBinding::ImageFormat::kRgba8Unorm; + case ast::ImageFormat::kRgba8UnormSrgb: + return ResourceBinding::ImageFormat::kRgba8UnormSrgb; + case ast::ImageFormat::kRgba8Snorm: + return ResourceBinding::ImageFormat::kRgba8Snorm; + case ast::ImageFormat::kRgba8Uint: + return ResourceBinding::ImageFormat::kRgba8Uint; + case ast::ImageFormat::kRgba8Sint: + return ResourceBinding::ImageFormat::kRgba8Sint; + case ast::ImageFormat::kBgra8Unorm: + return ResourceBinding::ImageFormat::kBgra8Unorm; + case ast::ImageFormat::kBgra8UnormSrgb: + return ResourceBinding::ImageFormat::kBgra8UnormSrgb; + case ast::ImageFormat::kRgb10A2Unorm: + return ResourceBinding::ImageFormat::kRgb10A2Unorm; + case ast::ImageFormat::kRg11B10Float: + return ResourceBinding::ImageFormat::kRg11B10Float; + case ast::ImageFormat::kRg32Uint: + return ResourceBinding::ImageFormat::kRg32Uint; + case ast::ImageFormat::kRg32Sint: + return ResourceBinding::ImageFormat::kRg32Sint; + case ast::ImageFormat::kRg32Float: + return ResourceBinding::ImageFormat::kRg32Float; + case ast::ImageFormat::kRgba16Uint: + return ResourceBinding::ImageFormat::kRgba16Uint; + case ast::ImageFormat::kRgba16Sint: + return ResourceBinding::ImageFormat::kRgba16Sint; + case ast::ImageFormat::kRgba16Float: + return ResourceBinding::ImageFormat::kRgba16Float; + case ast::ImageFormat::kRgba32Uint: + return ResourceBinding::ImageFormat::kRgba32Uint; + case ast::ImageFormat::kRgba32Sint: + return ResourceBinding::ImageFormat::kRgba32Sint; + case ast::ImageFormat::kRgba32Float: + return ResourceBinding::ImageFormat::kRgba32Float; + case ast::ImageFormat::kNone: + return ResourceBinding::ImageFormat::kNone; + } + return ResourceBinding::ImageFormat::kNone; +} + +} // namespace inspector +} // namespace tint diff --git a/src/inspector/resource_binding.h b/src/inspector/resource_binding.h new file mode 100644 index 0000000000..faf609ab1c --- /dev/null +++ b/src/inspector/resource_binding.h @@ -0,0 +1,147 @@ +// Copyright 2021 The Tint Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SRC_INSPECTOR_RESOURCE_BINDING_H_ +#define SRC_INSPECTOR_RESOURCE_BINDING_H_ + +#include + +#include "src/ast/storage_texture.h" +#include "src/ast/texture.h" + +namespace tint { +namespace inspector { + +/// Container for information about how a resource is bound +struct ResourceBinding { + /// The dimensionality of a texture + enum class TextureDimension { + /// Invalid texture + kNone = -1, + /// 1 dimensional texture + k1d, + /// 2 dimensional texture + k2d, + /// 2 dimensional array texture + k2dArray, + /// 3 dimensional texture + k3d, + /// cube texture + kCube, + /// cube array texture + kCubeArray, + }; + + /// Component type of the texture's data. Same as the Sampled Type parameter + /// in SPIR-V OpTypeImage. + enum class SampledKind { kUnknown = -1, kFloat, kUInt, kSInt }; + + /// Enumerator of texture image formats + enum class ImageFormat { + kNone = -1, + kR8Unorm, + kR8Snorm, + kR8Uint, + kR8Sint, + kR16Uint, + kR16Sint, + kR16Float, + kRg8Unorm, + kRg8Snorm, + kRg8Uint, + kRg8Sint, + kR32Uint, + kR32Sint, + kR32Float, + kRg16Uint, + kRg16Sint, + kRg16Float, + kRgba8Unorm, + kRgba8UnormSrgb, + kRgba8Snorm, + kRgba8Uint, + kRgba8Sint, + kBgra8Unorm, + kBgra8UnormSrgb, + kRgb10A2Unorm, + kRg11B10Float, + kRg32Uint, + kRg32Sint, + kRg32Float, + kRgba16Uint, + kRgba16Sint, + kRgba16Float, + kRgba32Uint, + kRgba32Sint, + kRgba32Float, + }; + + /// kXXX maps to entries returned by GetXXXResourceBindings call. + enum class ResourceType { + kUniformBuffer, + kStorageBuffer, + kReadOnlyStorageBuffer, + kSampler, + kComparisonSampler, + kSampledTexture, + kMultisampledTexture, + kReadOnlyStorageTexture, + kWriteOnlyStorageTexture, + kDepthTexture, + kExternalTexture + }; + + /// Type of resource that is bound. + ResourceType resource_type; + /// Bind group the binding belongs + uint32_t bind_group; + /// Identifier to identify this binding within the bind group + uint32_t binding; + /// Size for this binding, in bytes, if defined. + uint64_t size; + /// Size for this binding without trailing structure padding, in bytes, if + /// defined. + uint64_t size_no_padding; + /// Dimensionality of this binding, if defined. + TextureDimension dim; + /// Kind of data being sampled, if defined. + SampledKind sampled_kind; + /// Format of data, if defined. + ImageFormat image_format; +}; + +/// Convert from internal ast::TextureDimension to public +/// ResourceBinding::TextureDimension +/// @param type_dim internal value to convert from +/// @returns the publicly visible equivalent +ResourceBinding::TextureDimension +TypeTextureDimensionToResourceBindingTextureDimension( + const ast::TextureDimension& type_dim); + +/// Infer ResourceBinding::SampledKind for a given sem::Type +/// @param base_type internal type to infer from +/// @returns the publicly visible equivalent +ResourceBinding::SampledKind BaseTypeToSampledKind(const sem::Type* base_type); + +/// Convert from internal ast::ImageFormat to public +/// ResourceBinding::ImageFormat +/// @param image_format internal value to convert from +/// @returns the publicly visible equivalent +ResourceBinding::ImageFormat TypeImageFormatToResourceBindingImageFormat( + const ast::ImageFormat& image_format); + +} // namespace inspector +} // namespace tint + +#endif // SRC_INSPECTOR_RESOURCE_BINDING_H_ diff --git a/src/inspector/sampler_texture_pair.h b/src/inspector/sampler_texture_pair.h new file mode 100644 index 0000000000..12b4f7eb00 --- /dev/null +++ b/src/inspector/sampler_texture_pair.h @@ -0,0 +1,71 @@ +// Copyright 2021 The Tint Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SRC_INSPECTOR_SAMPLER_TEXTURE_PAIR_H_ +#define SRC_INSPECTOR_SAMPLER_TEXTURE_PAIR_H_ + +#include +#include + +#include "src/sem/binding_point.h" + +namespace tint { +namespace inspector { + +/// Mapping of a sampler to a texture it samples. +struct SamplerTexturePair { + /// group & binding values for a sampler. + sem::BindingPoint sampler_binding_point; + /// group & binding values for a texture samepled by the sampler. + sem::BindingPoint texture_binding_point; + + /// Equality operator + /// @param rhs the SamplerTexturePair to compare against + /// @returns true if this SamplerTexturePair is equal to `rhs` + inline bool operator==(const SamplerTexturePair& rhs) const { + return sampler_binding_point == rhs.sampler_binding_point && + texture_binding_point == rhs.texture_binding_point; + } + + /// Inequality operator + /// @param rhs the SamplerTexturePair to compare against + /// @returns true if this SamplerTexturePair is not equal to `rhs` + inline bool operator!=(const SamplerTexturePair& rhs) const { + return !(*this == rhs); + } +}; + +} // namespace inspector +} // namespace tint + +namespace std { + +/// Custom std::hash specialization for ttint::inspector::SamplerTexturePair so +/// SamplerTexturePairss be used as keys for std::unordered_map and +/// std::unordered_set. +template <> +class hash { + public: + /// @param stp the texture pair to create a hash for + /// @return the hash value + inline std::size_t operator()( + const tint::inspector::SamplerTexturePair& stp) const { + return tint::utils::Hash(stp.sampler_binding_point, + stp.texture_binding_point); + } +}; + +} // namespace std + +#endif // SRC_INSPECTOR_SAMPLER_TEXTURE_PAIR_H_