Add APICreateErrorView on TextureBase

This API is used to return an error texture view when arrayLayerCount
and mipLevelCount are validated failed in Blink.

Bug: dawn:1026
Change-Id: Ic48b8ff3d360ac549bdaebcbf4f9e7bcc99594be
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/168820
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Loko Kung <lokokung@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn/dawn.json b/src/dawn/dawn.json
index eb1d80f..db09714 100644
--- a/src/dawn/dawn.json
+++ b/src/dawn/dawn.json
@@ -3403,6 +3403,14 @@
                 ]
             },
             {
+                "name": "create error view",
+                "returns": "texture view",
+                "tags": ["dawn"],
+                "args": [
+                    {"name": "descriptor", "type": "texture view descriptor", "annotation": "const*", "optional": true}
+                ]
+            },
+            {
                 "name": "set label",
                 "returns": "void",
                 "args": [
diff --git a/src/dawn/native/Texture.cpp b/src/dawn/native/Texture.cpp
index 06479e7..52f7aa5 100644
--- a/src/dawn/native/Texture.cpp
+++ b/src/dawn/native/Texture.cpp
@@ -1109,6 +1109,10 @@
     return GetDevice()->CreateTextureView(this, descriptor);
 }
 
+TextureViewBase* TextureBase::CreateErrorView(const TextureViewDescriptor* descriptor) {
+    return TextureViewBase::MakeError(GetDevice(), descriptor ? descriptor->label : nullptr);
+}
+
 ApiObjectList* TextureBase::GetViewTrackingList() {
     return &mTextureViews;
 }
@@ -1119,11 +1123,15 @@
     Ref<TextureViewBase> result;
     if (device->ConsumedError(CreateView(descriptor), &result, "calling %s.CreateView(%s).", this,
                               descriptor)) {
-        return TextureViewBase::MakeError(device, descriptor ? descriptor->label : nullptr);
+        return CreateErrorView(descriptor);
     }
     return result.Detach();
 }
 
+TextureViewBase* TextureBase::APICreateErrorView(const TextureViewDescriptor* descriptor) {
+    return CreateErrorView(descriptor);
+}
+
 bool TextureBase::IsImplicitMSAARenderTextureViewSupported() const {
     return (GetUsage() & wgpu::TextureUsage::TextureBinding) != 0;
 }
diff --git a/src/dawn/native/Texture.h b/src/dawn/native/Texture.h
index 14aca0f..f3acaef 100644
--- a/src/dawn/native/Texture.h
+++ b/src/dawn/native/Texture.h
@@ -139,6 +139,7 @@
 
     ResultOrError<Ref<TextureViewBase>> CreateView(
         const TextureViewDescriptor* descriptor = nullptr);
+    TextureViewBase* CreateErrorView(const TextureViewDescriptor* descriptor = nullptr);
     ApiObjectList* GetViewTrackingList();
 
     bool IsImplicitMSAARenderTextureViewSupported() const;
@@ -147,6 +148,7 @@
 
     // Dawn API
     TextureViewBase* APICreateView(const TextureViewDescriptor* descriptor = nullptr);
+    TextureViewBase* APICreateErrorView(const TextureViewDescriptor* descriptor = nullptr);
     void APIDestroy();
     uint32_t APIGetWidth() const;
     uint32_t APIGetHeight() const;
diff --git a/src/dawn/tests/unittests/validation/TextureViewValidationTests.cpp b/src/dawn/tests/unittests/validation/TextureViewValidationTests.cpp
index 6fa3d9a..cf17283 100644
--- a/src/dawn/tests/unittests/validation/TextureViewValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/TextureViewValidationTests.cpp
@@ -28,6 +28,7 @@
 #include <array>
 
 #include "dawn/tests/unittests/validation/ValidationTest.h"
+#include "dawn/utils/WGPUHelpers.h"
 
 namespace dawn {
 namespace {
@@ -928,6 +929,21 @@
     }
 }
 
+// Test that CreateErrorView creates an invalid texture view but doesn't produce an error.
+TEST_F(TextureViewValidationTest, CreateErrorView) {
+    wgpu::Texture texture = Create2DArrayTexture(device, 1);
+    wgpu::TextureViewDescriptor descriptor =
+        CreateDefaultViewDescriptor(wgpu::TextureViewDimension::e2D);
+
+    // Creating the error texture view doesn't produce an error.
+    wgpu::TextureView view = texture.CreateErrorView(&descriptor);
+
+    // Using the error texture view will throw an error.
+    wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
+        device, {{0, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Float}});
+    ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, view}}));
+}
+
 class D32S8TextureViewValidationTests : public ValidationTest {
   protected:
     WGPUDevice CreateTestDevice(native::Adapter dawnAdapter,