Newline fixes and tiny cleanups for lazy-0-init

BUG=

Change-Id: I1165b0d75b4e2796ff89ffabb2401c474955ee2a
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/8440
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Natasha Lee <natlee@microsoft.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn_native/vulkan/CommandBufferVk.cpp b/src/dawn_native/vulkan/CommandBufferVk.cpp
index 7fdb225..cacbbac 100644
--- a/src/dawn_native/vulkan/CommandBufferVk.cpp
+++ b/src/dawn_native/vulkan/CommandBufferVk.cpp
@@ -175,7 +175,7 @@
                     dawn::LoadOp loadOp = attachmentInfo.loadOp;
                     ASSERT(view->GetLayerCount() == 1);
                     ASSERT(view->GetLevelCount() == 1);
-                    if (loadOp == dawn::LoadOp::Load && view->GetTexture() &&
+                    if (loadOp == dawn::LoadOp::Load &&
                         !view->GetTexture()->IsSubresourceContentInitialized(
                             view->GetBaseMipLevel(), 1, view->GetBaseArrayLayer(), 1)) {
                         loadOp = dawn::LoadOp::Clear;
diff --git a/src/tests/end2end/NonzeroTextureCreationTests.cpp b/src/tests/end2end/NonzeroTextureCreationTests.cpp
index a019945..e448cd6 100644
--- a/src/tests/end2end/NonzeroTextureCreationTests.cpp
+++ b/src/tests/end2end/NonzeroTextureCreationTests.cpp
@@ -1,106 +1,106 @@
-// Copyright 2019 The Dawn Authors

-//

-// Licensed under the Apache License, Version 2.0 (the "License");

-// you may not use this file except in compliance with the License.

-// You may obtain a copy of the License at

-//

-//     http://www.apache.org/licenses/LICENSE-2.0

-//

-// Unless required by applicable law or agreed to in writing, software

-// distributed under the License is distributed on an "AS IS" BASIS,

-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

-// See the License for the specific language governing permissions and

-// limitations under the License.

-

-#include "tests/DawnTest.h"

-

-#include "utils/ComboRenderPipelineDescriptor.h"

-#include "utils/DawnHelpers.h"

-

-class NonzeroTextureCreationTests : public DawnTest {

-  protected:

-    void SetUp() override {

-        DawnTest::SetUp();

-    }

-

-    constexpr static uint32_t kSize = 128;

-};

-

-// Test that texture clears to 1's because toggle is enabled.

-TEST_P(NonzeroTextureCreationTests, TextureCreationClearsOneBits) {

-    dawn::TextureDescriptor descriptor;

-    descriptor.dimension = dawn::TextureDimension::e2D;

-    descriptor.size.width = kSize;

-    descriptor.size.height = kSize;

-    descriptor.size.depth = 1;

-    descriptor.arrayLayerCount = 1;

-    descriptor.sampleCount = 1;

-    descriptor.format = dawn::TextureFormat::RGBA8Unorm;

-    descriptor.mipLevelCount = 1;

-    descriptor.usage = dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::TransferSrc;

-    dawn::Texture texture = device.CreateTexture(&descriptor);

-

-    RGBA8 filledWithOnes(255, 255, 255, 255);

-    EXPECT_PIXEL_RGBA8_EQ(filledWithOnes, texture, 0, 0);

-}

-

-// Test that non-zero mip level clears to 1's because toggle is enabled.

-TEST_P(NonzeroTextureCreationTests, MipMapClears) {

-    constexpr uint32_t mipLevels = 4;

-

-    dawn::TextureDescriptor descriptor;

-    descriptor.dimension = dawn::TextureDimension::e2D;

-    descriptor.size.width = kSize;

-    descriptor.size.height = kSize;

-    descriptor.size.depth = 1;

-    descriptor.arrayLayerCount = 1;

-    descriptor.sampleCount = 1;

-    descriptor.format = dawn::TextureFormat::RGBA8Unorm;

-    descriptor.mipLevelCount = mipLevels;

-    descriptor.usage = dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::TransferSrc;

-    dawn::Texture texture = device.CreateTexture(&descriptor);

-

-    std::vector<RGBA8> expected;

-    RGBA8 filledWithOnes(255, 255, 255, 255);

-    for (uint32_t i = 0; i < kSize * kSize; ++i) {

-        expected.push_back(filledWithOnes);

-    }

-    uint32_t mipSize = kSize >> 2;

-    EXPECT_TEXTURE_RGBA8_EQ(expected.data(), texture, 0, 0, mipSize, mipSize, 2, 0);

-}

-

-// Test that non-zero array layers clears to 1's because toggle is enabled.

-TEST_P(NonzeroTextureCreationTests, ArrayLayerClears) {

-    constexpr uint32_t arrayLayers = 4;

-

-    dawn::TextureDescriptor descriptor;

-    descriptor.dimension = dawn::TextureDimension::e2D;

-    descriptor.size.width = kSize;

-    descriptor.size.height = kSize;

-    descriptor.size.depth = 1;

-    descriptor.arrayLayerCount = arrayLayers;

-    descriptor.sampleCount = 1;

-    descriptor.format = dawn::TextureFormat::RGBA8Unorm;

-    descriptor.mipLevelCount = 1;

-    descriptor.usage = dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::TransferSrc;

-    dawn::Texture texture = device.CreateTexture(&descriptor);

-

-    std::vector<RGBA8> expected;

-    RGBA8 filledWithOnes(255, 255, 255, 255);

-    for (uint32_t i = 0; i < kSize * kSize; ++i) {

-        expected.push_back(filledWithOnes);

-    }

-

-    EXPECT_TEXTURE_RGBA8_EQ(expected.data(), texture, 0, 0, kSize, kSize, 0, 2);

-}

-

-DAWN_INSTANTIATE_TEST(NonzeroTextureCreationTests,

-                      ForceWorkarounds(D3D12Backend,

-                                       {"nonzero_clear_resources_on_creation_for_testing"},

-                                       {"lazy_clear_resource_on_first_use"}),

-                      ForceWorkarounds(OpenGLBackend,

-                                       {"nonzero_clear_resources_on_creation_for_testing"},

-                                       {"lazy_clear_resource_on_first_use"}),

-                      ForceWorkarounds(VulkanBackend,

-                                       {"nonzero_clear_resources_on_creation_for_testing"},

-                                       {"lazy_clear_resource_on_first_use"}));

+// Copyright 2019 The Dawn Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "tests/DawnTest.h"
+
+#include "utils/ComboRenderPipelineDescriptor.h"
+#include "utils/DawnHelpers.h"
+
+class NonzeroTextureCreationTests : public DawnTest {
+  protected:
+    void SetUp() override {
+        DawnTest::SetUp();
+    }
+
+    constexpr static uint32_t kSize = 128;
+};
+
+// Test that texture clears to 1's because toggle is enabled.
+TEST_P(NonzeroTextureCreationTests, TextureCreationClearsOneBits) {
+    dawn::TextureDescriptor descriptor;
+    descriptor.dimension = dawn::TextureDimension::e2D;
+    descriptor.size.width = kSize;
+    descriptor.size.height = kSize;
+    descriptor.size.depth = 1;
+    descriptor.arrayLayerCount = 1;
+    descriptor.sampleCount = 1;
+    descriptor.format = dawn::TextureFormat::RGBA8Unorm;
+    descriptor.mipLevelCount = 1;
+    descriptor.usage = dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::TransferSrc;
+    dawn::Texture texture = device.CreateTexture(&descriptor);
+
+    RGBA8 filledWithOnes(255, 255, 255, 255);
+    EXPECT_PIXEL_RGBA8_EQ(filledWithOnes, texture, 0, 0);
+}
+
+// Test that non-zero mip level clears to 1's because toggle is enabled.
+TEST_P(NonzeroTextureCreationTests, MipMapClears) {
+    constexpr uint32_t mipLevels = 4;
+
+    dawn::TextureDescriptor descriptor;
+    descriptor.dimension = dawn::TextureDimension::e2D;
+    descriptor.size.width = kSize;
+    descriptor.size.height = kSize;
+    descriptor.size.depth = 1;
+    descriptor.arrayLayerCount = 1;
+    descriptor.sampleCount = 1;
+    descriptor.format = dawn::TextureFormat::RGBA8Unorm;
+    descriptor.mipLevelCount = mipLevels;
+    descriptor.usage = dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::TransferSrc;
+    dawn::Texture texture = device.CreateTexture(&descriptor);
+
+    std::vector<RGBA8> expected;
+    RGBA8 filledWithOnes(255, 255, 255, 255);
+    for (uint32_t i = 0; i < kSize * kSize; ++i) {
+        expected.push_back(filledWithOnes);
+    }
+    uint32_t mipSize = kSize >> 2;
+    EXPECT_TEXTURE_RGBA8_EQ(expected.data(), texture, 0, 0, mipSize, mipSize, 2, 0);
+}
+
+// Test that non-zero array layers clears to 1's because toggle is enabled.
+TEST_P(NonzeroTextureCreationTests, ArrayLayerClears) {
+    constexpr uint32_t arrayLayers = 4;
+
+    dawn::TextureDescriptor descriptor;
+    descriptor.dimension = dawn::TextureDimension::e2D;
+    descriptor.size.width = kSize;
+    descriptor.size.height = kSize;
+    descriptor.size.depth = 1;
+    descriptor.arrayLayerCount = arrayLayers;
+    descriptor.sampleCount = 1;
+    descriptor.format = dawn::TextureFormat::RGBA8Unorm;
+    descriptor.mipLevelCount = 1;
+    descriptor.usage = dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::TransferSrc;
+    dawn::Texture texture = device.CreateTexture(&descriptor);
+
+    std::vector<RGBA8> expected;
+    RGBA8 filledWithOnes(255, 255, 255, 255);
+    for (uint32_t i = 0; i < kSize * kSize; ++i) {
+        expected.push_back(filledWithOnes);
+    }
+
+    EXPECT_TEXTURE_RGBA8_EQ(expected.data(), texture, 0, 0, kSize, kSize, 0, 2);
+}
+
+DAWN_INSTANTIATE_TEST(NonzeroTextureCreationTests,
+                      ForceWorkarounds(D3D12Backend,
+                                       {"nonzero_clear_resources_on_creation_for_testing"},
+                                       {"lazy_clear_resource_on_first_use"}),
+                      ForceWorkarounds(OpenGLBackend,
+                                       {"nonzero_clear_resources_on_creation_for_testing"},
+                                       {"lazy_clear_resource_on_first_use"}),
+                      ForceWorkarounds(VulkanBackend,
+                                       {"nonzero_clear_resources_on_creation_for_testing"},
+                                       {"lazy_clear_resource_on_first_use"}));
diff --git a/src/tests/end2end/TextureZeroInitTests.cpp b/src/tests/end2end/TextureZeroInitTests.cpp
index 316d473..f469d05 100644
--- a/src/tests/end2end/TextureZeroInitTests.cpp
+++ b/src/tests/end2end/TextureZeroInitTests.cpp
@@ -1,406 +1,410 @@
-// Copyright 2019 The Dawn Authors

-//

-// Licensed under the Apache License, Version 2.0 (the "License");

-// you may not use this file except in compliance with the License.

-// You may obtain a copy of the License at

-//

-//     http://www.apache.org/licenses/LICENSE-2.0

-//

-// Unless required by applicable law or agreed to in writing, software

-// distributed under the License is distributed on an "AS IS" BASIS,

-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

-// See the License for the specific language governing permissions and

-// limitations under the License.

-

-#include "tests/DawnTest.h"

-

-#include "utils/ComboRenderPipelineDescriptor.h"

-#include "utils/DawnHelpers.h"

-

-class TextureZeroInitTest : public DawnTest {

-  protected:

-    void SetUp() override {

-        DawnTest::SetUp();

-    }

-    dawn::TextureDescriptor CreateTextureDescriptor(uint32_t mipLevelCount,

-                                                    uint32_t arrayLayerCount,

-                                                    dawn::TextureUsageBit usage,

-                                                    dawn::TextureFormat format) {

-        dawn::TextureDescriptor descriptor;

-        descriptor.dimension = dawn::TextureDimension::e2D;

-        descriptor.size.width = kSize;

-        descriptor.size.height = kSize;

-        descriptor.size.depth = 1;

-        descriptor.arrayLayerCount = arrayLayerCount;

-        descriptor.sampleCount = 1;

-        descriptor.format = format;

-        descriptor.mipLevelCount = mipLevelCount;

-        descriptor.usage = usage;

-        return descriptor;

-    }

-    dawn::TextureViewDescriptor CreateTextureViewDescriptor(uint32_t baseMipLevel,

-                                                            uint32_t baseArrayLayer) {

-        dawn::TextureViewDescriptor descriptor;

-        descriptor.format = kColorFormat;

-        descriptor.baseArrayLayer = baseArrayLayer;

-        descriptor.arrayLayerCount = 1;

-        descriptor.baseMipLevel = baseMipLevel;

-        descriptor.mipLevelCount = 1;

-        descriptor.dimension = dawn::TextureViewDimension::e2D;

-        return descriptor;

-    }

-    dawn::RenderPipeline CreatePipelineForTest() {

-        utils::ComboRenderPipelineDescriptor pipelineDescriptor(device);

-        const char* vs =

-            R"(#version 450

-        const vec3 pos[6] = vec3[6](vec3(-1.0f, -1.0f, 0.0f),

-                                    vec3(-1.0f,  1.0f, 0.0f),

-                                    vec3( 1.0f, -1.0f, 0.0f),

-                                    vec3( 1.0f,  1.0f, 0.0f),

-                                    vec3(-1.0f,  1.0f, 0.0f),

-                                    vec3( 1.0f, -1.0f, 0.0f)

-                                    );

-

-        void main() {

-           gl_Position = vec4(pos[gl_VertexIndex], 1.0);

-        })";

-        pipelineDescriptor.cVertexStage.module =

-            utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, vs);

-

-        const char* fs =

-            "#version 450\n"

-            "layout(location = 0) out vec4 fragColor;"

-            "void main() {\n"

-            "   fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"

-            "}\n";

-        pipelineDescriptor.cFragmentStage.module =

-            utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, fs);

-

-        pipelineDescriptor.cDepthStencilState.depthCompare = dawn::CompareFunction::Equal;

-        pipelineDescriptor.cDepthStencilState.stencilFront.compare = dawn::CompareFunction::Equal;

-        pipelineDescriptor.depthStencilState = &pipelineDescriptor.cDepthStencilState;

-

-        return device.CreateRenderPipeline(&pipelineDescriptor);

-    }

-    constexpr static uint32_t kSize = 128;

-    constexpr static dawn::TextureFormat kColorFormat = dawn::TextureFormat::RGBA8Unorm;

-    constexpr static dawn::TextureFormat kDepthStencilFormat =

-        dawn::TextureFormat::Depth24PlusStencil8;

-};

-

-// This tests that the code path of CopyTextureToBuffer clears correctly to Zero after first usage

-TEST_P(TextureZeroInitTest, RecycleTextureMemoryClear) {

-    dawn::TextureDescriptor descriptor = CreateTextureDescriptor(

-        1, 1, dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::TransferSrc,

-        kColorFormat);

-    dawn::Texture texture = device.CreateTexture(&descriptor);

-

-    // Texture's first usage is in EXPECT_PIXEL_RGBA8_EQ's call to CopyTextureToBuffer

-    RGBA8 filledWithZeros(0, 0, 0, 0);

-    EXPECT_PIXEL_RGBA8_EQ(filledWithZeros, texture, 0, 0);

-}

-

-// Test that non-zero mip level clears subresource to Zero after first use

-// This goes through the BeginRenderPass's code path

-TEST_P(TextureZeroInitTest, MipMapClearsToZero) {

-    dawn::TextureDescriptor descriptor = CreateTextureDescriptor(

-        4, 1, dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::TransferSrc,

-        kColorFormat);

-    dawn::Texture texture = device.CreateTexture(&descriptor);

-

-    dawn::TextureViewDescriptor viewDescriptor = CreateTextureViewDescriptor(2, 0);

-    dawn::TextureView view = texture.CreateView(&viewDescriptor);

-

-    utils::BasicRenderPass renderPass = utils::BasicRenderPass(kSize, kSize, texture, kColorFormat);

-

-    renderPass.renderPassInfo.cColorAttachmentsInfoPtr[0]->attachment = view;

-    dawn::CommandEncoder encoder = device.CreateCommandEncoder();

-    {

-        // Texture's first usage is in BeginRenderPass's call to RecordRenderPass

-        dawn::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);

-        pass.EndPass();

-    }

-    dawn::CommandBuffer commands = encoder.Finish();

-    queue.Submit(1, &commands);

-

-    uint32_t mipSize = kSize >> 2;

-    std::vector<RGBA8> expected(mipSize * mipSize, {0, 0, 0, 0});

-

-    EXPECT_TEXTURE_RGBA8_EQ(expected.data(), renderPass.color, 0, 0, mipSize, mipSize, 2, 0);

-}

-

-// Test that non-zero array layers clears subresource to Zero after first use.

-// This goes through the BeginRenderPass's code path

-TEST_P(TextureZeroInitTest, ArrayLayerClearsToZero) {

-    dawn::TextureDescriptor descriptor = CreateTextureDescriptor(

-        1, 4, dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::TransferSrc,

-        kColorFormat);

-    dawn::Texture texture = device.CreateTexture(&descriptor);

-

-    dawn::TextureViewDescriptor viewDescriptor = CreateTextureViewDescriptor(0, 2);

-    dawn::TextureView view = texture.CreateView(&viewDescriptor);

-

-    utils::BasicRenderPass renderPass = utils::BasicRenderPass(kSize, kSize, texture, kColorFormat);

-

-    renderPass.renderPassInfo.cColorAttachmentsInfoPtr[0]->attachment = view;

-    dawn::CommandEncoder encoder = device.CreateCommandEncoder();

-    {

-        dawn::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);

-        pass.EndPass();

-    }

-    dawn::CommandBuffer commands = encoder.Finish();

-    queue.Submit(1, &commands);

-

-    std::vector<RGBA8> expected(kSize * kSize, {0, 0, 0, 0});

-

-    EXPECT_TEXTURE_RGBA8_EQ(expected.data(), renderPass.color, 0, 0, kSize, kSize, 0, 2);

-}

-

-// This tests CopyBufferToTexture fully overwrites copy so lazy init is not needed.

-// TODO(natlee@microsoft.com): Add backdoor to dawn native to query the number of zero-inited

-// subresources

-TEST_P(TextureZeroInitTest, CopyBufferToTexture) {

-    dawn::TextureDescriptor descriptor = CreateTextureDescriptor(

-        4, 1,

-        dawn::TextureUsageBit::TransferDst | dawn::TextureUsageBit::Sampled |

-            dawn::TextureUsageBit::TransferSrc,

-        kColorFormat);

-    dawn::Texture texture = device.CreateTexture(&descriptor);

-

-    std::vector<uint8_t> data(4 * kSize * kSize, 100);

-    dawn::Buffer stagingBuffer = utils::CreateBufferFromData(

-        device, data.data(), static_cast<uint32_t>(data.size()), dawn::BufferUsageBit::TransferSrc);

-    dawn::BufferCopyView bufferCopyView = utils::CreateBufferCopyView(stagingBuffer, 0, 0, 0);

-    dawn::TextureCopyView textureCopyView = utils::CreateTextureCopyView(texture, 0, 0, {0, 0, 0});

-    dawn::Extent3D copySize = {kSize, kSize, 1};

-    dawn::CommandEncoder encoder = device.CreateCommandEncoder();

-    encoder.CopyBufferToTexture(&bufferCopyView, &textureCopyView, &copySize);

-    dawn::CommandBuffer commands = encoder.Finish();

-    queue.Submit(1, &commands);

-

-    std::vector<RGBA8> expected(kSize * kSize, {100, 100, 100, 100});

-

-    EXPECT_TEXTURE_RGBA8_EQ(expected.data(), texture, 0, 0, kSize, kSize, 0, 0);

-}

-

-// Test for a copy only to a subset of the subresource, lazy init is necessary to clear the other

-// half.

-TEST_P(TextureZeroInitTest, CopyBufferToTextureHalf) {

-    dawn::TextureDescriptor descriptor = CreateTextureDescriptor(

-        4, 1,

-        dawn::TextureUsageBit::TransferDst | dawn::TextureUsageBit::Sampled |

-            dawn::TextureUsageBit::TransferSrc,

-        kColorFormat);

-    dawn::Texture texture = device.CreateTexture(&descriptor);

-

-    std::vector<uint8_t> data(4 * kSize * kSize, 100);

-    dawn::Buffer stagingBuffer = utils::CreateBufferFromData(

-        device, data.data(), static_cast<uint32_t>(data.size()), dawn::BufferUsageBit::TransferSrc);

-    dawn::BufferCopyView bufferCopyView = utils::CreateBufferCopyView(stagingBuffer, 0, 0, 0);

-    dawn::TextureCopyView textureCopyView = utils::CreateTextureCopyView(texture, 0, 0, {0, 0, 0});

-    dawn::Extent3D copySize = {kSize / 2, kSize, 1};

-    dawn::CommandEncoder encoder = device.CreateCommandEncoder();

-    encoder.CopyBufferToTexture(&bufferCopyView, &textureCopyView, &copySize);

-    dawn::CommandBuffer commands = encoder.Finish();

-    queue.Submit(1, &commands);

-

-    std::vector<RGBA8> expected100((kSize / 2) * kSize, {100, 100, 100, 100});

-    std::vector<RGBA8> expectedZeros((kSize / 2) * kSize, {0, 0, 0, 0});

-    // first half filled with 100, by the buffer data

-    EXPECT_TEXTURE_RGBA8_EQ(expected100.data(), texture, 0, 0, kSize / 2, kSize, 0, 0);

-    // second half should be cleared

-    EXPECT_TEXTURE_RGBA8_EQ(expectedZeros.data(), texture, kSize / 2, 0, kSize / 2, kSize, 0, 0);

-}

-

-// This tests CopyTextureToTexture fully overwrites copy so lazy init is not needed.

-TEST_P(TextureZeroInitTest, CopyTextureToTexture) {

-    dawn::TextureDescriptor srcDescriptor = CreateTextureDescriptor(

-        1, 1, dawn::TextureUsageBit::Sampled | dawn::TextureUsageBit::TransferSrc, kColorFormat);

-    dawn::Texture srcTexture = device.CreateTexture(&srcDescriptor);

-

-    dawn::TextureCopyView srcTextureCopyView =

-        utils::CreateTextureCopyView(srcTexture, 0, 0, {0, 0, 0});

-

-    dawn::TextureDescriptor dstDescriptor = CreateTextureDescriptor(

-        1, 1,

-        dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::TransferDst |

-            dawn::TextureUsageBit::TransferSrc,

-        kColorFormat);

-    dawn::Texture dstTexture = device.CreateTexture(&dstDescriptor);

-

-    dawn::TextureCopyView dstTextureCopyView =

-        utils::CreateTextureCopyView(dstTexture, 0, 0, {0, 0, 0});

-

-    dawn::Extent3D copySize = {kSize, kSize, 1};

-

-    dawn::CommandEncoder encoder = device.CreateCommandEncoder();

-    encoder.CopyTextureToTexture(&srcTextureCopyView, &dstTextureCopyView, &copySize);

-    dawn::CommandBuffer commands = encoder.Finish();

-    queue.Submit(1, &commands);

-

-    std::vector<RGBA8> expected(kSize * kSize, {0, 0, 0, 0});

-

-    EXPECT_TEXTURE_RGBA8_EQ(expected.data(), srcTexture, 0, 0, kSize, kSize, 0, 0);

-    EXPECT_TEXTURE_RGBA8_EQ(expected.data(), dstTexture, 0, 0, kSize, kSize, 0, 0);

-}

-

-// This Tests the CopyTextureToTexture's copy only to a subset of the subresource, lazy init is

-// necessary to clear the other half.

-TEST_P(TextureZeroInitTest, CopyTextureToTextureHalf) {

-    dawn::TextureDescriptor srcDescriptor = CreateTextureDescriptor(

-        1, 1,

-        dawn::TextureUsageBit::Sampled | dawn::TextureUsageBit::TransferSrc |

-            dawn::TextureUsageBit::TransferDst,

-        kColorFormat);

-    dawn::Texture srcTexture = device.CreateTexture(&srcDescriptor);

-

-    // fill srcTexture with 100

-    {

-        std::vector<uint8_t> data(4 * kSize * kSize, 100);

-        dawn::Buffer stagingBuffer =

-            utils::CreateBufferFromData(device, data.data(), static_cast<uint32_t>(data.size()),

-                                        dawn::BufferUsageBit::TransferSrc);

-        dawn::BufferCopyView bufferCopyView = utils::CreateBufferCopyView(stagingBuffer, 0, 0, 0);

-        dawn::TextureCopyView textureCopyView =

-            utils::CreateTextureCopyView(srcTexture, 0, 0, {0, 0, 0});

-        dawn::Extent3D copySize = {kSize, kSize, 1};

-        dawn::CommandEncoder encoder = device.CreateCommandEncoder();

-        encoder.CopyBufferToTexture(&bufferCopyView, &textureCopyView, &copySize);

-        dawn::CommandBuffer commands = encoder.Finish();

-        queue.Submit(1, &commands);

-    }

-

-    dawn::TextureCopyView srcTextureCopyView =

-        utils::CreateTextureCopyView(srcTexture, 0, 0, {0, 0, 0});

-

-    dawn::TextureDescriptor dstDescriptor = CreateTextureDescriptor(

-        1, 1,

-        dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::TransferDst |

-            dawn::TextureUsageBit::TransferSrc,

-        kColorFormat);

-    dawn::Texture dstTexture = device.CreateTexture(&dstDescriptor);

-

-    dawn::TextureCopyView dstTextureCopyView =

-        utils::CreateTextureCopyView(dstTexture, 0, 0, {0, 0, 0});

-    dawn::Extent3D copySize = {kSize / 2, kSize, 1};

-

-    dawn::CommandEncoder encoder = device.CreateCommandEncoder();

-    encoder.CopyTextureToTexture(&srcTextureCopyView, &dstTextureCopyView, &copySize);

-    dawn::CommandBuffer commands = encoder.Finish();

-    queue.Submit(1, &commands);

-

-    std::vector<RGBA8> expectedWithZeros((kSize / 2) * kSize, {0, 0, 0, 0});

-    std::vector<RGBA8> expectedWith100(kSize * kSize, {100, 100, 100, 100});

-

-    EXPECT_TEXTURE_RGBA8_EQ(expectedWith100.data(), srcTexture, 0, 0, kSize, kSize, 0, 0);

-    EXPECT_TEXTURE_RGBA8_EQ(expectedWith100.data(), dstTexture, 0, 0, kSize / 2, kSize, 0, 0);

-    EXPECT_TEXTURE_RGBA8_EQ(expectedWithZeros.data(), dstTexture, kSize / 2, 0, kSize / 2, kSize, 0,

-                            0);

-}

-

-// This tests the texture with depth attachment and load op load will init depth stencil texture to

-// 0s.

-TEST_P(TextureZeroInitTest, DepthClear) {

-    dawn::TextureDescriptor srcDescriptor = CreateTextureDescriptor(

-        1, 1,

-        dawn::TextureUsageBit::TransferSrc | dawn::TextureUsageBit::TransferDst |

-            dawn::TextureUsageBit::OutputAttachment,

-        kColorFormat);

-    dawn::Texture srcTexture = device.CreateTexture(&srcDescriptor);

-

-    dawn::TextureDescriptor depthStencilDescriptor = CreateTextureDescriptor(

-        1, 1, dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::TransferSrc,

-        kDepthStencilFormat);

-    dawn::Texture depthStencilTexture = device.CreateTexture(&depthStencilDescriptor);

-

-    utils::ComboRenderPassDescriptor renderPassDescriptor({srcTexture.CreateDefaultView()},

-                                                          depthStencilTexture.CreateDefaultView());

-    renderPassDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = dawn::LoadOp::Load;

-    renderPassDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = dawn::LoadOp::Clear;

-    renderPassDescriptor.cDepthStencilAttachmentInfo.clearStencil = 0;

-

-    dawn::CommandEncoder encoder = device.CreateCommandEncoder();

-    auto pass = encoder.BeginRenderPass(&renderPassDescriptor);

-    pass.SetPipeline(CreatePipelineForTest());

-    pass.Draw(6, 1, 0, 0);

-    pass.EndPass();

-    dawn::CommandBuffer commandBuffer = encoder.Finish();

-    queue.Submit(1, &commandBuffer);

-

-    // Expect the texture to be red because depth test passed.

-    std::vector<RGBA8> expected(kSize * kSize, {255, 0, 0, 255});

-    EXPECT_TEXTURE_RGBA8_EQ(expected.data(), srcTexture, 0, 0, kSize, kSize, 0, 0);

-}

-

-// This tests the texture with stencil attachment and load op load will init depth stencil texture

-// to 0s.

-TEST_P(TextureZeroInitTest, StencilClear) {

-    dawn::TextureDescriptor srcDescriptor = CreateTextureDescriptor(

-        1, 1,

-        dawn::TextureUsageBit::TransferSrc | dawn::TextureUsageBit::TransferDst |

-            dawn::TextureUsageBit::OutputAttachment,

-        kColorFormat);

-    dawn::Texture srcTexture = device.CreateTexture(&srcDescriptor);

-

-    dawn::TextureDescriptor depthStencilDescriptor = CreateTextureDescriptor(

-        1, 1, dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::TransferSrc,

-        kDepthStencilFormat);

-    dawn::Texture depthStencilTexture = device.CreateTexture(&depthStencilDescriptor);

-

-    utils::ComboRenderPassDescriptor renderPassDescriptor({srcTexture.CreateDefaultView()},

-                                                          depthStencilTexture.CreateDefaultView());

-    renderPassDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = dawn::LoadOp::Clear;

-    renderPassDescriptor.cDepthStencilAttachmentInfo.clearDepth = 0.0f;

-    renderPassDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = dawn::LoadOp::Load;

-

-    dawn::CommandEncoder encoder = device.CreateCommandEncoder();

-    auto pass = encoder.BeginRenderPass(&renderPassDescriptor);

-    pass.SetPipeline(CreatePipelineForTest());

-    pass.Draw(6, 1, 0, 0);

-    pass.EndPass();

-    dawn::CommandBuffer commandBuffer = encoder.Finish();

-    queue.Submit(1, &commandBuffer);

-

-    // Expect the texture to be red because stencil test passed.

-    std::vector<RGBA8> expected(kSize * kSize, {255, 0, 0, 255});

-    EXPECT_TEXTURE_RGBA8_EQ(expected.data(), srcTexture, 0, 0, kSize, kSize, 0, 0);

-}

-

-// This tests the texture with depth stencil attachment and load op load will init depth stencil

-// texture to 0s.

-TEST_P(TextureZeroInitTest, DepthStencilClear) {

-    dawn::TextureDescriptor srcDescriptor = CreateTextureDescriptor(

-        1, 1,

-        dawn::TextureUsageBit::TransferSrc | dawn::TextureUsageBit::TransferDst |

-            dawn::TextureUsageBit::OutputAttachment,

-        kColorFormat);

-    dawn::Texture srcTexture = device.CreateTexture(&srcDescriptor);

-

-    dawn::TextureDescriptor depthStencilDescriptor = CreateTextureDescriptor(

-        1, 1, dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::TransferSrc,

-        kDepthStencilFormat);

-    dawn::Texture depthStencilTexture = device.CreateTexture(&depthStencilDescriptor);

-

-    utils::ComboRenderPassDescriptor renderPassDescriptor({srcTexture.CreateDefaultView()},

-                                                          depthStencilTexture.CreateDefaultView());

-    renderPassDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = dawn::LoadOp::Load;

-    renderPassDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = dawn::LoadOp::Load;

-

-    dawn::CommandEncoder encoder = device.CreateCommandEncoder();

-    auto pass = encoder.BeginRenderPass(&renderPassDescriptor);

-    pass.SetPipeline(CreatePipelineForTest());

-    pass.Draw(6, 1, 0, 0);

-    pass.EndPass();

-    dawn::CommandBuffer commandBuffer = encoder.Finish();

-    queue.Submit(1, &commandBuffer);

-

-    // Expect the texture to be red because both depth and stencil tests passed.

-    std::vector<RGBA8> expected(kSize * kSize, {255, 0, 0, 255});

-    EXPECT_TEXTURE_RGBA8_EQ(expected.data(), srcTexture, 0, 0, kSize, kSize, 0, 0);

-}

-

-DAWN_INSTANTIATE_TEST(TextureZeroInitTest,

-                      ForceWorkarounds(D3D12Backend,

-                                       {"nonzero_clear_resources_on_creation_for_testing"}),

-                      ForceWorkarounds(VulkanBackend,

-                                       {"nonzero_clear_resources_on_creation_for_testing"}));

+// Copyright 2019 The Dawn Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "tests/DawnTest.h"
+
+#include "utils/ComboRenderPipelineDescriptor.h"
+#include "utils/DawnHelpers.h"
+
+class TextureZeroInitTest : public DawnTest {
+  protected:
+    void SetUp() override {
+        DawnTest::SetUp();
+    }
+    dawn::TextureDescriptor CreateTextureDescriptor(uint32_t mipLevelCount,
+                                                    uint32_t arrayLayerCount,
+                                                    dawn::TextureUsageBit usage,
+                                                    dawn::TextureFormat format) {
+        dawn::TextureDescriptor descriptor;
+        descriptor.dimension = dawn::TextureDimension::e2D;
+        descriptor.size.width = kSize;
+        descriptor.size.height = kSize;
+        descriptor.size.depth = 1;
+        descriptor.arrayLayerCount = arrayLayerCount;
+        descriptor.sampleCount = 1;
+        descriptor.format = format;
+        descriptor.mipLevelCount = mipLevelCount;
+        descriptor.usage = usage;
+        return descriptor;
+    }
+    dawn::TextureViewDescriptor CreateTextureViewDescriptor(uint32_t baseMipLevel,
+                                                            uint32_t baseArrayLayer) {
+        dawn::TextureViewDescriptor descriptor;
+        descriptor.format = kColorFormat;
+        descriptor.baseArrayLayer = baseArrayLayer;
+        descriptor.arrayLayerCount = 1;
+        descriptor.baseMipLevel = baseMipLevel;
+        descriptor.mipLevelCount = 1;
+        descriptor.dimension = dawn::TextureViewDimension::e2D;
+        return descriptor;
+    }
+    dawn::RenderPipeline CreatePipelineForTest() {
+        utils::ComboRenderPipelineDescriptor pipelineDescriptor(device);
+        const char* vs =
+            R"(#version 450
+        const vec2 pos[6] = vec2[6](vec2(-1.0f, -1.0f),
+                                    vec2(-1.0f,  1.0f),
+                                    vec2( 1.0f, -1.0f),
+                                    vec2( 1.0f,  1.0f),
+                                    vec2(-1.0f,  1.0f),
+                                    vec2( 1.0f, -1.0f)
+                                    );
+
+        void main() {
+           gl_Position = vec4(pos[gl_VertexIndex], 0.0, 1.0);
+        })";
+        pipelineDescriptor.cVertexStage.module =
+            utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, vs);
+
+        const char* fs =
+            "#version 450\n"
+            "layout(location = 0) out vec4 fragColor;"
+            "void main() {\n"
+            "   fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
+            "}\n";
+        pipelineDescriptor.cFragmentStage.module =
+            utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, fs);
+
+        pipelineDescriptor.cDepthStencilState.depthCompare = dawn::CompareFunction::Equal;
+        pipelineDescriptor.cDepthStencilState.stencilFront.compare = dawn::CompareFunction::Equal;
+        pipelineDescriptor.depthStencilState = &pipelineDescriptor.cDepthStencilState;
+
+        return device.CreateRenderPipeline(&pipelineDescriptor);
+    }
+    constexpr static uint32_t kSize = 128;
+    constexpr static dawn::TextureFormat kColorFormat = dawn::TextureFormat::RGBA8Unorm;
+    constexpr static dawn::TextureFormat kDepthStencilFormat =
+        dawn::TextureFormat::Depth24PlusStencil8;
+};
+
+// This tests that the code path of CopyTextureToBuffer clears correctly to Zero after first usage
+TEST_P(TextureZeroInitTest, CopyTextureToBufferSource) {
+    dawn::TextureDescriptor descriptor = CreateTextureDescriptor(
+        1, 1, dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::TransferSrc,
+        kColorFormat);
+    dawn::Texture texture = device.CreateTexture(&descriptor);
+
+    // Texture's first usage is in EXPECT_PIXEL_RGBA8_EQ's call to CopyTextureToBuffer
+    RGBA8 filledWithZeros(0, 0, 0, 0);
+    EXPECT_PIXEL_RGBA8_EQ(filledWithZeros, texture, 0, 0);
+}
+
+// Test that non-zero mip level clears subresource to Zero after first use
+// This goes through the BeginRenderPass's code path
+TEST_P(TextureZeroInitTest, RenderingMipMapClearsToZero) {
+    dawn::TextureDescriptor descriptor = CreateTextureDescriptor(
+        4, 1, dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::TransferSrc,
+        kColorFormat);
+    dawn::Texture texture = device.CreateTexture(&descriptor);
+
+    dawn::TextureViewDescriptor viewDescriptor = CreateTextureViewDescriptor(2, 0);
+    dawn::TextureView view = texture.CreateView(&viewDescriptor);
+
+    utils::BasicRenderPass renderPass = utils::BasicRenderPass(kSize, kSize, texture, kColorFormat);
+
+    renderPass.renderPassInfo.cColorAttachmentsInfoPtr[0]->attachment = view;
+    dawn::CommandEncoder encoder = device.CreateCommandEncoder();
+    {
+        // Texture's first usage is in BeginRenderPass's call to RecordRenderPass
+        dawn::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
+        pass.EndPass();
+    }
+    dawn::CommandBuffer commands = encoder.Finish();
+    queue.Submit(1, &commands);
+
+    uint32_t mipSize = kSize >> 2;
+    std::vector<RGBA8> expected(mipSize * mipSize, {0, 0, 0, 0});
+
+    EXPECT_TEXTURE_RGBA8_EQ(expected.data(), renderPass.color, 0, 0, mipSize, mipSize, 2, 0);
+}
+
+// Test that non-zero array layers clears subresource to Zero after first use.
+// This goes through the BeginRenderPass's code path
+TEST_P(TextureZeroInitTest, RenderingArrayLayerClearsToZero) {
+    dawn::TextureDescriptor descriptor = CreateTextureDescriptor(
+        1, 4, dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::TransferSrc,
+        kColorFormat);
+    dawn::Texture texture = device.CreateTexture(&descriptor);
+
+    dawn::TextureViewDescriptor viewDescriptor = CreateTextureViewDescriptor(0, 2);
+    dawn::TextureView view = texture.CreateView(&viewDescriptor);
+
+    utils::BasicRenderPass renderPass = utils::BasicRenderPass(kSize, kSize, texture, kColorFormat);
+
+    renderPass.renderPassInfo.cColorAttachmentsInfoPtr[0]->attachment = view;
+    dawn::CommandEncoder encoder = device.CreateCommandEncoder();
+    {
+        dawn::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
+        pass.EndPass();
+    }
+    dawn::CommandBuffer commands = encoder.Finish();
+    queue.Submit(1, &commands);
+
+    std::vector<RGBA8> expected(kSize * kSize, {0, 0, 0, 0});
+
+    EXPECT_TEXTURE_RGBA8_EQ(expected.data(), renderPass.color, 0, 0, kSize, kSize, 0, 2);
+}
+
+// This tests CopyBufferToTexture fully overwrites copy so lazy init is not needed.
+// TODO(natlee@microsoft.com): Add backdoor to dawn native to query the number of zero-inited
+// subresources
+TEST_P(TextureZeroInitTest, CopyBufferToTexture) {
+    dawn::TextureDescriptor descriptor = CreateTextureDescriptor(
+        4, 1,
+        dawn::TextureUsageBit::TransferDst | dawn::TextureUsageBit::Sampled |
+            dawn::TextureUsageBit::TransferSrc,
+        kColorFormat);
+    dawn::Texture texture = device.CreateTexture(&descriptor);
+
+    std::vector<uint8_t> data(4 * kSize * kSize, 100);
+    dawn::Buffer stagingBuffer = utils::CreateBufferFromData(
+        device, data.data(), static_cast<uint32_t>(data.size()), dawn::BufferUsageBit::TransferSrc);
+
+    dawn::BufferCopyView bufferCopyView = utils::CreateBufferCopyView(stagingBuffer, 0, 0, 0);
+    dawn::TextureCopyView textureCopyView = utils::CreateTextureCopyView(texture, 0, 0, {0, 0, 0});
+    dawn::Extent3D copySize = {kSize, kSize, 1};
+
+    dawn::CommandEncoder encoder = device.CreateCommandEncoder();
+    encoder.CopyBufferToTexture(&bufferCopyView, &textureCopyView, &copySize);
+    dawn::CommandBuffer commands = encoder.Finish();
+    queue.Submit(1, &commands);
+
+    std::vector<RGBA8> expected(kSize * kSize, {100, 100, 100, 100});
+
+    EXPECT_TEXTURE_RGBA8_EQ(expected.data(), texture, 0, 0, kSize, kSize, 0, 0);
+}
+
+// Test for a copy only to a subset of the subresource, lazy init is necessary to clear the other
+// half.
+TEST_P(TextureZeroInitTest, CopyBufferToTextureHalf) {
+    dawn::TextureDescriptor descriptor = CreateTextureDescriptor(
+        4, 1,
+        dawn::TextureUsageBit::TransferDst | dawn::TextureUsageBit::Sampled |
+            dawn::TextureUsageBit::TransferSrc,
+        kColorFormat);
+    dawn::Texture texture = device.CreateTexture(&descriptor);
+
+    std::vector<uint8_t> data(4 * kSize * kSize, 100);
+    dawn::Buffer stagingBuffer = utils::CreateBufferFromData(
+        device, data.data(), static_cast<uint32_t>(data.size()), dawn::BufferUsageBit::TransferSrc);
+
+    dawn::BufferCopyView bufferCopyView = utils::CreateBufferCopyView(stagingBuffer, 0, 0, 0);
+    dawn::TextureCopyView textureCopyView = utils::CreateTextureCopyView(texture, 0, 0, {0, 0, 0});
+    dawn::Extent3D copySize = {kSize / 2, kSize, 1};
+
+    dawn::CommandEncoder encoder = device.CreateCommandEncoder();
+    encoder.CopyBufferToTexture(&bufferCopyView, &textureCopyView, &copySize);
+    dawn::CommandBuffer commands = encoder.Finish();
+    queue.Submit(1, &commands);
+
+    std::vector<RGBA8> expected100((kSize / 2) * kSize, {100, 100, 100, 100});
+    std::vector<RGBA8> expectedZeros((kSize / 2) * kSize, {0, 0, 0, 0});
+    // first half filled with 100, by the buffer data
+    EXPECT_TEXTURE_RGBA8_EQ(expected100.data(), texture, 0, 0, kSize / 2, kSize, 0, 0);
+    // second half should be cleared
+    EXPECT_TEXTURE_RGBA8_EQ(expectedZeros.data(), texture, kSize / 2, 0, kSize / 2, kSize, 0, 0);
+}
+
+// This tests CopyTextureToTexture fully overwrites copy so lazy init is not needed.
+TEST_P(TextureZeroInitTest, CopyTextureToTexture) {
+    dawn::TextureDescriptor srcDescriptor = CreateTextureDescriptor(
+        1, 1, dawn::TextureUsageBit::Sampled | dawn::TextureUsageBit::TransferSrc, kColorFormat);
+    dawn::Texture srcTexture = device.CreateTexture(&srcDescriptor);
+
+    dawn::TextureCopyView srcTextureCopyView =
+        utils::CreateTextureCopyView(srcTexture, 0, 0, {0, 0, 0});
+
+    dawn::TextureDescriptor dstDescriptor = CreateTextureDescriptor(
+        1, 1,
+        dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::TransferDst |
+            dawn::TextureUsageBit::TransferSrc,
+        kColorFormat);
+    dawn::Texture dstTexture = device.CreateTexture(&dstDescriptor);
+
+    dawn::TextureCopyView dstTextureCopyView =
+        utils::CreateTextureCopyView(dstTexture, 0, 0, {0, 0, 0});
+
+    dawn::Extent3D copySize = {kSize, kSize, 1};
+
+    dawn::CommandEncoder encoder = device.CreateCommandEncoder();
+    encoder.CopyTextureToTexture(&srcTextureCopyView, &dstTextureCopyView, &copySize);
+    dawn::CommandBuffer commands = encoder.Finish();
+    queue.Submit(1, &commands);
+
+    std::vector<RGBA8> expected(kSize * kSize, {0, 0, 0, 0});
+
+    EXPECT_TEXTURE_RGBA8_EQ(expected.data(), srcTexture, 0, 0, kSize, kSize, 0, 0);
+    EXPECT_TEXTURE_RGBA8_EQ(expected.data(), dstTexture, 0, 0, kSize, kSize, 0, 0);
+}
+
+// This Tests the CopyTextureToTexture's copy only to a subset of the subresource, lazy init is
+// necessary to clear the other half.
+TEST_P(TextureZeroInitTest, CopyTextureToTextureHalf) {
+    dawn::TextureDescriptor srcDescriptor = CreateTextureDescriptor(
+        1, 1,
+        dawn::TextureUsageBit::Sampled | dawn::TextureUsageBit::TransferSrc |
+            dawn::TextureUsageBit::TransferDst,
+        kColorFormat);
+    dawn::Texture srcTexture = device.CreateTexture(&srcDescriptor);
+
+    // fill srcTexture with 100
+    {
+        std::vector<uint8_t> data(4 * kSize * kSize, 100);
+        dawn::Buffer stagingBuffer =
+            utils::CreateBufferFromData(device, data.data(), static_cast<uint32_t>(data.size()),
+                                        dawn::BufferUsageBit::TransferSrc);
+        dawn::BufferCopyView bufferCopyView = utils::CreateBufferCopyView(stagingBuffer, 0, 0, 0);
+        dawn::TextureCopyView textureCopyView =
+            utils::CreateTextureCopyView(srcTexture, 0, 0, {0, 0, 0});
+        dawn::Extent3D copySize = {kSize, kSize, 1};
+        dawn::CommandEncoder encoder = device.CreateCommandEncoder();
+        encoder.CopyBufferToTexture(&bufferCopyView, &textureCopyView, &copySize);
+        dawn::CommandBuffer commands = encoder.Finish();
+        queue.Submit(1, &commands);
+    }
+
+    dawn::TextureCopyView srcTextureCopyView =
+        utils::CreateTextureCopyView(srcTexture, 0, 0, {0, 0, 0});
+
+    dawn::TextureDescriptor dstDescriptor = CreateTextureDescriptor(
+        1, 1,
+        dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::TransferDst |
+            dawn::TextureUsageBit::TransferSrc,
+        kColorFormat);
+    dawn::Texture dstTexture = device.CreateTexture(&dstDescriptor);
+
+    dawn::TextureCopyView dstTextureCopyView =
+        utils::CreateTextureCopyView(dstTexture, 0, 0, {0, 0, 0});
+    dawn::Extent3D copySize = {kSize / 2, kSize, 1};
+
+    dawn::CommandEncoder encoder = device.CreateCommandEncoder();
+    encoder.CopyTextureToTexture(&srcTextureCopyView, &dstTextureCopyView, &copySize);
+    dawn::CommandBuffer commands = encoder.Finish();
+    queue.Submit(1, &commands);
+
+    std::vector<RGBA8> expectedWithZeros((kSize / 2) * kSize, {0, 0, 0, 0});
+    std::vector<RGBA8> expectedWith100(kSize * kSize, {100, 100, 100, 100});
+
+    EXPECT_TEXTURE_RGBA8_EQ(expectedWith100.data(), srcTexture, 0, 0, kSize, kSize, 0, 0);
+    EXPECT_TEXTURE_RGBA8_EQ(expectedWith100.data(), dstTexture, 0, 0, kSize / 2, kSize, 0, 0);
+    EXPECT_TEXTURE_RGBA8_EQ(expectedWithZeros.data(), dstTexture, kSize / 2, 0, kSize / 2, kSize, 0,
+                            0);
+}
+
+// This tests the texture with depth attachment and load op load will init depth stencil texture to
+// 0s.
+TEST_P(TextureZeroInitTest, RenderingLoadingDepth) {
+    dawn::TextureDescriptor srcDescriptor = CreateTextureDescriptor(
+        1, 1,
+        dawn::TextureUsageBit::TransferSrc | dawn::TextureUsageBit::TransferDst |
+            dawn::TextureUsageBit::OutputAttachment,
+        kColorFormat);
+    dawn::Texture srcTexture = device.CreateTexture(&srcDescriptor);
+
+    dawn::TextureDescriptor depthStencilDescriptor = CreateTextureDescriptor(
+        1, 1, dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::TransferSrc,
+        kDepthStencilFormat);
+    dawn::Texture depthStencilTexture = device.CreateTexture(&depthStencilDescriptor);
+
+    utils::ComboRenderPassDescriptor renderPassDescriptor({srcTexture.CreateDefaultView()},
+                                                          depthStencilTexture.CreateDefaultView());
+    renderPassDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = dawn::LoadOp::Load;
+    renderPassDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = dawn::LoadOp::Clear;
+    renderPassDescriptor.cDepthStencilAttachmentInfo.clearStencil = 0;
+
+    dawn::CommandEncoder encoder = device.CreateCommandEncoder();
+    auto pass = encoder.BeginRenderPass(&renderPassDescriptor);
+    pass.SetPipeline(CreatePipelineForTest());
+    pass.Draw(6, 1, 0, 0);
+    pass.EndPass();
+    dawn::CommandBuffer commandBuffer = encoder.Finish();
+    queue.Submit(1, &commandBuffer);
+
+    // Expect the texture to be red because depth test passed.
+    std::vector<RGBA8> expected(kSize * kSize, {255, 0, 0, 255});
+    EXPECT_TEXTURE_RGBA8_EQ(expected.data(), srcTexture, 0, 0, kSize, kSize, 0, 0);
+}
+
+// This tests the texture with stencil attachment and load op load will init depth stencil texture
+// to 0s.
+TEST_P(TextureZeroInitTest, RenderingLoadingStencil) {
+    dawn::TextureDescriptor srcDescriptor = CreateTextureDescriptor(
+        1, 1,
+        dawn::TextureUsageBit::TransferSrc | dawn::TextureUsageBit::TransferDst |
+            dawn::TextureUsageBit::OutputAttachment,
+        kColorFormat);
+    dawn::Texture srcTexture = device.CreateTexture(&srcDescriptor);
+
+    dawn::TextureDescriptor depthStencilDescriptor = CreateTextureDescriptor(
+        1, 1, dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::TransferSrc,
+        kDepthStencilFormat);
+    dawn::Texture depthStencilTexture = device.CreateTexture(&depthStencilDescriptor);
+
+    utils::ComboRenderPassDescriptor renderPassDescriptor({srcTexture.CreateDefaultView()},
+                                                          depthStencilTexture.CreateDefaultView());
+    renderPassDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = dawn::LoadOp::Clear;
+    renderPassDescriptor.cDepthStencilAttachmentInfo.clearDepth = 0.0f;
+    renderPassDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = dawn::LoadOp::Load;
+
+    dawn::CommandEncoder encoder = device.CreateCommandEncoder();
+    auto pass = encoder.BeginRenderPass(&renderPassDescriptor);
+    pass.SetPipeline(CreatePipelineForTest());
+    pass.Draw(6, 1, 0, 0);
+    pass.EndPass();
+    dawn::CommandBuffer commandBuffer = encoder.Finish();
+    queue.Submit(1, &commandBuffer);
+
+    // Expect the texture to be red because stencil test passed.
+    std::vector<RGBA8> expected(kSize * kSize, {255, 0, 0, 255});
+    EXPECT_TEXTURE_RGBA8_EQ(expected.data(), srcTexture, 0, 0, kSize, kSize, 0, 0);
+}
+
+// This tests the texture with depth stencil attachment and load op load will init depth stencil
+// texture to 0s.
+TEST_P(TextureZeroInitTest, RenderingLoadingDepthStencil) {
+    dawn::TextureDescriptor srcDescriptor = CreateTextureDescriptor(
+        1, 1,
+        dawn::TextureUsageBit::TransferSrc | dawn::TextureUsageBit::TransferDst |
+            dawn::TextureUsageBit::OutputAttachment,
+        kColorFormat);
+    dawn::Texture srcTexture = device.CreateTexture(&srcDescriptor);
+
+    dawn::TextureDescriptor depthStencilDescriptor = CreateTextureDescriptor(
+        1, 1, dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::TransferSrc,
+        kDepthStencilFormat);
+    dawn::Texture depthStencilTexture = device.CreateTexture(&depthStencilDescriptor);
+
+    utils::ComboRenderPassDescriptor renderPassDescriptor({srcTexture.CreateDefaultView()},
+                                                          depthStencilTexture.CreateDefaultView());
+    renderPassDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = dawn::LoadOp::Load;
+    renderPassDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = dawn::LoadOp::Load;
+
+    dawn::CommandEncoder encoder = device.CreateCommandEncoder();
+    auto pass = encoder.BeginRenderPass(&renderPassDescriptor);
+    pass.SetPipeline(CreatePipelineForTest());
+    pass.Draw(6, 1, 0, 0);
+    pass.EndPass();
+    dawn::CommandBuffer commandBuffer = encoder.Finish();
+    queue.Submit(1, &commandBuffer);
+
+    // Expect the texture to be red because both depth and stencil tests passed.
+    std::vector<RGBA8> expected(kSize * kSize, {255, 0, 0, 255});
+    EXPECT_TEXTURE_RGBA8_EQ(expected.data(), srcTexture, 0, 0, kSize, kSize, 0, 0);
+}
+
+DAWN_INSTANTIATE_TEST(TextureZeroInitTest,
+                      ForceWorkarounds(D3D12Backend,
+                                       {"nonzero_clear_resources_on_creation_for_testing"}),
+                      ForceWorkarounds(VulkanBackend,
+                                       {"nonzero_clear_resources_on_creation_for_testing"}));