Add texture_external to inspector
Adds texture_external to the inspector, allowing us to recognize the
type and return provide binding information. Includes a basic test.
Bug: Dawn:728
Change-Id: Ib0f39998359dc22a530ad222141229f9ba30552f
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/51161
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
Commit-Queue: Brandon Jones <brandon1.jones@intel.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/samples/main.cc b/samples/main.cc
index 98797bd..44a9898 100644
--- a/samples/main.cc
+++ b/samples/main.cc
@@ -337,6 +337,8 @@
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 a6c9ec2..eb79153 100644
--- a/src/inspector/inspector.cc
+++ b/src/inspector/inspector.cc
@@ -381,7 +381,8 @@
AppendResourceBindings(
&result, GetWriteOnlyStorageTextureResourceBindings(entry_point));
AppendResourceBindings(&result, GetDepthTextureResourceBindings(entry_point));
-
+ AppendResourceBindings(&result,
+ GetExternalTextureResourceBindings(entry_point));
return result;
}
@@ -531,6 +532,33 @@
return result;
}
+std::vector<ResourceBinding> Inspector::GetExternalTextureResourceBindings(
+ const std::string& entry_point) {
+ auto* func = FindEntryPointByName(entry_point);
+ if (!func) {
+ return {};
+ }
+
+ std::vector<ResourceBinding> 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<sem::Texture>();
+ 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 149d70c..8d93740 100644
--- a/src/inspector/inspector.h
+++ b/src/inspector/inspector.h
@@ -104,6 +104,7 @@
kReadOnlyStorageTexture,
kWriteOnlyStorageTexture,
kDepthTexture,
+ kExternalTexture
};
/// Type of resource that is bound.
@@ -209,6 +210,11 @@
std::vector<ResourceBinding> 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<ResourceBinding> 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 39c98c6..2c5f01f 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 @@
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 @@
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 @@
: public InspectorHelper,
public testing::TestWithParam<GetStorageTextureTestParams> {};
+class InspectorGetExternalTextureResourceBindingsTest : public InspectorHelper,
+ public testing::Test {};
+
TEST_F(InspectorGetEntryPointTest, NoFunctions) {
Inspector& inspector = Build();
@@ -2936,6 +2958,30 @@
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<ast::CallStatement>(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 74367bc..610f1eb 100644
--- a/src/program_builder.h
+++ b/src/program_builder.h
@@ -869,6 +869,12 @@
dims, format, ast::AccessControl::kInvalid, sem_subtype)};
}
+ /// @returns the external texture
+ typ::ExternalTexture external_texture() const {
+ return {builder->create<ast::ExternalTexture>(),
+ builder->create<sem::ExternalTexture>()};
+ }
+
/// @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 5a5a151..35c2e71 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 @@
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<sem::ExternalTexture>();
+ 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 3b107ee..a29e318 100644
--- a/src/sem/function.h
+++ b/src/sem/function.h
@@ -135,9 +135,14 @@
/// 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