diff --git a/src/dawn_native/vulkan/CommandBufferVk.cpp b/src/dawn_native/vulkan/CommandBufferVk.cpp index e36676f713..f200e2b110 100644 --- a/src/dawn_native/vulkan/CommandBufferVk.cpp +++ b/src/dawn_native/vulkan/CommandBufferVk.cpp @@ -169,24 +169,43 @@ namespace dawn_native { namespace vulkan { RenderPassCacheQuery query; for (uint32_t i : IterateBitSet(renderPass->colorAttachmentsSet)) { - const auto& attachmentInfo = renderPass->colorAttachments[i]; + auto& attachmentInfo = renderPass->colorAttachments[i]; + TextureView* view = ToBackend(attachmentInfo.view.Get()); bool hasResolveTarget = attachmentInfo.resolveTarget.Get() != nullptr; dawn::LoadOp loadOp = attachmentInfo.loadOp; - if (loadOp == dawn::LoadOp::Load && attachmentInfo.view->GetTexture() && - !attachmentInfo.view->GetTexture()->IsSubresourceContentInitialized( - attachmentInfo.view->GetBaseMipLevel(), 1, - attachmentInfo.view->GetBaseArrayLayer(), 1)) { + ASSERT(view->GetLayerCount() == 1); + ASSERT(view->GetLevelCount() == 1); + if (loadOp == dawn::LoadOp::Load && view->GetTexture() && + !view->GetTexture()->IsSubresourceContentInitialized( + view->GetBaseMipLevel(), 1, view->GetBaseArrayLayer(), 1)) { loadOp = dawn::LoadOp::Clear; } + switch (attachmentInfo.storeOp) { + case dawn::StoreOp::Store: { + view->GetTexture()->SetIsSubresourceContentInitialized( + view->GetBaseMipLevel(), 1, view->GetBaseArrayLayer(), 1); + } break; + + default: { UNREACHABLE(); } break; + } query.SetColor(i, attachmentInfo.view->GetFormat(), loadOp, hasResolveTarget); } if (renderPass->hasDepthStencilAttachment) { - const auto& attachmentInfo = renderPass->depthStencilAttachment; + auto& attachmentInfo = renderPass->depthStencilAttachment; query.SetDepthStencil(attachmentInfo.view->GetTexture()->GetFormat(), attachmentInfo.depthLoadOp, attachmentInfo.stencilLoadOp); + if (attachmentInfo.depthLoadOp == dawn::LoadOp::Load || + attachmentInfo.stencilLoadOp == dawn::LoadOp::Load) { + ToBackend(attachmentInfo.view->GetTexture()) + ->EnsureSubresourceContentInitialized( + commands, attachmentInfo.view->GetBaseMipLevel(), + attachmentInfo.view->GetLevelCount(), + attachmentInfo.view->GetBaseArrayLayer(), + attachmentInfo.view->GetLayerCount()); + } } query.SetSampleCount(renderPass->sampleCount); @@ -553,20 +572,6 @@ namespace dawn_native { namespace vulkan { case Command::EndRenderPass: { mCommands.NextCommand(); device->fn.CmdEndRenderPass(commands); - for (uint32_t i : IterateBitSet(renderPassCmd->colorAttachmentsSet)) { - auto& attachmentInfo = renderPassCmd->colorAttachments[i]; - TextureView* view = ToBackend(attachmentInfo.view.Get()); - switch (attachmentInfo.storeOp) { - case dawn::StoreOp::Store: { - attachmentInfo.view->GetTexture() - ->SetIsSubresourceContentInitialized( - view->GetBaseMipLevel(), view->GetLevelCount(), - view->GetBaseArrayLayer(), view->GetLayerCount()); - } break; - - default: { UNREACHABLE(); } break; - } - } return; } break; diff --git a/src/dawn_native/vulkan/TextureVk.cpp b/src/dawn_native/vulkan/TextureVk.cpp index 263cd860c4..cbd7644531 100644 --- a/src/dawn_native/vulkan/TextureVk.cpp +++ b/src/dawn_native/vulkan/TextureVk.cpp @@ -331,16 +331,27 @@ namespace dawn_native { namespace vulkan { range.levelCount = GetNumMipLevels(); range.baseArrayLayer = 0; range.layerCount = GetArrayLayers(); - - // TODO(natlee@microsoft.com): use correct union member depending on the texture format - VkClearColorValue clear_color = {{1.0, 1.0, 1.0, 1.0}}; - TransitionUsageNow(ToBackend(GetDevice())->GetPendingCommandBuffer(), dawn::TextureUsageBit::TransferDst); - ToBackend(GetDevice()) - ->fn.CmdClearColorImage(ToBackend(GetDevice())->GetPendingCommandBuffer(), - GetHandle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - &clear_color, 1, &range); + + if (TextureFormatHasDepthOrStencil(GetFormat())) { + VkClearDepthStencilValue clear_color[1]; + clear_color[0].depth = 1.0f; + clear_color[0].stencil = 1u; + ToBackend(GetDevice()) + ->fn.CmdClearDepthStencilImage( + ToBackend(GetDevice())->GetPendingCommandBuffer(), GetHandle(), + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, clear_color, 1, &range); + } else { + // TODO(natlee@microsoft.com): use correct union member depending on the texture + // format + VkClearColorValue clear_color = {{1.0, 1.0, 1.0, 1.0}}; + + ToBackend(GetDevice()) + ->fn.CmdClearColorImage(ToBackend(GetDevice())->GetPendingCommandBuffer(), + GetHandle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + &clear_color, 1, &range); + } } } @@ -420,37 +431,33 @@ namespace dawn_native { namespace vulkan { uint32_t levelCount, uint32_t baseArrayLayer, uint32_t layerCount) { - if (GetDevice()->IsToggleEnabled(Toggle::LazyClearResourceOnFirstUse)) { - VkImageSubresourceRange range = {}; - range.aspectMask = GetVkAspectMask(); - range.baseMipLevel = baseMipLevel; - range.levelCount = levelCount; - range.baseArrayLayer = baseArrayLayer; - range.layerCount = layerCount; + VkImageSubresourceRange range = {}; + range.aspectMask = GetVkAspectMask(); + range.baseMipLevel = baseMipLevel; + range.levelCount = levelCount; + range.baseArrayLayer = baseArrayLayer; + range.layerCount = layerCount; - TransitionUsageNow(commands, dawn::TextureUsageBit::TransferDst); - if (TextureFormatHasDepthOrStencil(GetFormat())) { - VkClearDepthStencilValue clear_color[1]; - clear_color[0].depth = 0.0f; - clear_color[0].stencil = 0u; - ToBackend(GetDevice()) - ->fn.CmdClearDepthStencilImage(commands, GetHandle(), - VulkanImageLayout(GetUsage(), GetFormat()), - clear_color, 1, &range); - } else { - VkClearColorValue clear_color[1]; - clear_color[0].float32[0] = 0.0f; - clear_color[0].float32[1] = 0.0f; - clear_color[0].float32[2] = 0.0f; - clear_color[0].float32[3] = 0.0f; - ToBackend(GetDevice()) - ->fn.CmdClearColorImage(commands, GetHandle(), - VulkanImageLayout(GetUsage(), GetFormat()), clear_color, - 1, &range); - } - SetIsSubresourceContentInitialized(baseMipLevel, levelCount, baseArrayLayer, - layerCount); + TransitionUsageNow(commands, dawn::TextureUsageBit::TransferDst); + if (TextureFormatHasDepthOrStencil(GetFormat())) { + VkClearDepthStencilValue clear_color[1]; + clear_color[0].depth = 0.0f; + clear_color[0].stencil = 0u; + ToBackend(GetDevice()) + ->fn.CmdClearDepthStencilImage(commands, GetHandle(), + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, clear_color, 1, + &range); + } else { + VkClearColorValue clear_color[1]; + clear_color[0].float32[0] = 0.0f; + clear_color[0].float32[1] = 0.0f; + clear_color[0].float32[2] = 0.0f; + clear_color[0].float32[3] = 0.0f; + ToBackend(GetDevice()) + ->fn.CmdClearColorImage(commands, GetHandle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + clear_color, 1, &range); } + SetIsSubresourceContentInitialized(baseMipLevel, levelCount, baseArrayLayer, layerCount); } void Texture::EnsureSubresourceContentInitialized(VkCommandBuffer commands, @@ -458,6 +465,9 @@ namespace dawn_native { namespace vulkan { uint32_t levelCount, uint32_t baseArrayLayer, uint32_t layerCount) { + if (!GetDevice()->IsToggleEnabled(Toggle::LazyClearResourceOnFirstUse)) { + return; + } if (!IsSubresourceContentInitialized(baseMipLevel, levelCount, baseArrayLayer, layerCount)) { // If subresource has not been initialized, clear it to black as it could contain dirty diff --git a/src/tests/end2end/TextureZeroInitTests.cpp b/src/tests/end2end/TextureZeroInitTests.cpp index df72ba7909..7b530f4339 100644 --- a/src/tests/end2end/TextureZeroInitTests.cpp +++ b/src/tests/end2end/TextureZeroInitTests.cpp @@ -24,7 +24,8 @@ class TextureZeroInitTest : public DawnTest { } dawn::TextureDescriptor CreateTextureDescriptor(uint32_t mipLevelCount, uint32_t arrayLayerCount, - dawn::TextureUsageBit usage) { + dawn::TextureUsageBit usage, + dawn::TextureFormat format) { dawn::TextureDescriptor descriptor; descriptor.dimension = dawn::TextureDimension::e2D; descriptor.size.width = kSize; @@ -32,7 +33,7 @@ class TextureZeroInitTest : public DawnTest { descriptor.size.depth = 1; descriptor.arrayLayerCount = arrayLayerCount; descriptor.sampleCount = 1; - descriptor.format = dawn::TextureFormat::RGBA8Unorm; + descriptor.format = format; descriptor.mipLevelCount = mipLevelCount; descriptor.usage = usage; return descriptor; @@ -40,7 +41,7 @@ class TextureZeroInitTest : public DawnTest { dawn::TextureViewDescriptor CreateTextureViewDescriptor(uint32_t baseMipLevel, uint32_t baseArrayLayer) { dawn::TextureViewDescriptor descriptor; - descriptor.format = dawn::TextureFormat::RGBA8Unorm; + descriptor.format = kColorFormat; descriptor.baseArrayLayer = baseArrayLayer; descriptor.arrayLayerCount = 1; descriptor.baseMipLevel = baseMipLevel; @@ -48,13 +49,50 @@ class TextureZeroInitTest : public DawnTest { 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); + 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 @@ -66,14 +104,14 @@ TEST_P(TextureZeroInitTest, RecycleTextureMemoryClear) { // This goes through the BeginRenderPass's code path TEST_P(TextureZeroInitTest, MipMapClearsToZero) { dawn::TextureDescriptor descriptor = CreateTextureDescriptor( - 4, 1, dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::TransferSrc); + 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, dawn::TextureFormat::RGBA8Unorm); + utils::BasicRenderPass renderPass = utils::BasicRenderPass(kSize, kSize, texture, kColorFormat); renderPass.renderPassInfo.cColorAttachmentsInfoPtr[0]->attachment = view; dawn::CommandEncoder encoder = device.CreateCommandEncoder(); @@ -95,14 +133,14 @@ TEST_P(TextureZeroInitTest, MipMapClearsToZero) { // This goes through the BeginRenderPass's code path TEST_P(TextureZeroInitTest, ArrayLayerClearsToZero) { dawn::TextureDescriptor descriptor = CreateTextureDescriptor( - 1, 4, dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::TransferSrc); + 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, dawn::TextureFormat::RGBA8Unorm); + utils::BasicRenderPass renderPass = utils::BasicRenderPass(kSize, kSize, texture, kColorFormat); renderPass.renderPassInfo.cColorAttachmentsInfoPtr[0]->attachment = view; dawn::CommandEncoder encoder = device.CreateCommandEncoder(); @@ -125,7 +163,8 @@ TEST_P(TextureZeroInitTest, CopyBufferToTexture) { dawn::TextureDescriptor descriptor = CreateTextureDescriptor( 4, 1, dawn::TextureUsageBit::TransferDst | dawn::TextureUsageBit::Sampled | - dawn::TextureUsageBit::TransferSrc); + dawn::TextureUsageBit::TransferSrc, + kColorFormat); dawn::Texture texture = device.CreateTexture(&descriptor); std::vector data(4 * kSize * kSize, 100); @@ -150,7 +189,8 @@ TEST_P(TextureZeroInitTest, CopyBufferToTextureHalf) { dawn::TextureDescriptor descriptor = CreateTextureDescriptor( 4, 1, dawn::TextureUsageBit::TransferDst | dawn::TextureUsageBit::Sampled | - dawn::TextureUsageBit::TransferSrc); + dawn::TextureUsageBit::TransferSrc, + kColorFormat); dawn::Texture texture = device.CreateTexture(&descriptor); std::vector data(4 * kSize * kSize, 100); @@ -175,7 +215,7 @@ TEST_P(TextureZeroInitTest, CopyBufferToTextureHalf) { // 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); + 1, 1, dawn::TextureUsageBit::Sampled | dawn::TextureUsageBit::TransferSrc, kColorFormat); dawn::Texture srcTexture = device.CreateTexture(&srcDescriptor); dawn::TextureCopyView srcTextureCopyView = @@ -184,7 +224,8 @@ TEST_P(TextureZeroInitTest, CopyTextureToTexture) { dawn::TextureDescriptor dstDescriptor = CreateTextureDescriptor( 1, 1, dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::TransferDst | - dawn::TextureUsageBit::TransferSrc); + dawn::TextureUsageBit::TransferSrc, + kColorFormat); dawn::Texture dstTexture = device.CreateTexture(&dstDescriptor); dawn::TextureCopyView dstTextureCopyView = @@ -209,7 +250,8 @@ TEST_P(TextureZeroInitTest, CopyTextureToTextureHalf) { dawn::TextureDescriptor srcDescriptor = CreateTextureDescriptor( 1, 1, dawn::TextureUsageBit::Sampled | dawn::TextureUsageBit::TransferSrc | - dawn::TextureUsageBit::TransferDst); + dawn::TextureUsageBit::TransferDst, + kColorFormat); dawn::Texture srcTexture = device.CreateTexture(&srcDescriptor); // fill srcTexture with 100 @@ -234,7 +276,8 @@ TEST_P(TextureZeroInitTest, CopyTextureToTextureHalf) { dawn::TextureDescriptor dstDescriptor = CreateTextureDescriptor( 1, 1, dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::TransferDst | - dawn::TextureUsageBit::TransferSrc); + dawn::TextureUsageBit::TransferSrc, + kColorFormat); dawn::Texture dstTexture = device.CreateTexture(&dstDescriptor); dawn::TextureCopyView dstTextureCopyView = @@ -255,6 +298,107 @@ TEST_P(TextureZeroInitTest, CopyTextureToTextureHalf) { 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 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 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 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(VulkanBackend, {"nonzero_clear_resources_on_creation_for_testing"}));