[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>
This commit is contained in:
Tomek Ponitka 2020-09-02 15:52:15 +00:00 committed by Commit Bot service account
parent 17b2b246c1
commit fd3ca9ee47
12 changed files with 363 additions and 1 deletions

View File

@ -909,6 +909,7 @@ source_set("tint_unittests_wgsl_reader_src") {
"src/reader/wgsl/parser_impl_postfix_expression_test.cc", "src/reader/wgsl/parser_impl_postfix_expression_test.cc",
"src/reader/wgsl/parser_impl_primary_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_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_sampler_type_test.cc",
"src/reader/wgsl/parser_impl_shift_expression_test.cc", "src/reader/wgsl/parser_impl_shift_expression_test.cc",
"src/reader/wgsl/parser_impl_statement_test.cc", "src/reader/wgsl/parser_impl_statement_test.cc",

View File

@ -440,6 +440,7 @@ if(${TINT_BUILD_WGSL_READER})
reader/wgsl/parser_impl_postfix_expression_test.cc reader/wgsl/parser_impl_postfix_expression_test.cc
reader/wgsl/parser_impl_primary_expression_test.cc reader/wgsl/parser_impl_primary_expression_test.cc
reader/wgsl/parser_impl_relational_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_sampler_type_test.cc
reader/wgsl/parser_impl_shift_expression_test.cc reader/wgsl/parser_impl_shift_expression_test.cc
reader/wgsl/parser_impl_statement_test.cc reader/wgsl/parser_impl_statement_test.cc

View File

@ -26,6 +26,9 @@ namespace type {
std::ostream& operator<<(std::ostream& out, TextureDimension dim) { std::ostream& operator<<(std::ostream& out, TextureDimension dim) {
switch (dim) { switch (dim) {
case TextureDimension::kNone:
out << "None";
break;
case TextureDimension::k1d: case TextureDimension::k1d:
out << "1d"; out << "1d";
break; break;

View File

@ -30,6 +30,8 @@ class StorageTextureType;
/// The dimensionality of the texture /// The dimensionality of the texture
enum class TextureDimension { enum class TextureDimension {
/// Invalid texture
kNone = -1,
/// 1 dimensional texture /// 1 dimensional texture
k1d, k1d,
/// 1 dimenstional array texture /// 1 dimenstional array texture

View File

@ -587,6 +587,32 @@ Token Lexer::check_keyword(const Source& source, const std::string& str) {
return {Token::Type::kTextureDepthCubeArray, source, return {Token::Type::kTextureDepthCubeArray, source,
"texture_depth_cube_array"}; "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") if (str == "true")
return {Token::Type::kTrue, source, "true"}; return {Token::Type::kTrue, source, "true"};
if (str == "type") if (str == "type")

View File

@ -470,6 +470,19 @@ INSTANTIATE_TEST_SUITE_P(
TokenData{"texture_depth_cube", Token::Type::kTextureDepthCube}, TokenData{"texture_depth_cube", Token::Type::kTextureDepthCube},
TokenData{"texture_depth_cube_array", TokenData{"texture_depth_cube_array",
Token::Type::kTextureDepthCubeArray}, 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{"true", Token::Type::kTrue},
TokenData{"type", Token::Type::kType}, TokenData{"type", Token::Type::kType},
TokenData{"u32", Token::Type::kU32}, TokenData{"u32", Token::Type::kU32},

View File

@ -51,6 +51,7 @@
#include "src/ast/type/i32_type.h" #include "src/ast/type/i32_type.h"
#include "src/ast/type/matrix_type.h" #include "src/ast/type/matrix_type.h"
#include "src/ast/type/pointer_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/sampler_type.h"
#include "src/ast/type/struct_type.h" #include "src/ast/type/struct_type.h"
#include "src/ast/type/u32_type.h" #include "src/ast/type/u32_type.h"
@ -580,7 +581,7 @@ std::unique_ptr<ast::Variable> ParserImpl::variable_decl() {
// texture_sampler_types // texture_sampler_types
// : sampler_type // : sampler_type
// | depth_texture_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: multisampled_texture_type LESS_THAN type_decl GREATER_THAN
// | TODO: storage_texture_type LESS_THAN image_storage_type GREATER_THAN // | TODO: storage_texture_type LESS_THAN image_storage_type GREATER_THAN
ast::type::Type* ParserImpl::texture_sampler_types() { ast::type::Type* ParserImpl::texture_sampler_types() {
@ -594,6 +595,32 @@ ast::type::Type* ParserImpl::texture_sampler_types() {
return type; 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; return nullptr;
} }
@ -615,6 +642,57 @@ ast::type::Type* ParserImpl::sampler_type() {
return nullptr; 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 // depth_texture_type
// : TEXTURE_DEPTH_2D // : TEXTURE_DEPTH_2D
// | TEXTURE_DEPTH_2D_ARRAY // | TEXTURE_DEPTH_2D_ARRAY

View File

@ -40,6 +40,7 @@
#include "src/ast/struct_decoration.h" #include "src/ast/struct_decoration.h"
#include "src/ast/struct_member.h" #include "src/ast/struct_member.h"
#include "src/ast/struct_member_decoration.h" #include "src/ast/struct_member_decoration.h"
#include "src/ast/type/texture_type.h"
#include "src/ast/type/type.h" #include "src/ast/type/type.h"
#include "src/ast/variable.h" #include "src/ast/variable.h"
#include "src/ast/variable_decoration.h" #include "src/ast/variable_decoration.h"
@ -186,6 +187,9 @@ class ParserImpl {
/// Parses a `sampler_type` grammar element /// Parses a `sampler_type` grammar element
/// @returns the parsed Type or nullptr if none matched. /// @returns the parsed Type or nullptr if none matched.
ast::type::Type* sampler_type(); 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 /// Parses a `depth_texture_type` grammar element
/// @returns the parsed Type or nullptr if none matched. /// @returns the parsed Type or nullptr if none matched.
ast::type::Type* depth_texture_type(); ast::type::Type* depth_texture_type();

View File

@ -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

View File

@ -39,6 +39,15 @@ TEST_F(ParserImplTest, TextureSamplerTypes_Sampler) {
EXPECT_FALSE(p->has_error()); 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) { TEST_F(ParserImplTest, TextureSamplerTypes_DepthTexture) {
auto* p = parser("texture_depth_2d"); auto* p = parser("texture_depth_2d");
auto* t = p->texture_sampler_types(); auto* t = p->texture_sampler_types();
@ -49,6 +58,67 @@ TEST_F(ParserImplTest, TextureSamplerTypes_DepthTexture) {
EXPECT_FALSE(p->has_error()); 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
} // namespace wgsl } // namespace wgsl
} // namespace reader } // namespace reader

View File

@ -219,6 +219,24 @@ std::string Token::TypeToName(Type type) {
return "texture_depth_cube"; return "texture_depth_cube";
case Token::Type::kTextureDepthCubeArray: case Token::Type::kTextureDepthCubeArray:
return "texture_depth_cube_array"; 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: case Token::Type::kTrue:
return "true"; return "true";
case Token::Type::kType: case Token::Type::kType:

View File

@ -230,6 +230,24 @@ class Token {
kTextureDepthCube, kTextureDepthCube,
/// A 'texture_depth_cube_array' /// A 'texture_depth_cube_array'
kTextureDepthCubeArray, 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' /// A 'true'
kTrue, kTrue,
/// A 'type' /// A 'type'
@ -503,6 +521,36 @@ class Token {
bool IsTextureDepthCubeArray() const { bool IsTextureDepthCubeArray() const {
return type_ == Type::kTextureDepthCubeArray; 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' /// @returns true if token is a 'true'
bool IsTrue() const { return type_ == Type::kTrue; } bool IsTrue() const { return type_ == Type::kTrue; }
/// @returns true if token is a 'type' /// @returns true if token is a 'type'