diff --git a/samples/main.cc b/samples/main.cc index 98797bd207..44a98984e1 100644 --- a/samples/main.cc +++ b/samples/main.cc @@ -337,6 +337,8 @@ std::string ResourceTypeToString( return "WriteOnlyStorageTexture"; case tint::inspector::ResourceBinding::ResourceType::kDepthTexture: return "DepthTexture"; + case tint::inspector::ResourceBinding::ResourceType::kExternalTexture: + return "ExternalTexture"; } return "Unknown"; diff --git a/src/inspector/inspector.cc b/src/inspector/inspector.cc index a6c9ec25b8..eb79153fc9 100644 --- a/src/inspector/inspector.cc +++ b/src/inspector/inspector.cc @@ -381,7 +381,8 @@ std::vector Inspector::GetResourceBindings( AppendResourceBindings( &result, GetWriteOnlyStorageTextureResourceBindings(entry_point)); AppendResourceBindings(&result, GetDepthTextureResourceBindings(entry_point)); - + AppendResourceBindings(&result, + GetExternalTextureResourceBindings(entry_point)); return result; } @@ -531,6 +532,33 @@ std::vector Inspector::GetDepthTextureResourceBindings( return result; } +std::vector Inspector::GetExternalTextureResourceBindings( + 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->ReferencedExternalTextureVariables()) { + auto* var = ref.first; + auto binding_info = ref.second; + + ResourceBinding entry; + entry.resource_type = ResourceBinding::ResourceType::kExternalTexture; + entry.bind_group = binding_info.group->value(); + entry.binding = binding_info.binding->value(); + + auto* texture_type = var->Type()->UnwrapAccess()->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 149d70cbdf..8d937408dd 100644 --- a/src/inspector/inspector.h +++ b/src/inspector/inspector.h @@ -104,6 +104,7 @@ struct ResourceBinding { kReadOnlyStorageTexture, kWriteOnlyStorageTexture, kDepthTexture, + kExternalTexture }; /// Type of resource that is bound. @@ -209,6 +210,11 @@ class Inspector { std::vector GetDepthTextureResourceBindings( 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 external textures. + std::vector GetExternalTextureResourceBindings( + 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 39c98c61a2..2c5f01f038 100644 --- a/src/inspector/inspector_test.cc +++ b/src/inspector/inspector_test.cc @@ -19,6 +19,7 @@ #include "src/ast/struct_block_decoration.h" #include "src/ast/workgroup_decoration.h" #include "src/sem/depth_texture_type.h" +#include "src/sem/external_texture_type.h" #include "src/sem/multisampled_texture_type.h" #include "src/sem/sampled_texture_type.h" #include "src/sem/variable.h" @@ -380,6 +381,12 @@ class InspectorHelper : public ProgramBuilder { return ty.multisampled_texture(dim, type); } + /// Generates an ExternalTexture appropriate for the params + /// @returns the generated ExternalTexture + typ::ExternalTexture MakeExternalTextureType() { + return ty.external_texture(); + } + /// Adds a sampled texture variable to the program /// @param name the name of the variable /// @param type the type to use @@ -420,6 +427,18 @@ class InspectorHelper : public ProgramBuilder { AddBinding(name, type, ast::StorageClass::kNone, group, binding); } + /// Adds an external texture variable to the program + /// @param name the name of the variable + /// @param type the type to use + /// @param group the binding/group to use for the external texture + /// @param binding the binding number to use for the external texture + void AddExternalTexture(const std::string& name, + ast::Type* type, + uint32_t group, + uint32_t binding) { + AddBinding(name, type, ast::StorageClass::kNone, group, binding); + } + /// 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 @@ -697,6 +716,9 @@ class InspectorGetStorageTextureResourceBindingsTestWithParam : public InspectorHelper, public testing::TestWithParam {}; +class InspectorGetExternalTextureResourceBindingsTest : public InspectorHelper, + public testing::Test {}; + TEST_F(InspectorGetEntryPointTest, NoFunctions) { Inspector& inspector = Build(); @@ -2936,6 +2958,30 @@ INSTANTIATE_TEST_SUITE_P( ast::TextureDimension::kCubeArray, inspector::ResourceBinding::TextureDimension::kCubeArray})); +TEST_F(InspectorGetExternalTextureResourceBindingsTest, Simple) { + auto external_texture_type = MakeExternalTextureType(); + AddExternalTexture("et", external_texture_type, 0, 0); + + Func("ep", ast::VariableList(), ty.void_(), + ast::StatementList{ + create(Call("textureDimensions", "et")), + }, + ast::DecorationList{ + Stage(ast::PipelineStage::kFragment), + }); + + Inspector& inspector = Build(); + + auto result = inspector.GetExternalTextureResourceBindings("ep"); + ASSERT_FALSE(inspector.has_error()) << inspector.error(); + EXPECT_EQ(ResourceBinding::ResourceType::kExternalTexture, + result[0].resource_type); + + ASSERT_EQ(1u, result.size()); + EXPECT_EQ(0u, result[0].bind_group); + EXPECT_EQ(0u, result[0].binding); +} + } // namespace } // namespace inspector } // namespace tint diff --git a/src/program_builder.h b/src/program_builder.h index 74367bcbeb..610f1eb72e 100644 --- a/src/program_builder.h +++ b/src/program_builder.h @@ -869,6 +869,12 @@ class ProgramBuilder { dims, format, ast::AccessControl::kInvalid, sem_subtype)}; } + /// @returns the external texture + typ::ExternalTexture external_texture() const { + return {builder->create(), + builder->create()}; + } + /// @param source the Source of the node /// @returns the external texture typ::ExternalTexture external_texture(const Source& source) const { diff --git a/src/sem/function.cc b/src/sem/function.cc index 5a5a15155e..35c2e713e8 100644 --- a/src/sem/function.cc +++ b/src/sem/function.cc @@ -16,6 +16,7 @@ #include "src/ast/function.h" #include "src/sem/depth_texture_type.h" +#include "src/sem/external_texture_type.h" #include "src/sem/multisampled_texture_type.h" #include "src/sem/sampled_texture_type.h" #include "src/sem/storage_texture_type.h" @@ -168,6 +169,24 @@ Function::VariableBindings Function::ReferencedDepthTextureVariables() const { return ret; } +Function::VariableBindings Function::ReferencedExternalTextureVariables() + const { + VariableBindings ret; + + for (auto* var : ReferencedModuleVariables()) { + auto* unwrapped_type = var->Type()->UnwrapAccess(); + auto* external_texture = unwrapped_type->As(); + if (external_texture == nullptr) { + continue; + } + + if (auto binding_point = var->Declaration()->binding_point()) { + ret.push_back({var, binding_point}); + } + } + return ret; +} + bool Function::HasAncestorEntryPoint(Symbol symbol) const { for (const auto& point : ancestor_entry_points_) { if (point == symbol) { diff --git a/src/sem/function.h b/src/sem/function.h index 3b107ee7c2..a29e318251 100644 --- a/src/sem/function.h +++ b/src/sem/function.h @@ -135,9 +135,14 @@ class Function : public Castable { /// Retrieves any referenced depth texture variables. Note, the variables /// must be decorated with both binding and group decorations. - /// @returns the referenced storage textures + /// @returns the referenced depth textures VariableBindings ReferencedDepthTextureVariables() const; + /// Retrieves any referenced external texture variables. Note, the variables + /// must be decorated with both binding and group decorations. + /// @returns the referenced external textures + VariableBindings ReferencedExternalTextureVariables() const; + /// Checks if the given entry point is an ancestor /// @param sym the entry point symbol /// @returns true if `sym` is an ancestor entry point of this function