[hlsl-writer] Emit texture types

This CL adds emission of the texture types from the HLSL backend.

Bug: tint:146
Change-Id: I378bd6d63719acfbedff887bdf280709dc981e8f
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/32221
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
Reviewed-by: Ben Clayton <bclayton@google.com>
Reviewed-by: David Neto <dneto@google.com>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
diff --git a/docs/translations.md b/docs/translations.md
index ed8431d..ed4fc02 100644
--- a/docs/translations.md
+++ b/docs/translations.md
@@ -104,6 +104,43 @@
 | tanh | GLSLstd450Tanh | tanh | tanh |
 | trunc | GLSLstd450Trunc | trunc | trunc |
 
+# Types
+## Sampler Types
+| WGSL | SPIR-V | MSL | HLSL |
+|------|--------|-----|------|
+| sampler | OpTypeSampler | | SamplerState |
+| sampler_comparison | OpTypeSampler | | 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_multisampled_2d&lt;type&gt; | OpTypeImage | | Texture2D |
+| | | |
+| texture_depth_2d | OpTypeImage | | Texture2D |
+| texture_depth_2d_array | OpTypeImage | | Texture2DArray |
+| texture_depth_cube | OpTypeImage | | TextureCube |
+| texture_depth_cube_array | OpTypeImage | | 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_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|
+
 # Short-circuting
 ## HLSL
 TODO(dsinclair): Nested if's
diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc
index 763bb66..1ae094c 100644
--- a/src/writer/hlsl/generator_impl.cc
+++ b/src/writer/hlsl/generator_impl.cc
@@ -44,7 +44,9 @@
 #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/sampler_type.h"
 #include "src/ast/type/struct_type.h"
+#include "src/ast/type/texture_type.h"
 #include "src/ast/type/vector_type.h"
 #include "src/ast/uint_literal.h"
 #include "src/ast/unary_op_expression.h"
@@ -1984,8 +1986,49 @@
     // https://bugs.chromium.org/p/tint/issues/detail?id=183
     error_ = "pointers not supported in HLSL";
     return false;
+  } else if (type->IsSampler()) {
+    auto* sampler = type->AsSampler();
+    out << "Sampler";
+    if (sampler->IsComparison()) {
+      out << "Comparison";
+    }
+    out << "State";
   } else if (type->IsStruct()) {
     out << type->AsStruct()->name();
+  } else if (type->IsTexture()) {
+    auto* tex = type->AsTexture();
+    if (tex->IsStorage()) {
+      out << "RW";
+    }
+    out << "Texture";
+
+    switch (tex->dim()) {
+      case ast::type::TextureDimension::k1d:
+        out << "1D";
+        break;
+      case ast::type::TextureDimension::k1dArray:
+        out << "1DArray";
+        break;
+      case ast::type::TextureDimension::k2d:
+        out << "2D";
+        break;
+      case ast::type::TextureDimension::k2dArray:
+        out << "2DArray";
+        break;
+      case ast::type::TextureDimension::k3d:
+        out << "3D";
+        break;
+      case ast::type::TextureDimension::kCube:
+        out << "Cube";
+        break;
+      case ast::type::TextureDimension::kCubeArray:
+        out << "CubeArray";
+        break;
+      default:
+        error_ = "Invalid texture dimensions";
+        return false;
+    }
+
   } else if (type->IsU32()) {
     out << "uint";
   } else if (type->IsVector()) {
diff --git a/src/writer/hlsl/generator_impl_type_test.cc b/src/writer/hlsl/generator_impl_type_test.cc
index f91756e..8cac130 100644
--- a/src/writer/hlsl/generator_impl_type_test.cc
+++ b/src/writer/hlsl/generator_impl_type_test.cc
@@ -21,10 +21,15 @@
 #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"
@@ -329,6 +334,139 @@
   EXPECT_EQ(result(), "void");
 }
 
+TEST_F(HlslGeneratorImplTest_Type, EmitSampler) {
+  ast::type::SamplerType sampler(ast::type::SamplerKind::kSampler);
+
+  ASSERT_TRUE(gen().EmitType(out(), &sampler, "")) << gen().error();
+  EXPECT_EQ(result(), "SamplerState");
+}
+
+TEST_F(HlslGeneratorImplTest_Type, EmitSamplerComparison) {
+  ast::type::SamplerType sampler(ast::type::SamplerKind::kComparisonSampler);
+
+  ASSERT_TRUE(gen().EmitType(out(), &sampler, "")) << gen().error();
+  EXPECT_EQ(result(), "SamplerComparisonState");
+}
+
+struct HlslDepthTextureData {
+  ast::type::TextureDimension dim;
+  std::string result;
+};
+inline std::ostream& operator<<(std::ostream& out, HlslDepthTextureData data) {
+  out << data.dim;
+  return out;
+}
+using HlslDepthtexturesTest =
+    TestHelperBase<testing::TestWithParam<HlslDepthTextureData>>;
+TEST_P(HlslDepthtexturesTest, Emit) {
+  auto params = GetParam();
+
+  ast::type::DepthTextureType s(params.dim);
+
+  ASSERT_TRUE(gen().EmitType(out(), &s, "")) << gen().error();
+  EXPECT_EQ(result(), params.result);
+}
+INSTANTIATE_TEST_SUITE_P(
+    HlslGeneratorImplTest_Type,
+    HlslDepthtexturesTest,
+    testing::Values(
+        HlslDepthTextureData{ast::type::TextureDimension::k2d, "Texture2D"},
+        HlslDepthTextureData{ast::type::TextureDimension::k2dArray,
+                             "Texture2DArray"},
+        HlslDepthTextureData{ast::type::TextureDimension::kCube, "TextureCube"},
+        HlslDepthTextureData{ast::type::TextureDimension::kCubeArray,
+                             "TextureCubeArray"}));
+
+struct HlslTextureData {
+  ast::type::TextureDimension dim;
+  std::string result;
+};
+inline std::ostream& operator<<(std::ostream& out, HlslTextureData data) {
+  out << data.dim;
+  return out;
+}
+using HlslSampledtexturesTest =
+    TestHelperBase<testing::TestWithParam<HlslTextureData>>;
+TEST_P(HlslSampledtexturesTest, Emit) {
+  auto params = GetParam();
+
+  ast::type::F32Type f32;
+  ast::type::SampledTextureType s(params.dim, &f32);
+
+  ASSERT_TRUE(gen().EmitType(out(), &s, "")) << gen().error();
+  EXPECT_EQ(result(), params.result);
+}
+INSTANTIATE_TEST_SUITE_P(
+    HlslGeneratorImplTest_Type,
+    HlslSampledtexturesTest,
+    testing::Values(
+        HlslTextureData{ast::type::TextureDimension::k1d, "Texture1D"},
+        HlslTextureData{ast::type::TextureDimension::k1dArray,
+                        "Texture1DArray"},
+        HlslTextureData{ast::type::TextureDimension::k2d, "Texture2D"},
+        HlslTextureData{ast::type::TextureDimension::k2dArray,
+                        "Texture2DArray"},
+        HlslTextureData{ast::type::TextureDimension::k3d, "Texture3D"},
+        HlslTextureData{ast::type::TextureDimension::kCube, "TextureCube"},
+        HlslTextureData{ast::type::TextureDimension::kCubeArray,
+                        "TextureCubeArray"}));
+
+TEST_F(HlslGeneratorImplTest_Type, EmitMultisampledTexture) {
+  ast::type::F32Type f32;
+  ast::type::MultisampledTextureType s(ast::type::TextureDimension::k2d, &f32);
+
+  ASSERT_TRUE(gen().EmitType(out(), &s, "")) << gen().error();
+  EXPECT_EQ(result(), "Texture2D");
+}
+
+struct HlslStorageTextureData {
+  ast::type::TextureDimension dim;
+  bool ro;
+  std::string result;
+};
+inline std::ostream& operator<<(std::ostream& out,
+                                HlslStorageTextureData data) {
+  out << data.dim << (data.ro ? "ReadOnly" : "WriteOnly");
+  return out;
+}
+using HlslStoragetexturesTest =
+    TestHelperBase<testing::TestWithParam<HlslStorageTextureData>>;
+TEST_P(HlslStoragetexturesTest, Emit) {
+  auto params = GetParam();
+
+  ast::type::StorageTextureType s(params.dim,
+                                  params.ro ? ast::AccessControl::kReadOnly
+                                            : ast::AccessControl::kWriteOnly,
+                                  ast::type::ImageFormat::kR16Float);
+
+  ASSERT_TRUE(gen().EmitType(out(), &s, "")) << gen().error();
+  EXPECT_EQ(result(), params.result);
+}
+INSTANTIATE_TEST_SUITE_P(
+    HlslGeneratorImplTest_Type,
+    HlslStoragetexturesTest,
+    testing::Values(
+        HlslStorageTextureData{ast::type::TextureDimension::k1d, true,
+                               "RWTexture1D"},
+        HlslStorageTextureData{ast::type::TextureDimension::k1dArray, true,
+                               "RWTexture1DArray"},
+        HlslStorageTextureData{ast::type::TextureDimension::k2d, true,
+                               "RWTexture2D"},
+        HlslStorageTextureData{ast::type::TextureDimension::k2dArray, true,
+                               "RWTexture2DArray"},
+        HlslStorageTextureData{ast::type::TextureDimension::k3d, true,
+                               "RWTexture3D"},
+        HlslStorageTextureData{ast::type::TextureDimension::k1d, false,
+                               "RWTexture1D"},
+        HlslStorageTextureData{ast::type::TextureDimension::k1dArray, false,
+                               "RWTexture1DArray"},
+        HlslStorageTextureData{ast::type::TextureDimension::k2d, false,
+                               "RWTexture2D"},
+        HlslStorageTextureData{ast::type::TextureDimension::k2dArray, false,
+                               "RWTexture2DArray"},
+        HlslStorageTextureData{ast::type::TextureDimension::k3d, false,
+                               "RWTexture3D"}));
+
 }  // namespace
 }  // namespace hlsl
 }  // namespace writer