[wgsl-reader] Parsing sampled texture type
Bug: tint:147
Change-Id: I21c864dd63c2003797c78758358ab4134cd8ff31
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/28002
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/BUILD.gn b/BUILD.gn
index 6add641..7462bef 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -909,6 +909,7 @@
"src/reader/wgsl/parser_impl_postfix_expression_test.cc",
"src/reader/wgsl/parser_impl_primary_expression_test.cc",
"src/reader/wgsl/parser_impl_relational_expression_test.cc",
+ "src/reader/wgsl/parser_impl_sampled_texture_type_test.cc",
"src/reader/wgsl/parser_impl_sampler_type_test.cc",
"src/reader/wgsl/parser_impl_shift_expression_test.cc",
"src/reader/wgsl/parser_impl_statement_test.cc",
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c735b0d..3d82ef6 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -440,6 +440,7 @@
reader/wgsl/parser_impl_postfix_expression_test.cc
reader/wgsl/parser_impl_primary_expression_test.cc
reader/wgsl/parser_impl_relational_expression_test.cc
+ reader/wgsl/parser_impl_sampled_texture_type_test.cc
reader/wgsl/parser_impl_sampler_type_test.cc
reader/wgsl/parser_impl_shift_expression_test.cc
reader/wgsl/parser_impl_statement_test.cc
diff --git a/src/ast/type/texture_type.cc b/src/ast/type/texture_type.cc
index a5a4e1e..690a514 100644
--- a/src/ast/type/texture_type.cc
+++ b/src/ast/type/texture_type.cc
@@ -26,6 +26,9 @@
std::ostream& operator<<(std::ostream& out, TextureDimension dim) {
switch (dim) {
+ case TextureDimension::kNone:
+ out << "None";
+ break;
case TextureDimension::k1d:
out << "1d";
break;
diff --git a/src/ast/type/texture_type.h b/src/ast/type/texture_type.h
index 37ca7e1..e0f44fa 100644
--- a/src/ast/type/texture_type.h
+++ b/src/ast/type/texture_type.h
@@ -30,6 +30,8 @@
/// The dimensionality of the texture
enum class TextureDimension {
+ /// Invalid texture
+ kNone = -1,
/// 1 dimensional texture
k1d,
/// 1 dimenstional array texture
diff --git a/src/reader/wgsl/lexer.cc b/src/reader/wgsl/lexer.cc
index c2126a8..eacd7ab 100644
--- a/src/reader/wgsl/lexer.cc
+++ b/src/reader/wgsl/lexer.cc
@@ -587,6 +587,32 @@
return {Token::Type::kTextureDepthCubeArray, source,
"texture_depth_cube_array"};
}
+ if (str == "texture_sampled_1d")
+ return {Token::Type::kTextureSampled1d, source, "texture_sampled_1d"};
+ if (str == "texture_sampled_1d_array") {
+ return {Token::Type::kTextureSampled1dArray, source,
+ "texture_sampled_1d_array"};
+ }
+ if (str == "texture_sampled_2d")
+ return {Token::Type::kTextureSampled2d, source, "texture_sampled_2d"};
+ if (str == "texture_sampled_2d_array") {
+ return {Token::Type::kTextureSampled2dArray, source,
+ "texture_sampled_2d_array"};
+ }
+ if (str == "texture_sampled_2d_ms")
+ return {Token::Type::kTextureSampled2dMs, source, "texture_sampled_2d_ms"};
+ if (str == "texture_sampled_2d_ms_array") {
+ return {Token::Type::kTextureSampled2dMsArray, source,
+ "texture_sampled_2d_ms_array"};
+ }
+ if (str == "texture_sampled_3d")
+ return {Token::Type::kTextureSampled3d, source, "texture_sampled_3d"};
+ if (str == "texture_sampled_cube")
+ return {Token::Type::kTextureSampledCube, source, "texture_sampled_cube"};
+ if (str == "texture_sampled_cube_array") {
+ return {Token::Type::kTextureSampledCubeArray, source,
+ "texture_sampled_cube_array"};
+ }
if (str == "true")
return {Token::Type::kTrue, source, "true"};
if (str == "type")
diff --git a/src/reader/wgsl/lexer_test.cc b/src/reader/wgsl/lexer_test.cc
index a2169cf..0dc5bfa 100644
--- a/src/reader/wgsl/lexer_test.cc
+++ b/src/reader/wgsl/lexer_test.cc
@@ -470,6 +470,19 @@
TokenData{"texture_depth_cube", Token::Type::kTextureDepthCube},
TokenData{"texture_depth_cube_array",
Token::Type::kTextureDepthCubeArray},
+ TokenData{"texture_sampled_1d", Token::Type::kTextureSampled1d},
+ TokenData{"texture_sampled_1d_array",
+ Token::Type::kTextureSampled1dArray},
+ TokenData{"texture_sampled_2d", Token::Type::kTextureSampled2d},
+ TokenData{"texture_sampled_2d_array",
+ Token::Type::kTextureSampled2dArray},
+ TokenData{"texture_sampled_2d_ms", Token::Type::kTextureSampled2dMs},
+ TokenData{"texture_sampled_2d_ms_array",
+ Token::Type::kTextureSampled2dMsArray},
+ TokenData{"texture_sampled_3d", Token::Type::kTextureSampled3d},
+ TokenData{"texture_sampled_cube", Token::Type::kTextureSampledCube},
+ TokenData{"texture_sampled_cube_array",
+ Token::Type::kTextureSampledCubeArray},
TokenData{"true", Token::Type::kTrue},
TokenData{"type", Token::Type::kType},
TokenData{"u32", Token::Type::kU32},
diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc
index e7a748b..4316930 100644
--- a/src/reader/wgsl/parser_impl.cc
+++ b/src/reader/wgsl/parser_impl.cc
@@ -51,6 +51,7 @@
#include "src/ast/type/i32_type.h"
#include "src/ast/type/matrix_type.h"
#include "src/ast/type/pointer_type.h"
+#include "src/ast/type/sampled_texture_type.h"
#include "src/ast/type/sampler_type.h"
#include "src/ast/type/struct_type.h"
#include "src/ast/type/u32_type.h"
@@ -580,7 +581,7 @@
// texture_sampler_types
// : sampler_type
// | depth_texture_type
-// | TODO: sampled_texture_type LESS_THAN type_decl GREATER_THAN
+// | sampled_texture_type LESS_THAN type_decl GREATER_THAN
// | TODO: multisampled_texture_type LESS_THAN type_decl GREATER_THAN
// | TODO: storage_texture_type LESS_THAN image_storage_type GREATER_THAN
ast::type::Type* ParserImpl::texture_sampler_types() {
@@ -594,6 +595,32 @@
return type;
}
+ auto dim = sampled_texture_type();
+ if (dim != ast::type::TextureDimension::kNone) {
+ auto t = next();
+ if (!t.IsLessThan()) {
+ set_error(peek(), "missing '<' for sampled texture type");
+ return nullptr;
+ }
+
+ auto* subtype = type_decl();
+ if (has_error())
+ return nullptr;
+ if (subtype == nullptr) {
+ set_error(peek(), "invalid subtype for sampled texture type");
+ return nullptr;
+ }
+
+ t = next();
+ if (!t.IsGreaterThan()) {
+ set_error(peek(), "missing '>' for sampled texture type");
+ return nullptr;
+ }
+
+ return ctx_.type_mgr().Get(
+ std::make_unique<ast::type::SampledTextureType>(dim, subtype));
+ }
+
return nullptr;
}
@@ -615,6 +642,57 @@
return nullptr;
}
+// sampled_texture_type
+// : TEXTURE_SAMPLED_1D
+// | TEXTURE_SAMPLED_1D_ARRAY
+// | TEXTURE_SAMPLED_2D
+// | TEXTURE_SAMPLED_2D_ARRAY
+// | TEXTURE_SAMPLED_2D_MS
+// | TEXTURE_SAMPLED_2D_MS_ARRAY
+// | TEXTURE_SAMPLED_3D
+// | TEXTURE_SAMPLED_CUBE
+// | TEXTURE_SAMPLED_CUBE_ARRAY
+ast::type::TextureDimension ParserImpl::sampled_texture_type() {
+ auto t = peek();
+ if (t.IsTextureSampled1d()) {
+ next(); // Consume the peek
+ return ast::type::TextureDimension::k1d;
+ }
+ if (t.IsTextureSampled1dArray()) {
+ next(); // Consume the peek
+ return ast::type::TextureDimension::k1dArray;
+ }
+ if (t.IsTextureSampled2d()) {
+ next(); // Consume the peek
+ return ast::type::TextureDimension::k2d;
+ }
+ if (t.IsTextureSampled2dArray()) {
+ next(); // Consume the peek
+ return ast::type::TextureDimension::k2dArray;
+ }
+ if (t.IsTextureSampled2dMs()) {
+ next(); // Consume the peek
+ return ast::type::TextureDimension::k2dMs;
+ }
+ if (t.IsTextureSampled2dMsArray()) {
+ next(); // Consume the peek
+ return ast::type::TextureDimension::k2dMsArray;
+ }
+ if (t.IsTextureSampled3d()) {
+ next(); // Consume the peek
+ return ast::type::TextureDimension::k3d;
+ }
+ if (t.IsTextureSampledCube()) {
+ next(); // Consume the peek
+ return ast::type::TextureDimension::kCube;
+ }
+ if (t.IsTextureSampledCubeArray()) {
+ next(); // Consume the peek
+ return ast::type::TextureDimension::kCubeArray;
+ }
+ return ast::type::TextureDimension::kNone;
+}
+
// depth_texture_type
// : TEXTURE_DEPTH_2D
// | TEXTURE_DEPTH_2D_ARRAY
diff --git a/src/reader/wgsl/parser_impl.h b/src/reader/wgsl/parser_impl.h
index d492438..3f3073f 100644
--- a/src/reader/wgsl/parser_impl.h
+++ b/src/reader/wgsl/parser_impl.h
@@ -40,6 +40,7 @@
#include "src/ast/struct_decoration.h"
#include "src/ast/struct_member.h"
#include "src/ast/struct_member_decoration.h"
+#include "src/ast/type/texture_type.h"
#include "src/ast/type/type.h"
#include "src/ast/variable.h"
#include "src/ast/variable_decoration.h"
@@ -186,6 +187,9 @@
/// Parses a `sampler_type` grammar element
/// @returns the parsed Type or nullptr if none matched.
ast::type::Type* sampler_type();
+ /// Parses a `sampled_texture_type` grammar element
+ /// @returns returns the sample texture dimension or kNone if none matched.
+ ast::type::TextureDimension sampled_texture_type();
/// Parses a `depth_texture_type` grammar element
/// @returns the parsed Type or nullptr if none matched.
ast::type::Type* depth_texture_type();
diff --git a/src/reader/wgsl/parser_impl_sampled_texture_type_test.cc b/src/reader/wgsl/parser_impl_sampled_texture_type_test.cc
new file mode 100644
index 0000000..da9a461
--- /dev/null
+++ b/src/reader/wgsl/parser_impl_sampled_texture_type_test.cc
@@ -0,0 +1,98 @@
+// Copyright 2020 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 "gtest/gtest.h"
+#include "src/ast/type/texture_type.h"
+#include "src/reader/wgsl/parser_impl.h"
+#include "src/reader/wgsl/parser_impl_test_helper.h"
+
+namespace tint {
+namespace reader {
+namespace wgsl {
+namespace {
+
+TEST_F(ParserImplTest, SampledTextureType_Invalid) {
+ auto* p = parser("1234");
+ auto t = p->sampled_texture_type();
+ EXPECT_EQ(t, ast::type::TextureDimension::kNone);
+ EXPECT_FALSE(p->has_error());
+}
+
+TEST_F(ParserImplTest, SampledTextureType_1d) {
+ auto* p = parser("texture_sampled_1d");
+ auto t = p->sampled_texture_type();
+ EXPECT_EQ(t, ast::type::TextureDimension::k1d);
+ EXPECT_FALSE(p->has_error());
+}
+
+TEST_F(ParserImplTest, SampledTextureType_1dArray) {
+ auto* p = parser("texture_sampled_1d_array");
+ auto t = p->sampled_texture_type();
+ EXPECT_EQ(t, ast::type::TextureDimension::k1dArray);
+ EXPECT_FALSE(p->has_error());
+}
+
+TEST_F(ParserImplTest, SampledTextureType_2d) {
+ auto* p = parser("texture_sampled_2d");
+ auto t = p->sampled_texture_type();
+ EXPECT_EQ(t, ast::type::TextureDimension::k2d);
+ EXPECT_FALSE(p->has_error());
+}
+
+TEST_F(ParserImplTest, SampledTextureType_2dArray) {
+ auto* p = parser("texture_sampled_2d_array");
+ auto t = p->sampled_texture_type();
+ EXPECT_EQ(t, ast::type::TextureDimension::k2dArray);
+ EXPECT_FALSE(p->has_error());
+}
+
+TEST_F(ParserImplTest, SampledTextureType_2dMs) {
+ auto* p = parser("texture_sampled_2d_ms");
+ auto t = p->sampled_texture_type();
+ EXPECT_EQ(t, ast::type::TextureDimension::k2dMs);
+ EXPECT_FALSE(p->has_error());
+}
+
+TEST_F(ParserImplTest, SampledTextureType_2dMsArray) {
+ auto* p = parser("texture_sampled_2d_ms_array");
+ auto t = p->sampled_texture_type();
+ EXPECT_EQ(t, ast::type::TextureDimension::k2dMsArray);
+ EXPECT_FALSE(p->has_error());
+}
+
+TEST_F(ParserImplTest, SampledTextureType_3d) {
+ auto* p = parser("texture_sampled_3d");
+ auto t = p->sampled_texture_type();
+ EXPECT_EQ(t, ast::type::TextureDimension::k3d);
+ EXPECT_FALSE(p->has_error());
+}
+
+TEST_F(ParserImplTest, SampledTextureType_Cube) {
+ auto* p = parser("texture_sampled_cube");
+ auto t = p->sampled_texture_type();
+ EXPECT_EQ(t, ast::type::TextureDimension::kCube);
+ EXPECT_FALSE(p->has_error());
+}
+
+TEST_F(ParserImplTest, SampledTextureType_kCubeArray) {
+ auto* p = parser("texture_sampled_cube_array");
+ auto t = p->sampled_texture_type();
+ EXPECT_EQ(t, ast::type::TextureDimension::kCubeArray);
+ EXPECT_FALSE(p->has_error());
+}
+
+} // namespace
+} // namespace wgsl
+} // namespace reader
+} // namespace tint
diff --git a/src/reader/wgsl/parser_impl_texture_sampler_types_test.cc b/src/reader/wgsl/parser_impl_texture_sampler_types_test.cc
index a1580e6..262dca9 100644
--- a/src/reader/wgsl/parser_impl_texture_sampler_types_test.cc
+++ b/src/reader/wgsl/parser_impl_texture_sampler_types_test.cc
@@ -39,6 +39,15 @@
EXPECT_FALSE(p->has_error());
}
+TEST_F(ParserImplTest, TextureSamplerTypes_SamplerComparison) {
+ auto* p = parser("sampler_comparison");
+ auto* t = p->texture_sampler_types();
+ ASSERT_NE(t, nullptr);
+ ASSERT_TRUE(t->IsSampler());
+ ASSERT_TRUE(t->AsSampler()->IsComparison());
+ EXPECT_FALSE(p->has_error());
+}
+
TEST_F(ParserImplTest, TextureSamplerTypes_DepthTexture) {
auto* p = parser("texture_depth_2d");
auto* t = p->texture_sampler_types();
@@ -49,6 +58,67 @@
EXPECT_FALSE(p->has_error());
}
+TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_F32) {
+ auto* p = parser("texture_sampled_1d<f32>");
+ auto* t = p->texture_sampler_types();
+ ASSERT_NE(t, nullptr);
+ ASSERT_TRUE(t->IsTexture());
+ ASSERT_TRUE(t->AsTexture()->IsSampled());
+ ASSERT_TRUE(t->AsTexture()->AsSampled()->type()->IsF32());
+ EXPECT_EQ(t->AsTexture()->dim(), ast::type::TextureDimension::k1d);
+ EXPECT_FALSE(p->has_error());
+}
+
+TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_I32) {
+ auto* p = parser("texture_sampled_2d<i32>");
+ auto* t = p->texture_sampler_types();
+ ASSERT_NE(t, nullptr);
+ ASSERT_TRUE(t->IsTexture());
+ ASSERT_TRUE(t->AsTexture()->IsSampled());
+ ASSERT_TRUE(t->AsTexture()->AsSampled()->type()->IsI32());
+ EXPECT_EQ(t->AsTexture()->dim(), ast::type::TextureDimension::k2d);
+ EXPECT_FALSE(p->has_error());
+}
+
+TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_U32) {
+ auto* p = parser("texture_sampled_3d<u32>");
+ auto* t = p->texture_sampler_types();
+ ASSERT_NE(t, nullptr);
+ ASSERT_TRUE(t->IsTexture());
+ ASSERT_TRUE(t->AsTexture()->IsSampled());
+ ASSERT_TRUE(t->AsTexture()->AsSampled()->type()->IsU32());
+ EXPECT_EQ(t->AsTexture()->dim(), ast::type::TextureDimension::k3d);
+ EXPECT_FALSE(p->has_error());
+}
+
+TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_Invalid) {
+ auto* p = parser("texture_sampled_1d<abc>");
+ auto* t = p->texture_sampler_types();
+ EXPECT_EQ(t, nullptr);
+ EXPECT_EQ(p->error(), "1:20: unknown type alias 'abc'");
+}
+
+TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_MissingType) {
+ auto* p = parser("texture_sampled_1d<>");
+ auto* t = p->texture_sampler_types();
+ EXPECT_EQ(t, nullptr);
+ EXPECT_EQ(p->error(), "1:20: invalid subtype for sampled texture type");
+}
+
+TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_MissingLessThan) {
+ auto* p = parser("texture_sampled_1d");
+ auto* t = p->texture_sampler_types();
+ EXPECT_EQ(t, nullptr);
+ EXPECT_EQ(p->error(), "1:19: missing '<' for sampled texture type");
+}
+
+TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_MissingGreaterThan) {
+ auto* p = parser("texture_sampled_1d<u32");
+ auto* t = p->texture_sampler_types();
+ EXPECT_EQ(t, nullptr);
+ EXPECT_EQ(p->error(), "1:23: missing '>' for sampled texture type");
+}
+
} // namespace
} // namespace wgsl
} // namespace reader
diff --git a/src/reader/wgsl/token.cc b/src/reader/wgsl/token.cc
index 9ca01c9..be6f752 100644
--- a/src/reader/wgsl/token.cc
+++ b/src/reader/wgsl/token.cc
@@ -219,6 +219,24 @@
return "texture_depth_cube";
case Token::Type::kTextureDepthCubeArray:
return "texture_depth_cube_array";
+ case Token::Type::kTextureSampled1d:
+ return "texture_sampled_1d";
+ case Token::Type::kTextureSampled1dArray:
+ return "texture_sampled_1d_array";
+ case Token::Type::kTextureSampled2d:
+ return "texture_sampled_2d";
+ case Token::Type::kTextureSampled2dArray:
+ return "texture_sampled_2d_array";
+ case Token::Type::kTextureSampled2dMs:
+ return "texture_sampled_2d_ms";
+ case Token::Type::kTextureSampled2dMsArray:
+ return "texture_sampled_2d_ms_array";
+ case Token::Type::kTextureSampled3d:
+ return "texture_sampled_3d";
+ case Token::Type::kTextureSampledCube:
+ return "texture_sampled_cube";
+ case Token::Type::kTextureSampledCubeArray:
+ return "texture_sampled_cube_array";
case Token::Type::kTrue:
return "true";
case Token::Type::kType:
diff --git a/src/reader/wgsl/token.h b/src/reader/wgsl/token.h
index 3740b79..1b8d5f7 100644
--- a/src/reader/wgsl/token.h
+++ b/src/reader/wgsl/token.h
@@ -230,6 +230,24 @@
kTextureDepthCube,
/// A 'texture_depth_cube_array'
kTextureDepthCubeArray,
+ /// A 'texture_sampled_1d'
+ kTextureSampled1d,
+ /// A 'texture_sampled_1d_array'
+ kTextureSampled1dArray,
+ /// A 'texture_sampled_2d'
+ kTextureSampled2d,
+ /// A 'texture_sampled_2d_array'
+ kTextureSampled2dArray,
+ /// A 'texture_sampled_2d_ms'
+ kTextureSampled2dMs,
+ /// A 'texture_sampled_2d_ms_array'
+ kTextureSampled2dMsArray,
+ /// A 'texture_sampled_3d'
+ kTextureSampled3d,
+ /// A 'texture_sampled_cube'
+ kTextureSampledCube,
+ /// A 'texture_sampled_cube_array'
+ kTextureSampledCubeArray,
/// A 'true'
kTrue,
/// A 'type'
@@ -503,6 +521,36 @@
bool IsTextureDepthCubeArray() const {
return type_ == Type::kTextureDepthCubeArray;
}
+ /// @returns true if token is a 'texture_sampled_1d'
+ bool IsTextureSampled1d() const { return type_ == Type::kTextureSampled1d; }
+ /// @returns true if token is a 'texture_sampled_1d_array'
+ bool IsTextureSampled1dArray() const {
+ return type_ == Type::kTextureSampled1dArray;
+ }
+ /// @returns true if token is a 'texture_sampled_2d'
+ bool IsTextureSampled2d() const { return type_ == Type::kTextureSampled2d; }
+ /// @returns true if token is a 'texture_sampled_2d_array'
+ bool IsTextureSampled2dArray() const {
+ return type_ == Type::kTextureSampled2dArray;
+ }
+ /// @returns true if token is a 'texture_sampled_2d_ms'
+ bool IsTextureSampled2dMs() const {
+ return type_ == Type::kTextureSampled2dMs;
+ }
+ /// @returns true if token is a 'texture_sampled_2d_ms_array'
+ bool IsTextureSampled2dMsArray() const {
+ return type_ == Type::kTextureSampled2dMsArray;
+ }
+ /// @returns true if token is a 'texture_sampled_3d'
+ bool IsTextureSampled3d() const { return type_ == Type::kTextureSampled3d; }
+ /// @returns true if token is a 'texture_sampled_cube'
+ bool IsTextureSampledCube() const {
+ return type_ == Type::kTextureSampledCube;
+ }
+ /// @returns true if token is a 'texture_sampled_cube_array'
+ bool IsTextureSampledCubeArray() const {
+ return type_ == Type::kTextureSampledCubeArray;
+ }
/// @returns true if token is a 'true'
bool IsTrue() const { return type_ == Type::kTrue; }
/// @returns true if token is a 'type'