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>
This commit is contained in:
Brandon Jones 2021-04-22 22:47:03 +00:00 committed by Commit Bot service account
parent add325bb61
commit 145f865fb1
10 changed files with 125 additions and 14 deletions

View File

@ -639,6 +639,7 @@ if(${TINT_BUILD_TESTS})
reader/wgsl/parser_impl_continue_stmt_test.cc reader/wgsl/parser_impl_continue_stmt_test.cc
reader/wgsl/parser_impl_continuing_stmt_test.cc reader/wgsl/parser_impl_continuing_stmt_test.cc
reader/wgsl/parser_impl_depth_texture_type_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_else_stmt_test.cc
reader/wgsl/parser_impl_elseif_stmt_test.cc reader/wgsl/parser_impl_elseif_stmt_test.cc
reader/wgsl/parser_impl_equality_expression_test.cc reader/wgsl/parser_impl_equality_expression_test.cc

View File

@ -22,6 +22,7 @@
#include "src/program_builder.h" #include "src/program_builder.h"
#include "src/sem/access_control_type.h" #include "src/sem/access_control_type.h"
#include "src/sem/depth_texture_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/multisampled_texture_type.h"
#include "src/sem/sampled_texture_type.h" #include "src/sem/sampled_texture_type.h"
#include "src/sem/storage_texture_type.h" #include "src/sem/storage_texture_type.h"
@ -570,6 +571,22 @@ class StorageTextureBuilder : public Builder {
OpenType const channel_format_; 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. /// SamplerBuilder is a Matcher / Builder for sampler types of the given kind.
class SamplerBuilder : public Builder { class SamplerBuilder : public Builder {
public: public:
@ -759,6 +776,11 @@ class Impl : public IntrinsicTable {
dimensions, texel_format, channel_format); 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 /// @returns a Matcher / Builder that matches a sampler type
Builder* sampler(ast::SamplerKind kind) { Builder* sampler(ast::SamplerKind kind) {
return matcher_allocator_.Create<SamplerBuilder>(kind); return matcher_allocator_.Create<SamplerBuilder>(kind);
@ -1091,6 +1113,7 @@ Impl::Impl() {
auto* tex_depth_2d_array = depth_texture(Dim::k2dArray); auto* tex_depth_2d_array = depth_texture(Dim::k2dArray);
auto* tex_depth_cube = depth_texture(Dim::kCube); auto* tex_depth_cube = depth_texture(Dim::kCube);
auto* tex_depth_cube_array = depth_texture(Dim::kCubeArray); auto* tex_depth_cube_array = depth_texture(Dim::kCubeArray);
auto* tex_external = external_texture();
auto* tex_storage_1d_FT = auto* tex_storage_1d_FT =
storage_texture(Dim::k1d, OpenNumber::F, OpenType::T); storage_texture(Dim::k1d, OpenNumber::F, OpenType::T);
auto* tex_storage_2d_FT = auto* tex_storage_2d_FT =
@ -1159,6 +1182,7 @@ Impl::Impl() {
Register(I::kTextureDimensions, vec2_i32, {{t, tex_storage_2d_FT}, }); // NOLINT 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, vec2_i32, {{t, tex_storage_2d_array_FT}, }); // NOLINT
Register(I::kTextureDimensions, vec3_i32, {{t, tex_storage_3d_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_2d_array_T}, });
Register(I::kTextureNumLayers, i32, {{t, tex_cube_array_T}, }); Register(I::kTextureNumLayers, i32, {{t, tex_cube_array_T}, });
@ -1195,6 +1219,8 @@ Impl::Impl() {
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_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}, {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, 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}, }); // NOLINT
Register(I::kTextureSampleBias, vec4_f32, {{t, tex_2d_f32}, {s, sampler}, {coords, vec2_f32}, {bias, f32}, {offset, vec2_i32}, }); // 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 @@ Impl::Impl() {
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_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::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_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_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_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_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_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, 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}, {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, 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_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_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_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_storage_ro_3d_FT}, {coords, vec3_i32}, }); // NOLINT
Register(I::kTextureLoad, vec4_f32, {{t, tex_external}, {coords, vec2_i32} }); // NOLINT
// clang-format on // clang-format on

View File

@ -18,6 +18,7 @@
#include "src/program_builder.h" #include "src/program_builder.h"
#include "src/sem/access_control_type.h" #include "src/sem/access_control_type.h"
#include "src/sem/depth_texture_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/multisampled_texture_type.h"
#include "src/sem/sampled_texture_type.h" #include "src/sem/sampled_texture_type.h"
#include "src/sem/storage_texture_type.h" #include "src/sem/storage_texture_type.h"
@ -285,6 +286,20 @@ TEST_F(IntrinsicTableTest, MatchDepthTexture) {
Parameter{ty.i32(), Parameter::Usage::kLevel})); 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) { TEST_F(IntrinsicTableTest, MatchROStorageTexture) {
auto tex = ty.storage_texture(ast::TextureDimension::k2d, auto tex = ty.storage_texture(ast::TextureDimension::k2d,
ast::ImageFormat::kR16Float); ast::ImageFormat::kR16Float);
@ -431,7 +446,7 @@ TEST_F(IntrinsicTableTest, OverloadOrderByNumberOfParameters) {
ASSERT_EQ(result.diagnostics.str(), ASSERT_EQ(result.diagnostics.str(),
R"(error: no matching call to textureDimensions(bool, bool) 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<T>, level : i32) -> vec2<i32>
textureDimensions(texture : texture_2d_array<T>, level : i32) -> vec2<i32> textureDimensions(texture : texture_2d_array<T>, level : i32) -> vec2<i32>
textureDimensions(texture : texture_3d<T>, level : i32) -> vec3<i32> textureDimensions(texture : texture_3d<T>, level : i32) -> vec3<i32>
@ -457,6 +472,7 @@ TEST_F(IntrinsicTableTest, OverloadOrderByNumberOfParameters) {
textureDimensions(texture : texture_storage_2d<F>) -> vec2<i32> textureDimensions(texture : texture_storage_2d<F>) -> vec2<i32>
textureDimensions(texture : texture_storage_2d_array<F>) -> vec2<i32> textureDimensions(texture : texture_storage_2d_array<F>) -> vec2<i32>
textureDimensions(texture : texture_storage_3d<F>) -> vec3<i32> textureDimensions(texture : texture_storage_3d<F>) -> vec3<i32>
textureDimensions(texture : texture_external) -> vec2<i32>
)"); )");
} }
@ -468,7 +484,7 @@ TEST_F(IntrinsicTableTest, OverloadOrderByMatchingParameter) {
result.diagnostics.str(), result.diagnostics.str(),
R"(error: no matching call to textureDimensions(texture_depth_2d, bool) 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, level : i32) -> vec2<i32>
textureDimensions(texture : texture_depth_2d) -> vec2<i32> textureDimensions(texture : texture_depth_2d) -> vec2<i32>
textureDimensions(texture : texture_2d<T>, level : i32) -> vec2<i32> textureDimensions(texture : texture_2d<T>, level : i32) -> vec2<i32>
@ -494,6 +510,7 @@ TEST_F(IntrinsicTableTest, OverloadOrderByMatchingParameter) {
textureDimensions(texture : texture_storage_2d<F>) -> vec2<i32> textureDimensions(texture : texture_storage_2d<F>) -> vec2<i32>
textureDimensions(texture : texture_storage_2d_array<F>) -> vec2<i32> textureDimensions(texture : texture_storage_2d_array<F>) -> vec2<i32>
textureDimensions(texture : texture_storage_3d<F>) -> vec3<i32> textureDimensions(texture : texture_storage_3d<F>) -> vec3<i32>
textureDimensions(texture : texture_external) -> vec2<i32>
)"); )");
} }

View File

@ -650,6 +650,9 @@ 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_external") {
return {Token::Type::kTextureExternal, source, "texture_external"};
}
if (str == "texture_multisampled_2d") { if (str == "texture_multisampled_2d") {
return {Token::Type::kTextureMultisampled2d, source, return {Token::Type::kTextureMultisampled2d, source,
"texture_multisampled_2d"}; "texture_multisampled_2d"};

View File

@ -26,6 +26,7 @@
#include "src/reader/wgsl/lexer.h" #include "src/reader/wgsl/lexer.h"
#include "src/sem/access_control_type.h" #include "src/sem/access_control_type.h"
#include "src/sem/depth_texture_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/multisampled_texture_type.h"
#include "src/sem/sampled_texture_type.h" #include "src/sem/sampled_texture_type.h"
@ -516,6 +517,10 @@ Maybe<sem::Type*> ParserImpl::texture_sampler_types() {
if (type.matched) if (type.matched)
return type.value; return type.value;
type = external_texture_type();
if (type.matched)
return type.value;
auto dim = sampled_texture_type(); auto dim = sampled_texture_type();
if (dim.matched) { if (dim.matched) {
const char* use = "sampled texture type"; const char* use = "sampled texture type";
@ -600,6 +605,16 @@ Maybe<ast::TextureDimension> ParserImpl::sampled_texture_type() {
return Failure::kNoMatch; 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 // multisampled_texture_type
// : TEXTURE_MULTISAMPLED_2D // : TEXTURE_MULTISAMPLED_2D
Maybe<ast::TextureDimension> ParserImpl::multisampled_texture_type() { Maybe<ast::TextureDimension> ParserImpl::multisampled_texture_type() {

View File

@ -414,6 +414,9 @@ class ParserImpl {
/// 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.
Maybe<sem::Type*> depth_texture_type(); 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 /// Parses a `image_storage_type` grammar element
/// @param use a description of what was being parsed if an error was raised /// @param use a description of what was being parsed if an error was raised
/// @returns returns the image format or kNone if none matched. /// @returns returns the image format or kNone if none matched.

View File

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

View File

@ -269,6 +269,8 @@ 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::kTextureExternal:
return "texture_external";
case Token::Type::kTextureMultisampled2d: case Token::Type::kTextureMultisampled2d:
return "texture_multisampled_2d"; return "texture_multisampled_2d";
case Token::Type::kTextureSampled1d: case Token::Type::kTextureSampled1d:

View File

@ -277,6 +277,8 @@ class Token {
kTextureDepthCube, kTextureDepthCube,
/// A 'texture_depth_cube_array' /// A 'texture_depth_cube_array'
kTextureDepthCubeArray, kTextureDepthCubeArray,
/// A 'texture_external'
kTextureExternal,
/// A 'texture_multisampled_2d' /// A 'texture_multisampled_2d'
kTextureMultisampled2d, kTextureMultisampled2d,
/// A 'texture_1d' /// A 'texture_1d'

View File

@ -416,6 +416,7 @@ tint_unittests_source_set("tint_unittests_wgsl_reader_src") {
"../src/reader/wgsl/parser_impl_error_msg_test.cc", "../src/reader/wgsl/parser_impl_error_msg_test.cc",
"../src/reader/wgsl/parser_impl_error_resync_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_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_for_stmt_test.cc",
"../src/reader/wgsl/parser_impl_function_decl_test.cc", "../src/reader/wgsl/parser_impl_function_decl_test.cc",
"../src/reader/wgsl/parser_impl_function_decoration_list_test.cc", "../src/reader/wgsl/parser_impl_function_decoration_list_test.cc",