Implement texture_depth_multisampled_2d

Implemented for all readers and writers.

Cleaned up some verbose code in sem::Function and the Inspector in the
process.

Fixed: tint:1032
Change-Id: Ia6f2f59e6d2e511c89160b97be990e8b7c9828d9
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/59664
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: David Neto <dneto@google.com>
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Auto-Submit: Ben Clayton <bclayton@google.com>
This commit is contained in:
Ben Clayton
2021-07-26 22:19:48 +00:00
committed by Tint LUCI CQ
parent d12379a405
commit fd35aa8e47
85 changed files with 5024 additions and 2515 deletions

View File

@@ -5404,7 +5404,7 @@ bool FunctionEmitter::EmitImageAccess(const spvtools::opt::Instruction& inst) {
// dref gather vec4 ImageFetch vec4 TODO(dneto)
// Construct a 4-element vector with the result from the builtin in the
// first component.
if (texture_type->Is<DepthTexture>()) {
if (texture_type->IsAnyOf<DepthTexture, DepthMultisampledTexture>()) {
if (is_non_dref_sample || (opcode == SpvOpImageFetch)) {
value = create<ast::TypeConstructorExpression>(
Source{},

View File

@@ -2516,7 +2516,11 @@ const Pointer* ParserImpl::GetTypeForHandleVar(
// OpImage variable with an OpImage*Dref* instruction. In WGSL we must
// treat that as a depth texture.
if (image_type->depth() || usage.IsDepthTexture()) {
ast_store_type = ty_.DepthTexture(dim);
if (image_type->is_multisampled()) {
ast_store_type = ty_.DepthMultisampledTexture(dim);
} else {
ast_store_type = ty_.DepthTexture(dim);
}
} else if (image_type->is_multisampled()) {
if (dim != ast::TextureDimension::k2d) {
Fail() << "WGSL multisampled textures must be 2d and non-arrayed: "

View File

@@ -3973,6 +3973,52 @@ INSTANTIATE_TEST_SUITE_P(ImageFetch_Depth,
}
})"}}));
INSTANTIATE_TEST_SUITE_P(
ImageFetch_DepthMultisampled,
// In SPIR-V OpImageFetch always yields a vector of 4
// elements, even for depth images. But in WGSL,
// textureLoad on a depth image yields f32.
// crbug.com/tint/439
SpvParserHandleTest_ImageAccessTest,
::testing::ValuesIn(std::vector<ImageAccessCase>{
// ImageFetch on multisampled depth image.
{"%float 2D 1 0 1 1 Unknown",
"%99 = OpImageFetch %v4float %im %vi12 Sample %i1",
R"(Variable{
Decorations{
GroupDecoration{2}
BindingDecoration{1}
}
x_20
none
undefined
__depth_multisampled_texture_2d
})",
R"(VariableDeclStatement{
VariableConst{
x_99
none
undefined
__vec_4__f32
{
TypeConstructor[not set]{
__vec_4__f32
Call[not set]{
Identifier[not set]{textureLoad}
(
Identifier[not set]{x_20}
Identifier[not set]{vi12}
Identifier[not set]{i1}
)
}
ScalarConstructor[not set]{0.000000}
ScalarConstructor[not set]{0.000000}
ScalarConstructor[not set]{0.000000}
}
}
}
})"}}));
INSTANTIATE_TEST_SUITE_P(
ImageFetch_Multisampled,
SpvParserHandleTest_ImageAccessTest,

View File

@@ -36,6 +36,7 @@ TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::Array);
TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::Sampler);
TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::Texture);
TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::DepthTexture);
TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::DepthMultisampledTexture);
TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::MultisampledTexture);
TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::SampledTexture);
TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::StorageTexture);
@@ -206,6 +207,15 @@ ast::Type* DepthTexture::Build(ProgramBuilder& b) const {
return b.ty.depth_texture(dims);
}
DepthMultisampledTexture::DepthMultisampledTexture(ast::TextureDimension d)
: Base(d) {}
DepthMultisampledTexture::DepthMultisampledTexture(
const DepthMultisampledTexture&) = default;
ast::Type* DepthMultisampledTexture::Build(ProgramBuilder& b) const {
return b.ty.depth_multisampled_texture(dims);
}
MultisampledTexture::MultisampledTexture(ast::TextureDimension d, const Type* t)
: Base(d), type(t) {}
MultisampledTexture::MultisampledTexture(const MultisampledTexture&) = default;
@@ -288,6 +298,10 @@ struct TypeManager::State {
/// Map of ast::TextureDimension to returned DepthTexture instance
std::unordered_map<ast::TextureDimension, const spirv::DepthTexture*>
depth_textures_;
/// Map of ast::TextureDimension to returned DepthMultisampledTexture instance
std::unordered_map<ast::TextureDimension,
const spirv::DepthMultisampledTexture*>
depth_multisampled_textures_;
/// Map of MultisampledTexture to the returned MultisampledTexture type
/// instance
std::unordered_map<spirv::MultisampledTexture,
@@ -487,6 +501,13 @@ const spirv::DepthTexture* TypeManager::DepthTexture(
});
}
const spirv::DepthMultisampledTexture* TypeManager::DepthMultisampledTexture(
ast::TextureDimension dims) {
return utils::GetOrCreate(state->depth_multisampled_textures_, dims, [&] {
return state->allocator_.Create<spirv::DepthMultisampledTexture>(dims);
});
}
const spirv::MultisampledTexture* TypeManager::MultisampledTexture(
ast::TextureDimension dims,
const Type* ty) {
@@ -586,6 +607,12 @@ std::string DepthTexture::String() const {
return ss.str();
}
std::string DepthMultisampledTexture::String() const {
std::stringstream ss;
ss << "depth_multisampled_" << dims;
return ss.str();
}
std::string MultisampledTexture::String() const {
std::stringstream ss;
ss << "texture_multisampled_" << dims << "<" << type << ">";

View File

@@ -344,6 +344,27 @@ struct DepthTexture : public Castable<DepthTexture, Texture> {
#endif // NDEBUG
};
/// `texture_depth_multisampled_D` type
struct DepthMultisampledTexture
: public Castable<DepthMultisampledTexture, Texture> {
/// Constructor
/// @param d the texture dimensions
explicit DepthMultisampledTexture(ast::TextureDimension d);
/// Copy constructor
/// @param other the other type to copy
DepthMultisampledTexture(const DepthMultisampledTexture& other);
/// @param b the ProgramBuilder used to construct the AST types
/// @returns the constructed ast::Type node for the given type
ast::Type* Build(ProgramBuilder& b) const override;
#ifndef NDEBUG
/// @returns a string representation of the type, for debug purposes only
std::string String() const override;
#endif // NDEBUG
};
/// `texture_multisampled_D<T>` type
struct MultisampledTexture : public Castable<MultisampledTexture, Texture> {
/// Constructor
@@ -549,6 +570,11 @@ class TypeManager {
/// return the same pointer.
const spirv::DepthTexture* DepthTexture(ast::TextureDimension d);
/// @param d the texture dimensions
/// @return a DepthMultisampledTexture type. Repeated calls with the same
/// arguments will return the same pointer.
const spirv::DepthMultisampledTexture* DepthMultisampledTexture(
ast::TextureDimension d);
/// @param d the texture dimensions
/// @param t the multisampled texture type
/// @return a MultisampledTexture type. Repeated calls with the same arguments
/// will return the same pointer.

View File

@@ -931,6 +931,10 @@ Token Lexer::check_keyword(const Source& source, const std::string& str) {
return {Token::Type::kTextureDepthCubeArray, source,
"texture_depth_cube_array"};
}
if (str == "texture_depth_multisampled_2d") {
return {Token::Type::kTextureDepthMultisampled2d, source,
"texture_depth_multisampled_2d"};
}
if (str == "texture_external") {
return {Token::Type::kTextureExternal, source, "texture_external"};
}

View File

@@ -543,6 +543,8 @@ INSTANTIATE_TEST_SUITE_P(
TokenData{"texture_depth_cube", Token::Type::kTextureDepthCube},
TokenData{"texture_depth_cube_array",
Token::Type::kTextureDepthCubeArray},
TokenData{"texture_depth_multisampled_2d",
Token::Type::kTextureDepthMultisampled2d},
TokenData{"texture_multisampled_2d",
Token::Type::kTextureMultisampled2d},
TokenData{"texture_storage_1d", Token::Type::kTextureStorage1d},

View File

@@ -724,21 +724,25 @@ Maybe<ast::TextureDimension> ParserImpl::storage_texture_type() {
// | TEXTURE_DEPTH_2D_ARRAY
// | TEXTURE_DEPTH_CUBE
// | TEXTURE_DEPTH_CUBE_ARRAY
// | TEXTURE_DEPTH_MULTISAMPLED_2D
Maybe<ast::Type*> ParserImpl::depth_texture_type() {
Source source;
if (match(Token::Type::kTextureDepth2d, &source))
if (match(Token::Type::kTextureDepth2d, &source)) {
return builder_.ty.depth_texture(source, ast::TextureDimension::k2d);
if (match(Token::Type::kTextureDepth2dArray, &source))
}
if (match(Token::Type::kTextureDepth2dArray, &source)) {
return builder_.ty.depth_texture(source, ast::TextureDimension::k2dArray);
if (match(Token::Type::kTextureDepthCube, &source))
}
if (match(Token::Type::kTextureDepthCube, &source)) {
return builder_.ty.depth_texture(source, ast::TextureDimension::kCube);
if (match(Token::Type::kTextureDepthCubeArray, &source))
}
if (match(Token::Type::kTextureDepthCubeArray, &source)) {
return builder_.ty.depth_texture(source, ast::TextureDimension::kCubeArray);
}
if (match(Token::Type::kTextureDepthMultisampled2d, &source)) {
return builder_.ty.depth_multisampled_texture(source,
ast::TextureDimension::k2d);
}
return Failure::kNoMatch;
}

View File

@@ -80,6 +80,19 @@ TEST_F(ParserImplTest, DepthTextureType_CubeArray) {
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 25u}}));
}
TEST_F(ParserImplTest, DepthTextureType_Multisampled2d) {
auto p = parser("texture_depth_multisampled_2d");
auto t = p->depth_texture_type();
EXPECT_TRUE(t.matched);
EXPECT_FALSE(t.errored);
ASSERT_NE(t.value, nullptr);
ASSERT_TRUE(t->Is<ast::Texture>());
ASSERT_TRUE(t->Is<ast::DepthMultisampledTexture>());
EXPECT_EQ(t->As<ast::Texture>()->dim(), ast::TextureDimension::k2d);
EXPECT_FALSE(p->has_error());
EXPECT_EQ(t.value->source().range, (Source::Range{{1u, 1u}, {1u, 30u}}));
}
} // namespace
} // namespace wgsl
} // namespace reader

View File

@@ -269,6 +269,8 @@ std::string Token::TypeToName(Type type) {
return "texture_depth_cube";
case Token::Type::kTextureDepthCubeArray:
return "texture_depth_cube_array";
case Token::Type::kTextureDepthMultisampled2d:
return "texture_depth_multisampled_2d";
case Token::Type::kTextureExternal:
return "texture_external";
case Token::Type::kTextureMultisampled2d:

View File

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