Allow Bind Group Layout Binding visibility to be None

According to https://github.com/gpuweb/gpuweb/issues/405, None is a
valid value for GPUBindGroupLayoutBinding visibility to be passed in.

Bug: dawn:22
Change-Id: I7b30b7ab8ed6824718573fa25fad5d509846db55
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/11980
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: François Beaufort <beaufort.francois@gmail.com>
diff --git a/src/dawn_native/BindGroupLayout.cpp b/src/dawn_native/BindGroupLayout.cpp
index 29aec85..2001b6b 100644
--- a/src/dawn_native/BindGroupLayout.cpp
+++ b/src/dawn_native/BindGroupLayout.cpp
@@ -49,10 +49,6 @@
                 return DAWN_VALIDATION_ERROR("some binding index was specified more than once");
             }
 
-            if (binding.visibility == dawn::ShaderStage::None) {
-                return DAWN_VALIDATION_ERROR("Visibility of bindings can't be None");
-            }
-
             switch (binding.type) {
                 case dawn::BindingType::UniformBuffer:
                     if (binding.hasDynamicOffset) {
diff --git a/src/tests/end2end/BindGroupTests.cpp b/src/tests/end2end/BindGroupTests.cpp
index fc8949b..d1ef43a 100644
--- a/src/tests/end2end/BindGroupTests.cpp
+++ b/src/tests/end2end/BindGroupTests.cpp
@@ -776,4 +776,35 @@
     EXPECT_PIXEL_RGBA8_EQ(notFilled, renderPass.color, max, max);
 }
 
+// Test that visibility of bindings in BindGroupLayout can be none
+// This test passes by not asserting or crashing.
+TEST_P(BindGroupTests, BindGroupLayoutVisibilityCanBeNone) {
+    utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize);
+
+    dawn::BindGroupLayoutBinding binding = {0, dawn::ShaderStage::None,
+                                            dawn::BindingType::UniformBuffer};
+    dawn::BindGroupLayoutDescriptor descriptor;
+    descriptor.bindingCount = 1;
+    descriptor.bindings = &binding;
+    dawn::BindGroupLayout layout = device.CreateBindGroupLayout(&descriptor);
+
+    dawn::RenderPipeline pipeline = MakeTestPipeline(renderPass, {}, {layout});
+
+    std::array<float, 4> color = {1, 0, 0, 1};
+    dawn::Buffer uniformBuffer =
+        utils::CreateBufferFromData(device, &color, sizeof(color), dawn::BufferUsage::Uniform);
+    dawn::BindGroup bindGroup =
+        utils::MakeBindGroup(device, layout, {{0, uniformBuffer, 0, sizeof(color)}});
+
+    dawn::CommandEncoder encoder = device.CreateCommandEncoder();
+    dawn::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
+    pass.SetPipeline(pipeline);
+    pass.SetBindGroup(0, bindGroup);
+    pass.Draw(3, 1, 0, 0);
+    pass.EndPass();
+
+    dawn::CommandBuffer commands = encoder.Finish();
+    queue.Submit(1, &commands);
+}
+
 DAWN_INSTANTIATE_TEST(BindGroupTests, D3D12Backend, MetalBackend, OpenGLBackend, VulkanBackend);
diff --git a/src/tests/unittests/validation/BindGroupValidationTests.cpp b/src/tests/unittests/validation/BindGroupValidationTests.cpp
index a59f315..ed4ec04 100644
--- a/src/tests/unittests/validation/BindGroupValidationTests.cpp
+++ b/src/tests/unittests/validation/BindGroupValidationTests.cpp
@@ -526,7 +526,7 @@
                 }));
 }
 
-// This test verifies that visibility of bindings in BindGroupLayout can't be none
+// This test verifies that visibility of bindings in BindGroupLayout can be none
 TEST_F(BindGroupLayoutValidationTest, BindGroupLayoutVisibilityNone) {
     utils::MakeBindGroupLayout(device,
                                {
@@ -538,7 +538,7 @@
     dawn::BindGroupLayoutDescriptor descriptor;
     descriptor.bindingCount = 1;
     descriptor.bindings = &binding;
-    ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&descriptor));
+    device.CreateBindGroupLayout(&descriptor);
 }
 
 // Check that dynamic buffer numbers exceed maximum value in one bind group layout.