From bd8de5d2a4855b6d0c7e9f8383ccc14024bfd91b Mon Sep 17 00:00:00 2001 From: Corentin Wallez Date: Thu, 28 Apr 2022 19:00:53 +0000 Subject: [PATCH] Add MetalRenderR8RG8UnormSmallMipToTempTexture workaround This workaround replaces the toggle that forbids creating mipmapped R8Unorm and RG8Unorm textures on Metal. Instead it adds a Metal render pass workaround that renders to a temporary texture under certain conditions, then copies back to the correct mip level. The texture lazy-clearing code is also changed to use the helper that does workarounds for Metal render passes. A test is added that triggers the issue with a small amount of code, but more extensive coverage is left to the CTS. For example texture_zero tests caught multiple issues during the creation of this CL. Bug: dawn:1071 Change-Id: I7ef1151524e71e5a9a8e8f5205d9b554bee438b3 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/87864 Commit-Queue: Corentin Wallez Reviewed-by: Austin Eng Kokoro: Kokoro --- src/dawn/native/Texture.cpp | 7 - src/dawn/native/Toggles.cpp | 14 +- src/dawn/native/Toggles.h | 2 +- src/dawn/native/metal/DeviceMTL.mm | 6 +- src/dawn/native/metal/TextureMTL.mm | 14 +- src/dawn/native/metal/UtilsMetal.h | 5 + src/dawn/native/metal/UtilsMetal.mm | 262 +++++++++++++++------ src/dawn/tests/end2end/RenderPassTests.cpp | 60 +++++ webgpu-cts/expectations.txt | 25 -- 9 files changed, 272 insertions(+), 123 deletions(-) diff --git a/src/dawn/native/Texture.cpp b/src/dawn/native/Texture.cpp index 75b3c0c522..eb3b021d8a 100644 --- a/src/dawn/native/Texture.cpp +++ b/src/dawn/native/Texture.cpp @@ -394,13 +394,6 @@ namespace dawn::native { "https://crbug.com/dawn/838: Stencil textures with more than one mip level are " "disabled on Metal."); - DAWN_INVALID_IF( - device->IsToggleEnabled(Toggle::DisableR8RG8Mipmaps) && descriptor->mipLevelCount > 1 && - (descriptor->format == wgpu::TextureFormat::R8Unorm || - descriptor->format == wgpu::TextureFormat::RG8Unorm), - "https://crbug.com/dawn/1071: r8unorm and rg8unorm textures with more than one mip " - "level are disabled on Metal."); - return {}; } diff --git a/src/dawn/native/Toggles.cpp b/src/dawn/native/Toggles.cpp index b1932141aa..8f229703f1 100644 --- a/src/dawn/native/Toggles.cpp +++ b/src/dawn/native/Toggles.cpp @@ -231,11 +231,6 @@ namespace dawn::native { "Enables calls to SetLabel to be forwarded to backend-specific APIs that label " "objects.", "https://crbug.com/dawn/840"}}, - {Toggle::DisableR8RG8Mipmaps, - {"disable_r8_rg8_mipmaps", - "Disables mipmaps for r8unorm and rg8unorm textures, which are known on some drivers " - "to not clear correctly.", - "https://crbug.com/dawn/1071"}}, {Toggle::UsePlaceholderFragmentInVertexOnlyPipeline, {"use_placeholder_fragment_in_vertex_only_pipeline", "Use a placeholder empty fragment shader in vertex only render pipeline. This toggle " @@ -272,7 +267,14 @@ namespace dawn::native { "it via split the copy operation into two copies, in order to make B2T/T2B copy " "being done correctly on D3D12.", "https://crbug.com/dawn/1289"}}, - + {Toggle::MetalRenderR8RG8UnormSmallMipToTempTexture, + {"metal_render_r8_rg8_unorm_small_mip_to_temp_texture", + "Metal Intel devices have issues with r8unorm and rg8unorm textures where rendering " + "to small mips (level >= 2) doesn't work correctly. Workaround this issue by " + "detecting this case and rendering to a temporary texture instead (with copies " + "before " + "and after if needed).", + "https://crbug.com/dawn/1071"}}, // Comment to separate the }} so it is clearer what to copy-paste to add a toggle. }}; } // anonymous namespace diff --git a/src/dawn/native/Toggles.h b/src/dawn/native/Toggles.h index 988a991569..0b47221d51 100644 --- a/src/dawn/native/Toggles.h +++ b/src/dawn/native/Toggles.h @@ -62,13 +62,13 @@ namespace dawn::native { DisableWorkgroupInit, DisableSymbolRenaming, UseUserDefinedLabelsInBackend, - DisableR8RG8Mipmaps, UsePlaceholderFragmentInVertexOnlyPipeline, FxcOptimizations, RecordDetailedTimingInTraceEvents, DisableTimestampQueryConversion, VulkanUseZeroInitializeWorkgroupMemoryExtension, D3D12SplitBufferTextureCopyForRowsPerImagePaddings, + MetalRenderR8RG8UnormSmallMipToTempTexture, EnumCount, InvalidEnum = EnumCount, diff --git a/src/dawn/native/metal/DeviceMTL.mm b/src/dawn/native/metal/DeviceMTL.mm index fdff8a05c2..fd8bf74abe 100644 --- a/src/dawn/native/metal/DeviceMTL.mm +++ b/src/dawn/native/metal/DeviceMTL.mm @@ -210,10 +210,10 @@ namespace dawn::native::metal { SetToggle(Toggle::MetalUseSharedModeForCounterSampleBuffer, useSharedMode); } - // TODO(crbug.com/dawn/1071): r8unorm and rg8unorm textures with multiple mip levels don't - // clear properly on Intel Macs. + // Rendering R8Unorm and RG8Unorm to small mip doesn't work properly on Intel. + // TODO(crbug.com/dawn/1071): Tighten the workaround when this issue is fixed. if (gpu_info::IsIntel(vendorId)) { - SetToggle(Toggle::DisableR8RG8Mipmaps, true); + SetToggle(Toggle::MetalRenderR8RG8UnormSmallMipToTempTexture, true); } // On some Intel GPU vertex only render pipeline get wrong depth result if no fragment diff --git a/src/dawn/native/metal/TextureMTL.mm b/src/dawn/native/metal/TextureMTL.mm index 7f0e13c25b..98c5fdb5d5 100644 --- a/src/dawn/native/metal/TextureMTL.mm +++ b/src/dawn/native/metal/TextureMTL.mm @@ -875,8 +875,8 @@ namespace dawn::native::metal { } } - commandContext->BeginRender(descriptor); - commandContext->EndRender(); + DAWN_TRY(EncodeEmptyMetalRenderPass(device, commandContext, descriptor, + GetMipLevelVirtualSize(level))); } } } else { @@ -923,16 +923,18 @@ namespace dawn::native::metal { if (attachment == kMaxColorAttachments) { attachment = 0; - commandContext->BeginRender(descriptor.Get()); - commandContext->EndRender(); + DAWN_TRY(EncodeEmptyMetalRenderPass(device, commandContext, + descriptor.Get(), + GetMipLevelVirtualSize(level))); descriptor = nullptr; } } } if (descriptor != nullptr) { - commandContext->BeginRender(descriptor.Get()); - commandContext->EndRender(); + DAWN_TRY(EncodeEmptyMetalRenderPass(device, commandContext, + descriptor.Get(), + GetMipLevelVirtualSize(level))); } } } diff --git a/src/dawn/native/metal/UtilsMetal.h b/src/dawn/native/metal/UtilsMetal.h index 5b71d73a4b..438d848277 100644 --- a/src/dawn/native/metal/UtilsMetal.h +++ b/src/dawn/native/metal/UtilsMetal.h @@ -102,6 +102,11 @@ namespace dawn::native::metal { uint32_t height, EncodeInsideRenderPass encodeInside); + MaybeError EncodeEmptyMetalRenderPass(Device* device, + CommandRecordingContext* commandContext, + MTLRenderPassDescriptor* mtlRenderPass, + Extent3D size); + } // namespace dawn::native::metal #endif // SRC_DAWN_NATIVE_METAL_UTILSMETAL_H_ diff --git a/src/dawn/native/metal/UtilsMetal.mm b/src/dawn/native/metal/UtilsMetal.mm index 505f5a0517..5c35d35bcd 100644 --- a/src/dawn/native/metal/UtilsMetal.mm +++ b/src/dawn/native/metal/UtilsMetal.mm @@ -13,15 +13,126 @@ // limitations under the License. #include "dawn/native/metal/UtilsMetal.h" + +#include "dawn/common/Assert.h" #include "dawn/native/CommandBuffer.h" #include "dawn/native/Pipeline.h" #include "dawn/native/ShaderModule.h" -#include "dawn/common/Assert.h" - namespace dawn::native::metal { namespace { + // A helper struct to track state while doing workarounds for Metal render passes. It + // contains a temporary texture and information about the attachment it replaces. + // Helper methods encode copies between the two textures. + struct SavedMetalAttachment { + id texture = nil; + NSUInteger level; + NSUInteger slice; + + NSPRef> temporary; + + void CopyFromTemporaryToAttachment(CommandRecordingContext* commandContext) { + [commandContext->EnsureBlit() + copyFromTexture:temporary.Get() + sourceSlice:0 + sourceLevel:0 + sourceOrigin:MTLOriginMake(0, 0, 0) + sourceSize:MTLSizeMake([temporary.Get() width], [temporary.Get() height], + 1) + toTexture:texture + destinationSlice:slice + destinationLevel:level + destinationOrigin:MTLOriginMake(0, 0, 0)]; + } + + void CopyFromAttachmentToTemporary(CommandRecordingContext* commandContext) { + [commandContext->EnsureBlit() + copyFromTexture:texture + sourceSlice:slice + sourceLevel:level + sourceOrigin:MTLOriginMake(0, 0, 0) + sourceSize:MTLSizeMake([temporary.Get() width], [temporary.Get() height], + 1) + toTexture:temporary.Get() + destinationSlice:0 + destinationLevel:0 + destinationOrigin:MTLOriginMake(0, 0, 0)]; + } + }; + + // Common code between both kinds of attachments swaps. + ResultOrError SaveAttachmentCreateTemporary( + Device* device, + id attachmentTexture, + NSUInteger attachmentLevel, + NSUInteger attachmentSlice) { + // Save the attachment. + SavedMetalAttachment result; + result.texture = attachmentTexture; + result.level = attachmentLevel; + result.slice = attachmentSlice; + + // Create the temporary texture. + NSRef mtlDescRef = AcquireNSRef([MTLTextureDescriptor new]); + MTLTextureDescriptor* mtlDesc = mtlDescRef.Get(); + + mtlDesc.textureType = MTLTextureType2D; + mtlDesc.usage = MTLTextureUsageRenderTarget; + mtlDesc.pixelFormat = [result.texture pixelFormat]; + mtlDesc.width = std::max([result.texture width] >> attachmentLevel, NSUInteger(1)); + mtlDesc.height = std::max([result.texture height] >> attachmentLevel, NSUInteger(1)); + mtlDesc.depth = 1; + mtlDesc.mipmapLevelCount = 1; + mtlDesc.arrayLength = 1; + mtlDesc.storageMode = MTLStorageModePrivate; + mtlDesc.sampleCount = [result.texture sampleCount]; + + result.temporary = + AcquireNSPRef([device->GetMTLDevice() newTextureWithDescriptor:mtlDesc]); + if (result.temporary == nil) { + return DAWN_OUT_OF_MEMORY_ERROR("Allocation of temporary texture failed."); + } + + return result; + } + + // Patches the render pass attachment to replace it with a temporary texture. Returns a + // SavedMetalAttachment that can be used to easily copy between the original attachment and + // the temporary. + ResultOrError PatchAttachmentWithTemporary( + Device* device, + MTLRenderPassAttachmentDescriptor* attachment) { + SavedMetalAttachment result; + DAWN_TRY_ASSIGN( + result, SaveAttachmentCreateTemporary(device, attachment.texture, attachment.level, + attachment.slice)); + + // Replace the attachment with the temporary + attachment.texture = result.temporary.Get(); + attachment.level = 0; + attachment.slice = 0; + + return result; + } + + // Same as PatchAttachmentWithTemporary but for the resolve attachment. + ResultOrError PatchResolveAttachmentWithTemporary( + Device* device, + MTLRenderPassAttachmentDescriptor* attachment) { + SavedMetalAttachment result; + DAWN_TRY_ASSIGN(result, SaveAttachmentCreateTemporary(device, attachment.resolveTexture, + attachment.resolveLevel, + attachment.resolveSlice)); + + // Replace the resolve attachment with the tempoary. + attachment.resolveTexture = result.temporary.Get(); + attachment.resolveLevel = 0; + attachment.resolveSlice = 0; + + return result; + } + // Helper function for Toggle EmulateStoreAndMSAAResolve void ResolveInAnotherRenderPass( CommandRecordingContext* commandContext, @@ -52,52 +163,6 @@ namespace dawn::native::metal { commandContext->BeginRender(mtlRenderPassForResolve); commandContext->EndRender(); } - - // Helper functions for Toggle AlwaysResolveIntoZeroLevelAndLayer - ResultOrError>> CreateResolveTextureForWorkaround( - Device* device, - MTLPixelFormat mtlFormat, - uint32_t width, - uint32_t height) { - NSRef mtlDescRef = AcquireNSRef([MTLTextureDescriptor new]); - MTLTextureDescriptor* mtlDesc = mtlDescRef.Get(); - - mtlDesc.textureType = MTLTextureType2D; - mtlDesc.usage = MTLTextureUsageRenderTarget; - mtlDesc.pixelFormat = mtlFormat; - mtlDesc.width = width; - mtlDesc.height = height; - mtlDesc.depth = 1; - mtlDesc.mipmapLevelCount = 1; - mtlDesc.arrayLength = 1; - mtlDesc.storageMode = MTLStorageModePrivate; - mtlDesc.sampleCount = 1; - - id texture = [device->GetMTLDevice() newTextureWithDescriptor:mtlDesc]; - if (texture == nil) { - return DAWN_OUT_OF_MEMORY_ERROR("Allocation of temporary texture failed."); - } - - return AcquireNSPRef(texture); - } - - void CopyIntoTrueResolveTarget(CommandRecordingContext* commandContext, - id mtlTrueResolveTexture, - uint32_t trueResolveLevel, - uint32_t trueResolveSlice, - id temporaryResolveTexture, - uint32_t width, - uint32_t height) { - [commandContext->EnsureBlit() copyFromTexture:temporaryResolveTexture - sourceSlice:0 - sourceLevel:0 - sourceOrigin:MTLOriginMake(0, 0, 0) - sourceSize:MTLSizeMake(width, height, 1) - toTexture:mtlTrueResolveTexture - destinationSlice:trueResolveSlice - destinationLevel:trueResolveLevel - destinationOrigin:MTLOriginMake(0, 0, 0)]; - } } // anonymous namespace MTLCompareFunction ToMetalCompareFunction(wgpu::CompareFunction compareFunction) { @@ -370,18 +435,16 @@ namespace dawn::native::metal { uint32_t width, uint32_t height, EncodeInsideRenderPass encodeInside) { + // This function handles multiple workarounds. Because some cases requires multiple + // workarounds to happen at the same time, it handles workarounds one by one and calls + // itself recursively to handle the next workaround if needed. + // Handle Toggle AlwaysResolveIntoZeroLevelAndLayer. We must handle this before applying // the store + MSAA resolve workaround, otherwise this toggle will never be handled because // the resolve texture is removed when applying the store + MSAA resolve workaround. if (device->IsToggleEnabled(Toggle::AlwaysResolveIntoZeroLevelAndLayer)) { - std::array, kMaxColorAttachments> trueResolveTextures = {}; - std::array trueResolveLevels = {}; - std::array trueResolveSlices = {}; - - // Use temporary resolve texture on the resolve targets with non-zero resolveLevel or - // resolveSlice. - bool useTemporaryResolveTexture = false; - std::array>, kMaxColorAttachments> temporaryResolveTextures = {}; + std::array trueResolveAttachments = {}; + bool workaroundUsed = false; for (uint32_t i = 0; i < kMaxColorAttachments; ++i) { if (mtlRenderPass.colorAttachments[i].resolveTexture == nullptr) { continue; @@ -392,42 +455,80 @@ namespace dawn::native::metal { continue; } - trueResolveTextures[i] = mtlRenderPass.colorAttachments[i].resolveTexture; - trueResolveLevels[i] = mtlRenderPass.colorAttachments[i].resolveLevel; - trueResolveSlices[i] = mtlRenderPass.colorAttachments[i].resolveSlice; - - const MTLPixelFormat mtlFormat = trueResolveTextures[i].pixelFormat; - DAWN_TRY_ASSIGN(temporaryResolveTextures[i], CreateResolveTextureForWorkaround( - device, mtlFormat, width, height)); - - mtlRenderPass.colorAttachments[i].resolveTexture = - temporaryResolveTextures[i].Get(); - mtlRenderPass.colorAttachments[i].resolveLevel = 0; - mtlRenderPass.colorAttachments[i].resolveSlice = 0; - useTemporaryResolveTexture = true; + DAWN_TRY_ASSIGN( + trueResolveAttachments[i], + PatchResolveAttachmentWithTemporary(device, mtlRenderPass.colorAttachments[i])); + workaroundUsed = true; } // If we need to use a temporary resolve texture we need to copy the result of MSAA // resolve back to the true resolve targets. - if (useTemporaryResolveTexture) { + if (workaroundUsed) { DAWN_TRY(EncodeMetalRenderPass(device, commandContext, mtlRenderPass, width, height, std::move(encodeInside))); for (uint32_t i = 0; i < kMaxColorAttachments; ++i) { - if (trueResolveTextures[i] == nullptr) { + if (trueResolveAttachments[i].texture == nullptr) { continue; } - ASSERT(temporaryResolveTextures[i] != nullptr); - CopyIntoTrueResolveTarget(commandContext, trueResolveTextures[i], - trueResolveLevels[i], trueResolveSlices[i], - temporaryResolveTextures[i].Get(), width, height); + trueResolveAttachments[i].CopyFromTemporaryToAttachment(commandContext); + } + return {}; + } + } + + // Handles the workaround for r8unorm rg8unorm mipmap rendering being broken on some + // devices. Render to a temporary texture instead and then copy back to the attachment. + if (device->IsToggleEnabled(Toggle::MetalRenderR8RG8UnormSmallMipToTempTexture)) { + std::array originalAttachments; + bool workaroundUsed = false; + + for (uint32_t i = 0; i < kMaxColorAttachments; ++i) { + if (mtlRenderPass.colorAttachments[i].texture == nullptr) { + continue; + } + + if ([mtlRenderPass.colorAttachments[i].texture pixelFormat] != + MTLPixelFormatR8Unorm && + [mtlRenderPass.colorAttachments[i].texture pixelFormat] != + MTLPixelFormatRG8Unorm) { + continue; + } + + if (mtlRenderPass.colorAttachments[i].level < 2) { + continue; + } + + DAWN_TRY_ASSIGN( + originalAttachments[i], + PatchAttachmentWithTemporary(device, mtlRenderPass.colorAttachments[i])); + workaroundUsed = true; + + if (mtlRenderPass.colorAttachments[i].loadAction == MTLLoadActionLoad) { + originalAttachments[i].CopyFromAttachmentToTemporary(commandContext); + } + } + + if (workaroundUsed) { + DAWN_TRY(EncodeMetalRenderPass(device, commandContext, mtlRenderPass, width, height, + std::move(encodeInside))); + + for (uint32_t i = 0; i < kMaxColorAttachments; ++i) { + if (originalAttachments[i].texture == nullptr) { + continue; + } + + originalAttachments[i].CopyFromTemporaryToAttachment(commandContext); } return {}; } } // Handle Store + MSAA resolve workaround (Toggle EmulateStoreAndMSAAResolve). + // Done after the workarounds that modify the non-resolve attachments so that + // ResolveInAnotherRenderPass uses the temporary attachments if needed instead of the + // original ones. if (device->IsToggleEnabled(Toggle::EmulateStoreAndMSAAResolve)) { bool hasStoreAndMSAAResolve = false; @@ -454,8 +555,19 @@ namespace dawn::native::metal { } } + // No (more) workarounds needed! We can finally encode the actual render pass. + commandContext->EndBlit(); DAWN_TRY(encodeInside(commandContext->BeginRender(mtlRenderPass))); commandContext->EndRender(); return {}; } + + MaybeError EncodeEmptyMetalRenderPass(Device* device, + CommandRecordingContext* commandContext, + MTLRenderPassDescriptor* mtlRenderPass, + Extent3D size) { + return EncodeMetalRenderPass(device, commandContext, mtlRenderPass, size.width, size.height, + [&](id) -> MaybeError { return {}; }); + } + } // namespace dawn::native::metal diff --git a/src/dawn/tests/end2end/RenderPassTests.cpp b/src/dawn/tests/end2end/RenderPassTests.cpp index 85d39c0a48..adf093e24b 100644 --- a/src/dawn/tests/end2end/RenderPassTests.cpp +++ b/src/dawn/tests/end2end/RenderPassTests.cpp @@ -163,6 +163,8 @@ TEST_P(RenderPassTest, NoCorrespondingFragmentShaderOutputs) { EXPECT_PIXEL_RGBA8_EQ(RGBA8::kRed, renderTarget, kRTSize - 1, 1); } +class RenderPassTest_RegressionDawn1071 : public RenderPassTest {}; + DAWN_INSTANTIATE_TEST(RenderPassTest, D3D12Backend(), D3D12Backend({}, {"use_d3d12_render_pass"}), @@ -170,3 +172,61 @@ DAWN_INSTANTIATE_TEST(RenderPassTest, OpenGLBackend(), OpenGLESBackend(), VulkanBackend()); + +// Test that clearing the lower mips of an R8Unorm texture works. This is a regression test for +// dawn:1071 where Intel Metal devices fail to do that correctly, requiring a workaround. +TEST_P(RenderPassTest_RegressionDawn1071, ClearLowestMipOfR8Unorm) { + const uint32_t kLastMipLevel = 2; + + // Create the texture and buffer used for readback. + wgpu::TextureDescriptor texDesc; + texDesc.format = wgpu::TextureFormat::R8Unorm; + texDesc.usage = wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc; + texDesc.size = {32, 32}; + texDesc.mipLevelCount = kLastMipLevel + 1; + wgpu::Texture tex = device.CreateTexture(&texDesc); + + wgpu::BufferDescriptor bufDesc; + bufDesc.size = 4; + bufDesc.usage = wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::CopySrc; + wgpu::Buffer buf = device.CreateBuffer(&bufDesc); + + wgpu::CommandEncoder encoder = device.CreateCommandEncoder(); + + // Clear the texture with a render pass. + { + wgpu::TextureViewDescriptor viewDesc; + viewDesc.baseMipLevel = kLastMipLevel; + + utils::ComboRenderPassDescriptor renderPass({tex.CreateView(&viewDesc)}); + renderPass.cColorAttachments[0].clearValue = {1.0f, 0.0f, 0.0f, 1.0f}; + renderPass.cColorAttachments[0].loadOp = wgpu::LoadOp::Clear; + renderPass.cColorAttachments[0].storeOp = wgpu::StoreOp::Store; + wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass); + pass.End(); + } + + // Copy the texture in the buffer. + { + wgpu::Extent3D copySize = {1, 1}; + wgpu::ImageCopyTexture src = utils::CreateImageCopyTexture(tex, kLastMipLevel); + wgpu::ImageCopyBuffer dst = utils::CreateImageCopyBuffer(buf); + + encoder.CopyTextureToBuffer(&src, &dst, ©Size); + } + + wgpu::CommandBuffer commands = encoder.Finish(); + queue.Submit(1, &commands); + + // The content of the texture should be reflected in the buffer (prior to the workaround it + // would be 0s). + EXPECT_BUFFER_U8_EQ(255, buf, 0); +} + +DAWN_INSTANTIATE_TEST(RenderPassTest_RegressionDawn1071, + D3D12Backend(), + MetalBackend(), + MetalBackend({"metal_render_r8_rg8_unorm_small_mip_to_temp_texture"}), + OpenGLBackend(), + OpenGLESBackend(), + VulkanBackend()); diff --git a/webgpu-cts/expectations.txt b/webgpu-cts/expectations.txt index c2025d285e..65736c3912 100644 --- a/webgpu-cts/expectations.txt +++ b/webgpu-cts/expectations.txt @@ -77,13 +77,6 @@ crbug.com/dawn/1111 [ intel-0x5912 ] webgpu:shader,execution,zero_init:compute,z crbug.com/dawn/1111 [ intel-0x5912 ] webgpu:shader,execution,zero_init:compute,zero_init:storageClass="workgroup";workgroupSize=[7,7,3];batch__=1 [ Failure ] crbug.com/dawn/1111 [ intel-0x5912 ] webgpu:shader,execution,zero_init:compute,zero_init:storageClass="workgroup";workgroupSize=[8,8,2];batch__=1 [ Failure ] -################################################################################ -# webgpu:api,operation,command_buffer,image_copy:mip_levels -# Partial failures on all platforms -# KEEP -################################################################################ -crbug.com/dawn/0000 webgpu:api,operation,command_buffer,image_copy:mip_levels:* [ Failure ] - ################################################################################ # webgpu:api,operation,resource_init,texture_zero:uninitialized_texture_is_zero # Spec / CTS bugs because depth24unorm-stencil8 depth-specific format is depth24plus @@ -112,18 +105,6 @@ crbug.com/dawn/1389 [ mac ] webgpu:api,operation,resource_init,texture_zero:unin crbug.com/dawn/1389 [ mac ] webgpu:api,operation,resource_init,texture_zero:uninitialized_texture_is_zero:dimension="2d";readMethod="CopyToBuffer";format="stencil8" [ Failure ] crbug.com/dawn/1389 [ mac ] webgpu:api,operation,resource_init,texture_zero:uninitialized_texture_is_zero:dimension="2d";readMethod="CopyToTexture";format="stencil8" [ Failure ] crbug.com/dawn/1389 [ mac ] webgpu:api,operation,resource_init,texture_zero:uninitialized_texture_is_zero:dimension="2d";readMethod="StencilTest";format="stencil8" [ Failure ] -crbug.com/dawn/1071 [ mac ] webgpu:api,operation,resource_init,texture_zero:uninitialized_texture_is_zero:dimension="2d";readMethod="CopyToBuffer";format="r8unorm" [ Failure ] -crbug.com/dawn/1071 [ mac ] webgpu:api,operation,resource_init,texture_zero:uninitialized_texture_is_zero:dimension="2d";readMethod="CopyToTexture";format="r8unorm" [ Failure ] -crbug.com/dawn/1071 [ mac ] webgpu:api,operation,resource_init,texture_zero:uninitialized_texture_is_zero:dimension="2d";readMethod="Sample";format="r8unorm" [ Failure ] -crbug.com/dawn/1071 [ mac ] webgpu:api,operation,resource_init,texture_zero:uninitialized_texture_is_zero:dimension="2d";readMethod="CopyToBuffer";format="rg8unorm" [ Failure ] -crbug.com/dawn/1071 [ mac ] webgpu:api,operation,resource_init,texture_zero:uninitialized_texture_is_zero:dimension="2d";readMethod="CopyToTexture";format="rg8unorm" [ Failure ] -crbug.com/dawn/1071 [ mac ] webgpu:api,operation,resource_init,texture_zero:uninitialized_texture_is_zero:dimension="2d";readMethod="Sample";format="rg8unorm" [ Failure ] -crbug.com/dawn/1071 [ mac ] webgpu:api,operation,resource_init,texture_zero:uninitialized_texture_is_zero:dimension="3d";readMethod="CopyToBuffer";format="r8unorm" [ Failure ] -crbug.com/dawn/1071 [ mac ] webgpu:api,operation,resource_init,texture_zero:uninitialized_texture_is_zero:dimension="3d";readMethod="CopyToTexture";format="r8unorm" [ Failure ] -crbug.com/dawn/1071 [ mac ] webgpu:api,operation,resource_init,texture_zero:uninitialized_texture_is_zero:dimension="3d";readMethod="Sample";format="r8unorm" [ Failure ] -crbug.com/dawn/1071 [ mac ] webgpu:api,operation,resource_init,texture_zero:uninitialized_texture_is_zero:dimension="3d";readMethod="CopyToBuffer";format="rg8unorm" [ Failure ] -crbug.com/dawn/1071 [ mac ] webgpu:api,operation,resource_init,texture_zero:uninitialized_texture_is_zero:dimension="3d";readMethod="CopyToTexture";format="rg8unorm" [ Failure ] -crbug.com/dawn/1071 [ mac ] webgpu:api,operation,resource_init,texture_zero:uninitialized_texture_is_zero:dimension="3d";readMethod="Sample";format="rg8unorm" [ Failure ] ################################################################################ # webgpu:api,operation,resource_init,texture_zero:uninitialized_texture_is_zero @@ -355,18 +336,12 @@ crbug.com/dawn/1325 webgpu:api,validation,attachment_compatibility:render_pass_o ################################################################################ crbug.com/dawn/0000 [ mac ] webgpu:api,operation,command_buffer,copyTextureToTexture:copy_depth_stencil:format="depth32float" [ Failure ] crbug.com/dawn/0000 [ win ] webgpu:api,operation,render_pass,resolve:* [ Failure ] -crbug.com/dawn/0000 [ mac ] webgpu:api,operation,render_pass,storeOp:render_pass_store_op,color_attachment_only:colorFormat="r8unorm";* [ Failure ] -crbug.com/dawn/0000 [ mac ] webgpu:api,operation,render_pass,storeOp:render_pass_store_op,color_attachment_only:colorFormat="rg8unorm";* [ Failure ] crbug.com/dawn/0000 [ win ] webgpu:api,operation,render_pipeline,pipeline_output_targets:color,component_count,blend:format="rg8unorm" [ Failure ] crbug.com/dawn/0000 [ win ] webgpu:shader,execution,robust_access_vertex:vertex_buffer_access:indexed=true;indirect=true;drawCallTestParameter="baseVertex";* [ Failure ] crbug.com/1236130 [ linux ] webgpu:web_platform,canvas,readbackFromWebGPUCanvas:* [ Skip ] # crashes (skip because there are very many) crbug.com/dawn/0000 [ mac ] webgpu:web_platform,canvas,readbackFromWebGPUCanvas:* [ Failure ] crbug.com/1309194 [ linux ] webgpu:web_platform,copyToTexture,canvas:copy_contents_from_2d_context_canvas:* [ Skip ] # crashes (skip because there are very many) crbug.com/1309194 [ linux ] webgpu:web_platform,copyToTexture,canvas:copy_contents_from_gl_context_canvas:* [ Skip ] # crashes (skip because there are very many) -crbug.com/dawn/0000 [ mac ] worker_webgpu:api,operation,render_pass,storeOp:render_pass_store_op,color_attachment_only:colorFormat="r8unorm";storeOperation="discard" [ Failure ] -crbug.com/dawn/0000 [ mac ] worker_webgpu:api,operation,render_pass,storeOp:render_pass_store_op,color_attachment_only:colorFormat="r8unorm";storeOperation="store" [ Failure ] -crbug.com/dawn/0000 [ mac ] worker_webgpu:api,operation,render_pass,storeOp:render_pass_store_op,color_attachment_only:colorFormat="rg8unorm";storeOperation="discard" [ Failure ] -crbug.com/dawn/0000 [ mac ] worker_webgpu:api,operation,render_pass,storeOp:render_pass_store_op,color_attachment_only:colorFormat="rg8unorm";storeOperation="store" [ Failure ] crbug.com/dawn/0000 [ mac ] worker_webgpu:api,operation,render_pass,storeOp:render_pass_store_op,depth_stencil_attachment_only:depthStencilFormat="stencil8";* [ Failure ] ################################################################################