[msl-writer] Emit texture types

This CL adds texture and sampler type emission to the MSL backend.

Bug: tint:145
Change-Id: Iaab4d32b7fc6fedc1ffba16658f7800d6a502853
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/32320
Reviewed-by: David Neto <dneto@google.com>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
dan sinclair 2020-11-11 00:58:19 +00:00 committed by Commit Bot service account
parent dbcc1e0e80
commit f7e152a3ab
3 changed files with 258 additions and 24 deletions

View File

@ -108,38 +108,38 @@ decorated with `NonWritable` or each member of the struct can be decorated with
## Sampler Types
| WGSL | SPIR-V | MSL | HLSL |
|------|--------|-----|------|
| sampler | OpTypeSampler | | SamplerState |
| sampler_comparison | OpTypeSampler | | SamplerComparisonState |
| sampler | OpTypeSampler | sampler | SamplerState |
| sampler_comparison | OpTypeSampler | sampler | SamplerComparisonState |
## Texture Types
| WGSL | SPIR-V | MSL | HLSL |
|------|--------|-----|------|
| texture_1d | OpTypeImage | | Texture1D |
| texture_1d_array | OpTypeImage | | Texture1DArray |
| texture_2d | OpTypeImage | | Texture2D |
| texture_2d_array | OpTypeImage | | Texture2DArray |
| texture_3d | OpTypeImage | | Texture3D |
| texture_cube | OpTypeImage | | TextureCube |
| texture_cube_array | OpTypeImage | | TextureCubeArray |
| texture_1d&lt;type&gt; | OpTypeImage | texture1d&lt;type, access::sample&gt; | Texture1D |
| texture_1d_array&lt;type&gt; | OpTypeImage | texture1d_array&lt;type, access::sample&gt; | Texture1DArray |
| texture_2d&lt;type&gt; | OpTypeImage | texture2d&lt;type, access::sample&gt; | Texture2D |
| texture_2d_array&lt;type&gt; | OpTypeImage | texture2d_array&lt;type, access::sample&gt; | Texture2DArray |
| texture_3d&lt;type&gt; | OpTypeImage | texture3d&lt;type, access::sample&gt; | Texture3D |
| texture_cube&lt;type&gt; | OpTypeImage | texturecube&lt;type, access::sample&gt; | TextureCube |
| texture_cube_array&lt;type&gt; | OpTypeImage | texturecube_array&lt;type, access::sample&gt; | TextureCubeArray |
| | | |
| texture_multisampled_2d&lt;type&gt; | OpTypeImage | | Texture2D |
| texture_multisampled_2d&lt;type&gt; | OpTypeImage | texture2d_ms&lt;type, access::sample&gt; | Texture2D |
| | | |
| texture_depth_2d | OpTypeImage | | Texture2D |
| texture_depth_2d_array | OpTypeImage | | Texture2DArray |
| texture_depth_cube | OpTypeImage | | TextureCube |
| texture_depth_cube_array | OpTypeImage | | TextureCubeArray |
| texture_depth_2d | OpTypeImage | depth2d&lt;float, access::sample&gt;| Texture2D |
| texture_depth_2d_array | OpTypeImage | depth2d_array&lt;float, access::sample&gt; | Texture2DArray |
| texture_depth_cube | OpTypeImage | depthcube&lt;float, access::sample&gt; | TextureCube |
| texture_depth_cube_array | OpTypeImage | depthcube_array&lt;float, access::sample&gt; | TextureCubeArray |
| | | |
| texture_storage_ro_1d&lt;image_storage_type&gt; | OpTypeImage | | RWTexture1D |
| texture_storage_ro_1d_array&lt;image_storage_type&gt; | OpTypeImage | | RWTexture1DArray |
| texture_storage_ro_2d&lt;image_storage_type&gt; | OpTypeImage | | RWTexture2D |
| texture_storage_ro_2d_array&lt;image_storage_type&gt; | OpTypeImage | | RWTexture2DArray |
| texture_storage_ro_3d&lt;image_storage_type&gt; | OpTypeImage | | RWTexture3D |
| texture_storage_ro_1d&lt;image_storage_type&gt; | OpTypeImage | texture1d&lt;type, access::read&gt; | RWTexture1D |
| texture_storage_ro_1d_array&lt;image_storage_type&gt; | OpTypeImage | texture1d_array&lt;type, access::read&gt; | RWTexture1DArray |
| texture_storage_ro_2d&lt;image_storage_type&gt; | OpTypeImage | texture2d&lt;type, access::read&gt; | RWTexture2D |
| texture_storage_ro_2d_array&lt;image_storage_type&gt; | OpTypeImage | texture2d_array&lt;type, access::read&gt; | RWTexture2DArray |
| texture_storage_ro_3d&lt;image_storage_type&gt; | OpTypeImage | texture3d&lt;type, access::read&gt; | RWTexture3D |
| | | |
| texture_storage_wo_1d&lt;image_storage_type&gt; | OpTypeImage | | RWTexture1D |
| texture_storage_wo_1d_array&lt;image_storage_type&gt; | OpTypeImage | | RWTexture1DArray |
| texture_storage_wo_2d&lt;image_storage_type&gt; | OpTypeImage | | RWTexture2D |
| texture_storage_wo_2d_array&lt;image_storage_type&gt; | OpTypeImage | | RWTexture2DArray |
| texture_storage_wo_3d&lt;image_storage_type&gt; | OpTypeImage | | RWTexture3D|
| texture_storage_wo_1d&lt;image_storage_type&gt; | OpTypeImage | texture1d&lt;type, access::write&gt; | RWTexture1D |
| texture_storage_wo_1d_array&lt;image_storage_type&gt; | OpTypeImage | texture1d_array&lt;type, access::write&gt; | RWTexture1DArray |
| texture_storage_wo_2d&lt;image_storage_type&gt; | OpTypeImage | texture2d&lt;type, access::write&gt; | RWTexture2D |
| texture_storage_wo_2d_array&lt;image_storage_type&gt; | OpTypeImage | texture2d_array&lt;type, access::write&gt; | RWTexture2DArray |
| texture_storage_wo_3d&lt;image_storage_type&gt; | OpTypeImage | texture3d&lt;type, access::write&gt; | RWTexture3D|
# Short-circuting
## HLSL

View File

@ -47,10 +47,15 @@
#include "src/ast/type/alias_type.h"
#include "src/ast/type/array_type.h"
#include "src/ast/type/bool_type.h"
#include "src/ast/type/depth_texture_type.h"
#include "src/ast/type/f32_type.h"
#include "src/ast/type/i32_type.h"
#include "src/ast/type/matrix_type.h"
#include "src/ast/type/multisampled_texture_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/storage_texture_type.h"
#include "src/ast/type/struct_type.h"
#include "src/ast/type/u32_type.h"
#include "src/ast/type/vector_type.h"
@ -1733,10 +1738,82 @@ bool GeneratorImpl::EmitType(ast::type::Type* type, const std::string& name) {
return false;
}
out_ << "*";
} else if (type->IsSampler()) {
out_ << "sampler";
} else if (type->IsStruct()) {
// The struct type emits as just the name. The declaration would be emitted
// as part of emitting the constructed types.
out_ << type->AsStruct()->name();
} else if (type->IsTexture()) {
auto* tex = type->AsTexture();
if (tex->IsDepth()) {
out_ << "depth";
} else {
out_ << "texture";
}
switch (tex->dim()) {
case ast::type::TextureDimension::k1d:
out_ << "1d";
break;
case ast::type::TextureDimension::k1dArray:
out_ << "1d_array";
break;
case ast::type::TextureDimension::k2d:
out_ << "2d";
break;
case ast::type::TextureDimension::k2dArray:
out_ << "2d_array";
break;
case ast::type::TextureDimension::k3d:
out_ << "3d";
break;
case ast::type::TextureDimension::kCube:
out_ << "cube";
break;
case ast::type::TextureDimension::kCubeArray:
out_ << "cube_array";
break;
default:
error_ = "Invalid texture dimensions";
return false;
}
if (tex->IsMultisampled()) {
out_ << "_ms";
}
out_ << "<";
if (tex->IsDepth()) {
out_ << "float, access::sample";
} else if (tex->IsStorage()) {
auto* storage = tex->AsStorage();
if (!EmitType(storage->type(), "")) {
return false;
}
out_ << ", access::";
if (storage->access() == ast::AccessControl::kReadOnly) {
out_ << "read";
} else if (storage->access() == ast::AccessControl::kWriteOnly) {
out_ << "write";
} else {
error_ = "Invalid access control for storage texture";
return false;
}
} else if (tex->IsMultisampled()) {
if (!EmitType(tex->AsMultisampled()->type(), "")) {
return false;
}
out_ << ", access::sample";
} else if (tex->IsSampled()) {
if (!EmitType(tex->AsSampled()->type(), "")) {
return false;
}
out_ << ", access::sample";
} else {
error_ = "invalid texture type";
return false;
}
out_ << ">";
} else if (type->IsU32()) {
out_ << "uint";

View File

@ -22,14 +22,21 @@
#include "src/ast/struct_member_offset_decoration.h"
#include "src/ast/type/array_type.h"
#include "src/ast/type/bool_type.h"
#include "src/ast/type/depth_texture_type.h"
#include "src/ast/type/f32_type.h"
#include "src/ast/type/i32_type.h"
#include "src/ast/type/matrix_type.h"
#include "src/ast/type/multisampled_texture_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/storage_texture_type.h"
#include "src/ast/type/struct_type.h"
#include "src/ast/type/u32_type.h"
#include "src/ast/type/vector_type.h"
#include "src/ast/type/void_type.h"
#include "src/context.h"
#include "src/type_determiner.h"
#include "src/writer/msl/generator_impl.h"
namespace tint {
@ -374,6 +381,156 @@ TEST_F(MslGeneratorImplTest, EmitType_Void) {
EXPECT_EQ(g.result(), "void");
}
TEST_F(MslGeneratorImplTest, EmitType_Sampler) {
ast::type::SamplerType sampler(ast::type::SamplerKind::kSampler);
ast::Module m;
GeneratorImpl g(&m);
ASSERT_TRUE(g.EmitType(&sampler, "")) << g.error();
EXPECT_EQ(g.result(), "sampler");
}
TEST_F(MslGeneratorImplTest, EmitType_SamplerComparison) {
ast::type::SamplerType sampler(ast::type::SamplerKind::kComparisonSampler);
ast::Module m;
GeneratorImpl g(&m);
ASSERT_TRUE(g.EmitType(&sampler, "")) << g.error();
EXPECT_EQ(g.result(), "sampler");
}
struct MslDepthTextureData {
ast::type::TextureDimension dim;
std::string result;
};
inline std::ostream& operator<<(std::ostream& out, MslDepthTextureData data) {
out << data.dim;
return out;
}
using MslDepthTexturesTest = testing::TestWithParam<MslDepthTextureData>;
TEST_P(MslDepthTexturesTest, Emit) {
auto params = GetParam();
ast::type::DepthTextureType s(params.dim);
ast::Module m;
GeneratorImpl g(&m);
ASSERT_TRUE(g.EmitType(&s, "")) << g.error();
EXPECT_EQ(g.result(), params.result);
}
INSTANTIATE_TEST_SUITE_P(
MslGeneratorImplTest,
MslDepthTexturesTest,
testing::Values(MslDepthTextureData{ast::type::TextureDimension::k2d,
"depth2d<float, access::sample>"},
MslDepthTextureData{ast::type::TextureDimension::k2dArray,
"depth2d_array<float, access::sample>"},
MslDepthTextureData{ast::type::TextureDimension::kCube,
"depthcube<float, access::sample>"},
MslDepthTextureData{
ast::type::TextureDimension::kCubeArray,
"depthcube_array<float, access::sample>"}));
struct MslTextureData {
ast::type::TextureDimension dim;
std::string result;
};
inline std::ostream& operator<<(std::ostream& out, MslTextureData data) {
out << data.dim;
return out;
}
using MslSampledtexturesTest = testing::TestWithParam<MslTextureData>;
TEST_P(MslSampledtexturesTest, Emit) {
auto params = GetParam();
ast::type::F32Type f32;
ast::type::SampledTextureType s(params.dim, &f32);
ast::Module m;
GeneratorImpl g(&m);
ASSERT_TRUE(g.EmitType(&s, "")) << g.error();
EXPECT_EQ(g.result(), params.result);
}
INSTANTIATE_TEST_SUITE_P(
MslGeneratorImplTest,
MslSampledtexturesTest,
testing::Values(MslTextureData{ast::type::TextureDimension::k1d,
"texture1d<float, access::sample>"},
MslTextureData{ast::type::TextureDimension::k1dArray,
"texture1d_array<float, access::sample>"},
MslTextureData{ast::type::TextureDimension::k2d,
"texture2d<float, access::sample>"},
MslTextureData{ast::type::TextureDimension::k2dArray,
"texture2d_array<float, access::sample>"},
MslTextureData{ast::type::TextureDimension::k3d,
"texture3d<float, access::sample>"},
MslTextureData{ast::type::TextureDimension::kCube,
"texturecube<float, access::sample>"},
MslTextureData{
ast::type::TextureDimension::kCubeArray,
"texturecube_array<float, access::sample>"}));
TEST_F(MslGeneratorImplTest, Emit_TypeMultisampledTexture) {
ast::type::U32Type u32;
ast::type::MultisampledTextureType s(ast::type::TextureDimension::k2d, &u32);
ast::Module m;
GeneratorImpl g(&m);
ASSERT_TRUE(g.EmitType(&s, "")) << g.error();
EXPECT_EQ(g.result(), "texture2d_ms<uint, access::sample>");
}
struct MslStorageTextureData {
ast::type::TextureDimension dim;
bool ro;
std::string result;
};
inline std::ostream& operator<<(std::ostream& out, MslStorageTextureData data) {
out << data.dim << (data.ro ? "ReadOnly" : "WriteOnly");
return out;
}
using MslStorageTexturesTest = testing::TestWithParam<MslStorageTextureData>;
TEST_P(MslStorageTexturesTest, Emit) {
auto params = GetParam();
ast::type::StorageTextureType s(params.dim,
params.ro ? ast::AccessControl::kReadOnly
: ast::AccessControl::kWriteOnly,
ast::type::ImageFormat::kR16Float);
Context ctx;
ast::Module m;
TypeDeterminer td(&ctx, &m);
GeneratorImpl g(&m);
ASSERT_TRUE(td.DetermineStorageTextureSubtype(&s)) << td.error();
ASSERT_TRUE(g.EmitType(&s, "")) << g.error();
EXPECT_EQ(g.result(), params.result);
}
INSTANTIATE_TEST_SUITE_P(
MslGeneratorImplTest,
MslStorageTexturesTest,
testing::Values(
MslStorageTextureData{ast::type::TextureDimension::k1d, true,
"texture1d<float, access::read>"},
MslStorageTextureData{ast::type::TextureDimension::k1dArray, true,
"texture1d_array<float, access::read>"},
MslStorageTextureData{ast::type::TextureDimension::k2d, true,
"texture2d<float, access::read>"},
MslStorageTextureData{ast::type::TextureDimension::k2dArray, true,
"texture2d_array<float, access::read>"},
MslStorageTextureData{ast::type::TextureDimension::k3d, true,
"texture3d<float, access::read>"},
MslStorageTextureData{ast::type::TextureDimension::k1d, false,
"texture1d<float, access::write>"},
MslStorageTextureData{ast::type::TextureDimension::k1dArray, false,
"texture1d_array<float, access::write>"},
MslStorageTextureData{ast::type::TextureDimension::k2d, false,
"texture2d<float, access::write>"},
MslStorageTextureData{ast::type::TextureDimension::k2dArray, false,
"texture2d_array<float, access::write>"},
MslStorageTextureData{ast::type::TextureDimension::k3d, false,
"texture3d<float, access::write>"}));
} // namespace
} // namespace msl
} // namespace writer