Add texture_external parsing and intrinsic overloads
Adds texture_external to ParserImpl. Adds texture_external overloads to
TextureSample, TextureLoad, and TextureDimensions to the intrisic table.
Adds corresponding tests.
Bug: dawn:728
Change-Id: I5e5557a10327f8c3d3044319decd748f812ecf3e
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/48722
Reviewed-by: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index d5e3737..605fa55 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -639,6 +639,7 @@
reader/wgsl/parser_impl_continue_stmt_test.cc
reader/wgsl/parser_impl_continuing_stmt_test.cc
reader/wgsl/parser_impl_depth_texture_type_test.cc
+ reader/wgsl/parser_impl_external_texture_type_test.cc
reader/wgsl/parser_impl_else_stmt_test.cc
reader/wgsl/parser_impl_elseif_stmt_test.cc
reader/wgsl/parser_impl_equality_expression_test.cc
diff --git a/src/intrinsic_table.cc b/src/intrinsic_table.cc
index b4164ed..2652ab8 100644
--- a/src/intrinsic_table.cc
+++ b/src/intrinsic_table.cc
@@ -22,6 +22,7 @@
#include "src/program_builder.h"
#include "src/sem/access_control_type.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"
@@ -570,6 +571,22 @@
OpenType const channel_format_;
};
+/// ExternalTextureBuilder is a Matcher / Builder for external textures.
+class ExternalTextureBuilder : public Builder {
+ public:
+ ExternalTextureBuilder() {}
+
+ bool MatchUnwrapped(MatchState&, sem::Type* ty) const override {
+ return ty->Is<sem::ExternalTexture>();
+ }
+
+ sem::Type* Build(BuildState& state) const override {
+ return state.ty_mgr.Get<sem::ExternalTexture>();
+ }
+
+ std::string str() const override { return "texture_external"; }
+};
+
/// SamplerBuilder is a Matcher / Builder for sampler types of the given kind.
class SamplerBuilder : public Builder {
public:
@@ -759,6 +776,11 @@
dimensions, texel_format, channel_format);
}
+ /// @returns a Matcher / Builder that matches an external texture
+ Builder* external_texture() {
+ return matcher_allocator_.Create<ExternalTextureBuilder>();
+ }
+
/// @returns a Matcher / Builder that matches a sampler type
Builder* sampler(ast::SamplerKind kind) {
return matcher_allocator_.Create<SamplerBuilder>(kind);
@@ -1091,6 +1113,7 @@
auto* tex_depth_2d_array = depth_texture(Dim::k2dArray);
auto* tex_depth_cube = depth_texture(Dim::kCube);
auto* tex_depth_cube_array = depth_texture(Dim::kCubeArray);
+ auto* tex_external = external_texture();
auto* tex_storage_1d_FT =
storage_texture(Dim::k1d, OpenNumber::F, OpenType::T);
auto* tex_storage_2d_FT =
@@ -1159,6 +1182,7 @@
Register(I::kTextureDimensions, vec2_i32, {{t, tex_storage_2d_FT}, }); // NOLINT
Register(I::kTextureDimensions, vec2_i32, {{t, tex_storage_2d_array_FT}, }); // NOLINT
Register(I::kTextureDimensions, vec3_i32, {{t, tex_storage_3d_FT}, }); // NOLINT
+ Register(I::kTextureDimensions, vec2_i32, {{t, tex_external}, }); // NOLINT
Register(I::kTextureNumLayers, i32, {{t, tex_2d_array_T}, });
Register(I::kTextureNumLayers, i32, {{t, tex_cube_array_T}, });
@@ -1195,6 +1219,8 @@
Register(I::kTextureSample, f32, {{t, tex_depth_2d_array}, {s, sampler}, {coords, vec2_f32}, {array_index, i32}, {offset, vec2_i32}, }); // NOLINT
Register(I::kTextureSample, f32, {{t, tex_depth_cube}, {s, sampler}, {coords, vec3_f32}, }); // NOLINT
Register(I::kTextureSample, f32, {{t, tex_depth_cube_array}, {s, sampler}, {coords, vec3_f32}, {array_index, i32}, }); // NOLINT
+ Register(I::kTextureSample, vec4_f32, {{t, tex_external}, {s, sampler}, {coords, vec2_f32}, }); // NOLINT
+ Register(I::kTextureSample, vec4_f32, {{t, tex_external}, {s, sampler}, {coords, vec2_f32}, {offset, vec2_i32}, }); // NOLINT
Register(I::kTextureSampleBias, vec4_f32, {{t, tex_2d_f32}, {s, sampler}, {coords, vec2_f32}, {bias, f32}, }); // NOLINT
Register(I::kTextureSampleBias, vec4_f32, {{t, tex_2d_f32}, {s, sampler}, {coords, vec2_f32}, {bias, f32}, {offset, vec2_i32}, }); // NOLINT
@@ -1241,18 +1267,19 @@
Register(I::kTextureStore, void_, {{t, tex_storage_wo_2d_array_FT},{coords, vec2_i32}, {array_index, i32}, {value, vec4_T}, }); // NOLINT
Register(I::kTextureStore, void_, {{t, tex_storage_wo_3d_FT}, {coords, vec3_i32}, {value, vec4_T}, }); // NOLINT
- Register(I::kTextureLoad, vec4_T, {{t, tex_1d_T}, {coords, i32}, {level, i32}, }); // NOLINT
- Register(I::kTextureLoad, vec4_T, {{t, tex_2d_T}, {coords, vec2_i32}, {level, i32}, }); // NOLINT
- Register(I::kTextureLoad, vec4_T, {{t, tex_2d_array_T}, {coords, vec2_i32}, {array_index, i32}, {level, i32}, }); // NOLINT
- Register(I::kTextureLoad, vec4_T, {{t, tex_3d_T}, {coords, vec3_i32}, {level, i32}, }); // NOLINT
- Register(I::kTextureLoad, vec4_T, {{t, tex_ms_2d_T}, {coords, vec2_i32}, {sample_index, i32}, }); // NOLINT
- Register(I::kTextureLoad, vec4_T, {{t, tex_ms_2d_array_T}, {coords, vec2_i32}, {array_index, i32}, {sample_index, i32}, }); // NOLINT
- Register(I::kTextureLoad, f32, {{t, tex_depth_2d}, {coords, vec2_i32}, {level, i32}, }); // NOLINT
- Register(I::kTextureLoad, f32, {{t, tex_depth_2d_array}, {coords, vec2_i32}, {array_index, i32}, {level, i32}, }); // NOLINT
- Register(I::kTextureLoad, vec4_T, {{t, tex_storage_ro_1d_FT}, {coords, i32}, }); // NOLINT
- Register(I::kTextureLoad, vec4_T, {{t, tex_storage_ro_2d_FT}, {coords, vec2_i32}, }); // NOLINT
- Register(I::kTextureLoad, vec4_T, {{t, tex_storage_ro_2d_array_FT},{coords, vec2_i32}, {array_index, i32}, }); // NOLINT
- Register(I::kTextureLoad, vec4_T, {{t, tex_storage_ro_3d_FT}, {coords, vec3_i32}, }); // NOLINT
+ Register(I::kTextureLoad, vec4_T, {{t, tex_1d_T}, {coords, i32}, {level, i32}, }); // NOLINT
+ Register(I::kTextureLoad, vec4_T, {{t, tex_2d_T}, {coords, vec2_i32}, {level, i32}, }); // NOLINT
+ Register(I::kTextureLoad, vec4_T, {{t, tex_2d_array_T}, {coords, vec2_i32}, {array_index, i32}, {level, i32}, }); // NOLINT
+ Register(I::kTextureLoad, vec4_T, {{t, tex_3d_T}, {coords, vec3_i32}, {level, i32}, }); // NOLINT
+ Register(I::kTextureLoad, vec4_T, {{t, tex_ms_2d_T}, {coords, vec2_i32}, {sample_index, i32}, }); // NOLINT
+ Register(I::kTextureLoad, vec4_T, {{t, tex_ms_2d_array_T}, {coords, vec2_i32}, {array_index, i32}, {sample_index, i32}, }); // NOLINT
+ Register(I::kTextureLoad, f32, {{t, tex_depth_2d}, {coords, vec2_i32}, {level, i32}, }); // NOLINT
+ Register(I::kTextureLoad, f32, {{t, tex_depth_2d_array}, {coords, vec2_i32}, {array_index, i32}, {level, i32}, }); // NOLINT
+ Register(I::kTextureLoad, vec4_T, {{t, tex_storage_ro_1d_FT}, {coords, i32}, }); // NOLINT
+ Register(I::kTextureLoad, vec4_T, {{t, tex_storage_ro_2d_FT}, {coords, vec2_i32}, }); // NOLINT
+ Register(I::kTextureLoad, vec4_T, {{t, tex_storage_ro_2d_array_FT},{coords, vec2_i32}, {array_index, i32}, }); // NOLINT
+ Register(I::kTextureLoad, vec4_T, {{t, tex_storage_ro_3d_FT}, {coords, vec3_i32}, }); // NOLINT
+ Register(I::kTextureLoad, vec4_f32, {{t, tex_external}, {coords, vec2_i32} }); // NOLINT
// clang-format on
diff --git a/src/intrinsic_table_test.cc b/src/intrinsic_table_test.cc
index a7a9f00..deae118 100644
--- a/src/intrinsic_table_test.cc
+++ b/src/intrinsic_table_test.cc
@@ -18,6 +18,7 @@
#include "src/program_builder.h"
#include "src/sem/access_control_type.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"
@@ -285,6 +286,20 @@
Parameter{ty.i32(), Parameter::Usage::kLevel}));
}
+TEST_F(IntrinsicTableTest, MatchExternalTexture) {
+ auto* tex = create<sem::ExternalTexture>();
+ auto result = table->Lookup(*this, IntrinsicType::kTextureLoad,
+ {tex, ty.vec2<i32>()}, Source{});
+ ASSERT_NE(result.intrinsic, nullptr);
+ ASSERT_EQ(result.diagnostics.str(), "");
+ EXPECT_THAT(result.intrinsic->Type(), IntrinsicType::kTextureLoad);
+ EXPECT_THAT(result.intrinsic->ReturnType(), ty.vec4<f32>());
+ EXPECT_THAT(
+ result.intrinsic->Parameters(),
+ ElementsAre(Parameter{tex, Parameter::Usage::kTexture},
+ Parameter{ty.vec2<i32>(), Parameter::Usage::kCoords}));
+}
+
TEST_F(IntrinsicTableTest, MatchROStorageTexture) {
auto tex = ty.storage_texture(ast::TextureDimension::k2d,
ast::ImageFormat::kR16Float);
@@ -431,7 +446,7 @@
ASSERT_EQ(result.diagnostics.str(),
R"(error: no matching call to textureDimensions(bool, bool)
-25 candidate functions:
+26 candidate functions:
textureDimensions(texture : texture_2d<T>, level : i32) -> vec2<i32>
textureDimensions(texture : texture_2d_array<T>, level : i32) -> vec2<i32>
textureDimensions(texture : texture_3d<T>, level : i32) -> vec3<i32>
@@ -457,6 +472,7 @@
textureDimensions(texture : texture_storage_2d<F>) -> vec2<i32>
textureDimensions(texture : texture_storage_2d_array<F>) -> vec2<i32>
textureDimensions(texture : texture_storage_3d<F>) -> vec3<i32>
+ textureDimensions(texture : texture_external) -> vec2<i32>
)");
}
@@ -468,7 +484,7 @@
result.diagnostics.str(),
R"(error: no matching call to textureDimensions(texture_depth_2d, bool)
-25 candidate functions:
+26 candidate functions:
textureDimensions(texture : texture_depth_2d, level : i32) -> vec2<i32>
textureDimensions(texture : texture_depth_2d) -> vec2<i32>
textureDimensions(texture : texture_2d<T>, level : i32) -> vec2<i32>
@@ -494,6 +510,7 @@
textureDimensions(texture : texture_storage_2d<F>) -> vec2<i32>
textureDimensions(texture : texture_storage_2d_array<F>) -> vec2<i32>
textureDimensions(texture : texture_storage_3d<F>) -> vec3<i32>
+ textureDimensions(texture : texture_external) -> vec2<i32>
)");
}
diff --git a/src/reader/wgsl/lexer.cc b/src/reader/wgsl/lexer.cc
index b224788..bfc34c0 100644
--- a/src/reader/wgsl/lexer.cc
+++ b/src/reader/wgsl/lexer.cc
@@ -650,6 +650,9 @@
return {Token::Type::kTextureDepthCubeArray, source,
"texture_depth_cube_array"};
}
+ if (str == "texture_external") {
+ return {Token::Type::kTextureExternal, source, "texture_external"};
+ }
if (str == "texture_multisampled_2d") {
return {Token::Type::kTextureMultisampled2d, source,
"texture_multisampled_2d"};
diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc
index 4783c4f..f09b481 100644
--- a/src/reader/wgsl/parser_impl.cc
+++ b/src/reader/wgsl/parser_impl.cc
@@ -26,6 +26,7 @@
#include "src/reader/wgsl/lexer.h"
#include "src/sem/access_control_type.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"
@@ -516,6 +517,10 @@
if (type.matched)
return type.value;
+ type = external_texture_type();
+ if (type.matched)
+ return type.value;
+
auto dim = sampled_texture_type();
if (dim.matched) {
const char* use = "sampled texture type";
@@ -600,6 +605,16 @@
return Failure::kNoMatch;
}
+// external_texture_type
+// : TEXTURE_EXTERNAL
+Maybe<sem::Type*> ParserImpl::external_texture_type() {
+ if (match(Token::Type::kTextureExternal)) {
+ return builder_.create<sem::ExternalTexture>();
+ }
+
+ return Failure::kNoMatch;
+}
+
// multisampled_texture_type
// : TEXTURE_MULTISAMPLED_2D
Maybe<ast::TextureDimension> ParserImpl::multisampled_texture_type() {
diff --git a/src/reader/wgsl/parser_impl.h b/src/reader/wgsl/parser_impl.h
index fe42a76..6b01db2 100644
--- a/src/reader/wgsl/parser_impl.h
+++ b/src/reader/wgsl/parser_impl.h
@@ -414,6 +414,9 @@
/// Parses a `depth_texture_type` grammar element
/// @returns the parsed Type or nullptr if none matched.
Maybe<sem::Type*> depth_texture_type();
+ /// Parses a 'texture_external_type' grammar element
+ /// @returns the parsed Type or nullptr if none matched
+ Maybe<sem::Type*> external_texture_type();
/// Parses a `image_storage_type` grammar element
/// @param use a description of what was being parsed if an error was raised
/// @returns returns the image format or kNone if none matched.
diff --git a/src/reader/wgsl/parser_impl_external_texture_type_test.cc b/src/reader/wgsl/parser_impl_external_texture_type_test.cc
new file mode 100644
index 0000000..92a8738
--- /dev/null
+++ b/src/reader/wgsl/parser_impl_external_texture_type_test.cc
@@ -0,0 +1,40 @@
+// 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/reader/wgsl/parser_impl_test_helper.h"
+
+namespace tint {
+namespace reader {
+namespace wgsl {
+namespace {
+
+TEST_F(ParserImplTest, ExternalTextureType_Invalid) {
+ auto p = parser("1234");
+ auto t = p->external_texture_type();
+ EXPECT_FALSE(t.matched);
+ EXPECT_FALSE(t.errored);
+ EXPECT_FALSE(p->has_error());
+}
+
+TEST_F(ParserImplTest, ExternalTextureType) {
+ auto p = parser("texture_external");
+ auto t = p->external_texture_type();
+ EXPECT_TRUE(t.matched);
+ EXPECT_FALSE(t.errored);
+}
+
+} // namespace
+} // namespace wgsl
+} // namespace reader
+} // namespace tint
diff --git a/src/reader/wgsl/token.cc b/src/reader/wgsl/token.cc
index a89c2ef..f131cd9 100644
--- a/src/reader/wgsl/token.cc
+++ b/src/reader/wgsl/token.cc
@@ -269,6 +269,8 @@
return "texture_depth_cube";
case Token::Type::kTextureDepthCubeArray:
return "texture_depth_cube_array";
+ case Token::Type::kTextureExternal:
+ return "texture_external";
case Token::Type::kTextureMultisampled2d:
return "texture_multisampled_2d";
case Token::Type::kTextureSampled1d:
diff --git a/src/reader/wgsl/token.h b/src/reader/wgsl/token.h
index 6e4581f..10c6b0e 100644
--- a/src/reader/wgsl/token.h
+++ b/src/reader/wgsl/token.h
@@ -277,6 +277,8 @@
kTextureDepthCube,
/// A 'texture_depth_cube_array'
kTextureDepthCubeArray,
+ /// A 'texture_external'
+ kTextureExternal,
/// A 'texture_multisampled_2d'
kTextureMultisampled2d,
/// A 'texture_1d'
diff --git a/test/BUILD.gn b/test/BUILD.gn
index 106056e..ce361dd 100644
--- a/test/BUILD.gn
+++ b/test/BUILD.gn
@@ -416,6 +416,7 @@
"../src/reader/wgsl/parser_impl_error_msg_test.cc",
"../src/reader/wgsl/parser_impl_error_resync_test.cc",
"../src/reader/wgsl/parser_impl_exclusive_or_expression_test.cc",
+ "../src/reader/wgsl/parser_impl_external_texture_type_test.cc",
"../src/reader/wgsl/parser_impl_for_stmt_test.cc",
"../src/reader/wgsl/parser_impl_function_decl_test.cc",
"../src/reader/wgsl/parser_impl_function_decoration_list_test.cc",