[tint][ir][val] Reject StorageTexture with invalid dimensions

Fixes: 383237362
Change-Id: Ib91fbf9af3a77adc2188da83ea2077e3a905b2eb
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/218815
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
Commit-Queue: James Price <jrprice@google.com>
Auto-Submit: Ryan Harrison <rharrison@chromium.org>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/tint/lang/core/ir/validator.cc b/src/tint/lang/core/ir/validator.cc
index c550285..b66637f 100644
--- a/src/tint/lang/core/ir/validator.cc
+++ b/src/tint/lang/core/ir/validator.cc
@@ -88,6 +88,7 @@
 #include "src/tint/lang/core/type/memory_view.h"
 #include "src/tint/lang/core/type/pointer.h"
 #include "src/tint/lang/core/type/reference.h"
+#include "src/tint/lang/core/type/storage_texture.h"
 #include "src/tint/lang/core/type/type.h"
 #include "src/tint/lang/core/type/u32.h"
 #include "src/tint/lang/core/type/u8.h"
@@ -1821,6 +1822,21 @@
                 }
                 return true;
             },
+            [&](const core::type::StorageTexture* s) {
+                switch (s->Dim()) {
+                    case core::type::TextureDimension::kCube:
+                    case core::type::TextureDimension::kCubeArray:
+                        diag() << "dimension " << style::Literal(ToString(s->Dim()))
+                               << " for storage textures does not in WGSL yet";
+                        return false;
+                    case core::type::TextureDimension::kNone:
+                        diag() << "invalid texture dimension "
+                               << style::Literal(ToString(s->Dim()));
+                        return false;
+                    default:
+                        return true;
+                }
+            },
             [](Default) { return true; });
     };
 
diff --git a/src/tint/lang/core/ir/validator_test.cc b/src/tint/lang/core/ir/validator_test.cc
index f332cc3..8a4037d 100644
--- a/src/tint/lang/core/ir/validator_test.cc
+++ b/src/tint/lang/core/ir/validator_test.cc
@@ -39,11 +39,13 @@
 #include "src/tint/lang/core/ir/type/array_count.h"
 #include "src/tint/lang/core/ir/validator.h"
 #include "src/tint/lang/core/number.h"
+#include "src/tint/lang/core/texel_format.h"
 #include "src/tint/lang/core/type/manager.h"
 #include "src/tint/lang/core/type/matrix.h"
 #include "src/tint/lang/core/type/memory_view.h"
 #include "src/tint/lang/core/type/pointer.h"
 #include "src/tint/lang/core/type/reference.h"
+#include "src/tint/lang/core/type/storage_texture.h"
 #include "src/tint/lang/core/type/struct.h"
 #include "src/tint/utils/text/string.h"
 
@@ -5313,6 +5315,77 @@
 )");
 }
 
+TEST_F(IR_ValidatorTest, Type_StorageTextureDimension) {
+    auto* valid =
+        b.Var("valid", AddressSpace::kStorage,
+              ty.storage_texture(core::type::TextureDimension::k2d, core::TexelFormat::kRgba32Float,
+                                 core::Access::kReadWrite),
+              read_write);
+    valid->SetBindingPoint(0, 0);
+    mod.root_block->Append(valid);
+
+    auto* cube =
+        b.Var("cube_invalid", AddressSpace::kStorage,
+              ty.storage_texture(core::type::TextureDimension::kCube,
+                                 core::TexelFormat::kRgba32Float, core::Access::kReadWrite),
+              read_write);
+    cube->SetBindingPoint(1, 1);
+    mod.root_block->Append(cube);
+
+    auto* cube_array =
+        b.Var("cube_array_invalid", AddressSpace::kStorage,
+              ty.storage_texture(core::type::TextureDimension::kCubeArray,
+                                 core::TexelFormat::kRgba32Float, core::Access::kReadWrite),
+              read_write);
+    cube_array->SetBindingPoint(2, 2);
+    mod.root_block->Append(cube_array);
+
+    auto* none =
+        b.Var("none_invalid", AddressSpace::kStorage,
+              ty.storage_texture(core::type::TextureDimension::kNone,
+                                 core::TexelFormat::kRgba32Float, core::Access::kReadWrite),
+              read_write);
+    none->SetBindingPoint(3, 3);
+    mod.root_block->Append(none);
+
+    auto res = ir::Validate(mod);
+    ASSERT_NE(res, Success);
+    EXPECT_EQ(res.Failure().reason.Str(),
+              R"(:3:3 error: var: dimension 'cube' for storage textures does not in WGSL yet
+  %cube_invalid:ptr<storage, texture_storage_cube<rgba32float, read_write>, read_write> = var @binding_point(1, 1)
+  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+:1:1 note: in block
+$B1: {  # root
+^^^
+
+:4:3 error: var: dimension 'cube_array' for storage textures does not in WGSL yet
+  %cube_array_invalid:ptr<storage, texture_storage_cube_array<rgba32float, read_write>, read_write> = var @binding_point(2, 2)
+  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+:1:1 note: in block
+$B1: {  # root
+^^^
+
+:5:3 error: var: invalid texture dimension 'none'
+  %none_invalid:ptr<storage, texture_storage_none<rgba32float, read_write>, read_write> = var @binding_point(3, 3)
+  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+:1:1 note: in block
+$B1: {  # root
+^^^
+
+note: # Disassembly
+$B1: {  # root
+  %valid:ptr<storage, texture_storage_2d<rgba32float, read_write>, read_write> = var @binding_point(0, 0)
+  %cube_invalid:ptr<storage, texture_storage_cube<rgba32float, read_write>, read_write> = var @binding_point(1, 1)
+  %cube_array_invalid:ptr<storage, texture_storage_cube_array<rgba32float, read_write>, read_write> = var @binding_point(2, 2)
+  %none_invalid:ptr<storage, texture_storage_none<rgba32float, read_write>, read_write> = var @binding_point(3, 3)
+}
+
+)");
+}
+
 TEST_F(IR_ValidatorTest, Var_RootBlock_NullResult) {
     auto* v = mod.CreateInstruction<ir::Var>(nullptr);
     v->SetInitializer(b.Constant(0_i));
diff --git a/src/tint/lang/core/type/manager.cc b/src/tint/lang/core/type/manager.cc
index 96b3489..9b04b4e 100644
--- a/src/tint/lang/core/type/manager.cc
+++ b/src/tint/lang/core/type/manager.cc
@@ -42,6 +42,7 @@
 #include "src/tint/lang/core/type/matrix.h"
 #include "src/tint/lang/core/type/pointer.h"
 #include "src/tint/lang/core/type/reference.h"
+#include "src/tint/lang/core/type/storage_texture.h"
 #include "src/tint/lang/core/type/type.h"
 #include "src/tint/lang/core/type/u32.h"
 #include "src/tint/lang/core/type/u8.h"
@@ -146,6 +147,13 @@
     return vec(inner, 4);
 }
 
+const core::type::StorageTexture* Manager::storage_texture(TextureDimension dim,
+                                                           core::TexelFormat format,
+                                                           core::Access access) {
+    const auto* subtype = StorageTexture::SubtypeFor(format, *this);
+    return Get<core::type::StorageTexture>(dim, format, access, subtype);
+}
+
 const core::type::Matrix* Manager::mat(const core::type::Type* inner,
                                        uint32_t cols,
                                        uint32_t rows) {
diff --git a/src/tint/lang/core/type/manager.h b/src/tint/lang/core/type/manager.h
index ae2a8ac..592df01 100644
--- a/src/tint/lang/core/type/manager.h
+++ b/src/tint/lang/core/type/manager.h
@@ -34,6 +34,7 @@
 #include "src/tint/lang/core/address_space.h"
 #include "src/tint/lang/core/fluent_types.h"
 #include "src/tint/lang/core/number.h"
+#include "src/tint/lang/core/texel_format.h"
 #include "src/tint/lang/core/type/atomic.h"
 #include "src/tint/lang/core/type/external_texture.h"
 #include "src/tint/lang/core/type/sampler.h"
@@ -59,6 +60,7 @@
 class Matrix;
 class Pointer;
 class Reference;
+class StorageTexture;
 class U8;
 class U32;
 class Vector;
@@ -254,6 +256,14 @@
     /// @returns a vec4 type with the element type @p inner
     const core::type::Vector* vec4(const core::type::Type* inner);
 
+    /// @param dim the dimensionality of the texture
+    /// @param format the texel format of the texture
+    /// @param access the access control type of the texture
+    /// @returns a storage texture type with the provided params
+    const core::type::StorageTexture* storage_texture(TextureDimension dim,
+                                                      core::TexelFormat format,
+                                                      core::Access access);
+
     /// Return a type with element type `el_ty` that has the same number of vector components as
     /// `match`. If `match` is scalar just return `el_ty`.
     /// @param el_ty the type to extend
diff --git a/src/tint/lang/core/type/texture_dimension.cc b/src/tint/lang/core/type/texture_dimension.cc
index 3f3a7fc..3371c1e 100644
--- a/src/tint/lang/core/type/texture_dimension.cc
+++ b/src/tint/lang/core/type/texture_dimension.cc
@@ -32,7 +32,7 @@
 std::string_view ToString(core::type::TextureDimension dim) {
     switch (dim) {
         case core::type::TextureDimension::kNone:
-            return "None";
+            return "none";
         case core::type::TextureDimension::k1d:
             return "1d";
         case core::type::TextureDimension::k2d:
diff --git a/src/tint/lang/glsl/writer/type_test.cc b/src/tint/lang/glsl/writer/type_test.cc
index 487394f..61cb4e0 100644
--- a/src/tint/lang/glsl/writer/type_test.cc
+++ b/src/tint/lang/glsl/writer/type_test.cc
@@ -924,10 +924,6 @@
                                TextureDataType::kF32, "readonly image2DArray"},
         GlslStorageTextureData{core::type::TextureDimension::k3d, core::Access::kRead,
                                TextureDataType::kF32, "readonly image3D"},
-        GlslStorageTextureData{core::type::TextureDimension::kCube, core::Access::kRead,
-                               TextureDataType::kF32, "readonly imageCube"},
-        GlslStorageTextureData{core::type::TextureDimension::kCubeArray, core::Access::kRead,
-                               TextureDataType::kF32, "readonly imageCubeArray"},
 
         GlslStorageTextureData{core::type::TextureDimension::k2d, core::Access::kWrite,
                                TextureDataType::kF32, "writeonly image2D"},
@@ -935,10 +931,6 @@
                                TextureDataType::kF32, "writeonly image2DArray"},
         GlslStorageTextureData{core::type::TextureDimension::k3d, core::Access::kWrite,
                                TextureDataType::kF32, "writeonly image3D"},
-        GlslStorageTextureData{core::type::TextureDimension::kCube, core::Access::kWrite,
-                               TextureDataType::kF32, "writeonly imageCube"},
-        GlslStorageTextureData{core::type::TextureDimension::kCubeArray, core::Access::kWrite,
-                               TextureDataType::kF32, "writeonly imageCubeArray"},
 
         GlslStorageTextureData{core::type::TextureDimension::k2d, core::Access::kReadWrite,
                                TextureDataType::kF32, "image2D"},
@@ -946,10 +938,6 @@
                                TextureDataType::kF32, "image2DArray"},
         GlslStorageTextureData{core::type::TextureDimension::k3d, core::Access::kReadWrite,
                                TextureDataType::kF32, "image3D"},
-        GlslStorageTextureData{core::type::TextureDimension::kCube, core::Access::kReadWrite,
-                               TextureDataType::kF32, "imageCube"},
-        GlslStorageTextureData{core::type::TextureDimension::kCubeArray, core::Access::kReadWrite,
-                               TextureDataType::kF32, "imageCubeArray"},
 
         GlslStorageTextureData{core::type::TextureDimension::k2d, core::Access::kRead,
                                TextureDataType::kI32, "readonly iimage2D"},
@@ -957,10 +945,6 @@
                                TextureDataType::kI32, "readonly iimage2DArray"},
         GlslStorageTextureData{core::type::TextureDimension::k3d, core::Access::kRead,
                                TextureDataType::kI32, "readonly iimage3D"},
-        GlslStorageTextureData{core::type::TextureDimension::kCube, core::Access::kRead,
-                               TextureDataType::kI32, "readonly iimageCube"},
-        GlslStorageTextureData{core::type::TextureDimension::kCubeArray, core::Access::kRead,
-                               TextureDataType::kI32, "readonly iimageCubeArray"},
 
         GlslStorageTextureData{core::type::TextureDimension::k2d, core::Access::kWrite,
                                TextureDataType::kI32, "writeonly iimage2D"},
@@ -968,10 +952,6 @@
                                TextureDataType::kI32, "writeonly iimage2DArray"},
         GlslStorageTextureData{core::type::TextureDimension::k3d, core::Access::kWrite,
                                TextureDataType::kI32, "writeonly iimage3D"},
-        GlslStorageTextureData{core::type::TextureDimension::kCube, core::Access::kWrite,
-                               TextureDataType::kI32, "writeonly iimageCube"},
-        GlslStorageTextureData{core::type::TextureDimension::kCubeArray, core::Access::kWrite,
-                               TextureDataType::kI32, "writeonly iimageCubeArray"},
 
         GlslStorageTextureData{core::type::TextureDimension::k2d, core::Access::kReadWrite,
                                TextureDataType::kI32, "iimage2D"},
@@ -979,10 +959,6 @@
                                TextureDataType::kI32, "iimage2DArray"},
         GlslStorageTextureData{core::type::TextureDimension::k3d, core::Access::kReadWrite,
                                TextureDataType::kI32, "iimage3D"},
-        GlslStorageTextureData{core::type::TextureDimension::kCube, core::Access::kReadWrite,
-                               TextureDataType::kI32, "iimageCube"},
-        GlslStorageTextureData{core::type::TextureDimension::kCubeArray, core::Access::kReadWrite,
-                               TextureDataType::kI32, "iimageCubeArray"},
 
         GlslStorageTextureData{core::type::TextureDimension::k2d, core::Access::kRead,
                                TextureDataType::kU32, "readonly uimage2D"},
@@ -990,10 +966,6 @@
                                TextureDataType::kU32, "readonly uimage2DArray"},
         GlslStorageTextureData{core::type::TextureDimension::k3d, core::Access::kRead,
                                TextureDataType::kU32, "readonly uimage3D"},
-        GlslStorageTextureData{core::type::TextureDimension::kCube, core::Access::kRead,
-                               TextureDataType::kU32, "readonly uimageCube"},
-        GlslStorageTextureData{core::type::TextureDimension::kCubeArray, core::Access::kRead,
-                               TextureDataType::kU32, "readonly uimageCubeArray"},
 
         GlslStorageTextureData{core::type::TextureDimension::k2d, core::Access::kWrite,
                                TextureDataType::kU32, "writeonly uimage2D"},
@@ -1001,21 +973,13 @@
                                TextureDataType::kU32, "writeonly uimage2DArray"},
         GlslStorageTextureData{core::type::TextureDimension::k3d, core::Access::kWrite,
                                TextureDataType::kU32, "writeonly uimage3D"},
-        GlslStorageTextureData{core::type::TextureDimension::kCube, core::Access::kWrite,
-                               TextureDataType::kU32, "writeonly uimageCube"},
-        GlslStorageTextureData{core::type::TextureDimension::kCubeArray, core::Access::kWrite,
-                               TextureDataType::kU32, "writeonly uimageCubeArray"},
 
         GlslStorageTextureData{core::type::TextureDimension::k2d, core::Access::kReadWrite,
                                TextureDataType::kU32, "uimage2D"},
         GlslStorageTextureData{core::type::TextureDimension::k2dArray, core::Access::kReadWrite,
                                TextureDataType::kU32, "uimage2DArray"},
         GlslStorageTextureData{core::type::TextureDimension::k3d, core::Access::kReadWrite,
-                               TextureDataType::kU32, "uimage3D"},
-        GlslStorageTextureData{core::type::TextureDimension::kCube, core::Access::kReadWrite,
-                               TextureDataType::kU32, "uimageCube"},
-        GlslStorageTextureData{core::type::TextureDimension::kCubeArray, core::Access::kReadWrite,
-                               TextureDataType::kU32, "uimageCubeArray"}));
+                               TextureDataType::kU32, "uimage3D"}));
 
 TEST_F(GlslWriterTest, EmitType_PadInlineStruct) {
     Vector members{ty.Get<core::type::StructMember>(