Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 367a1e360d4242e3f5f31bec7c4cbca0da6458b9
      
https://github.com/WebKit/WebKit/commit/367a1e360d4242e3f5f31bec7c4cbca0da6458b9
  Author: Kimmo Kinnunen <[email protected]>
  Date:   2026-06-02 (Tue, 02 Jun 2026)

  Changed paths:
    M Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/ContextMtl.mm
    M Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/DisplayMtl.h
    M Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/DisplayMtl.mm
    M Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/FrameBufferMtl.h
    M Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/FrameBufferMtl.mm
    M 
Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/gen_mtl_format_table.py
    M Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_common.h
    M 
Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_format_table_autogen.mm
    M Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_format_utils.h
    M Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_format_utils.mm
    M Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_pipeline_cache.mm
    M Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_utils.h
    M Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_utils.mm
    M Source/ThirdParty/ANGLE/src/tests/gl_tests/DrawBuffersTest.cpp

  Log Message:
  -----------
  ANGLE: Metal: Crash when clearing too many large pixels on iOS
https://bugs.webkit.org/show_bug.cgi?id=315651
rdar://178037647

Reviewed by Dan Glastonbury.

Fix bugs in handing render pass total pixel size limits:
 - Depth, stencil render attachments were part of the pixel size
   calculations, even though they should not be.
 - GL framebuffer completeness was incorrectly calculated based
   on the the color bitsizes of the attached attachments. The
   color bit sizes do not define the renderability, rather the
   underlying format.
 - If the framebuffer would be incorrectly validated as complete,
   draw could fail due to too big pixel size. In these cases
   a encoder nullptr dereference would occur.

OpenGL ES has following related limits:
 - MAX_COLOR_ATTACHMENTS -- how many attachments can be attached to FBO
 - MAX_DRAW_BUFFERS -- how many buffers can be rendered to
 - glDrawBuffers -- which buffers are being rendered to

Not all framebuffers are complete -- only those framebuffers are
complete that are renderable with all buffers
enabled.

Metal has following related limits:
 - Maximum number of color render targets per render
   pass descriptor
 - Maximum number of color bytes written per render pass

On macOS, the Mac2 GPU families have no limits. The smallest GPU (M1) is
Apple7, but also supports Mac2.
On iOS, the limit is 32 (Apple2, 3), 64 bytes (Apple4, 5, 6), 128 bytes
(Apple7+)

Thus framebuffers that do not fit into 32 or 64 bytes on respective
iOS GPUs are not complete. All GL formats fit to 128 bytes with
8 attachments (8 attachments, 4 components, 4 bytes per component).

The change 311827@main would update pixel format sizes from zeros to the
actual sizes. The sizes were used to calculate whether a render pass is
usable. Before the 311827@main, the render pass size calculation was not
effective due to zero sizes and thus the tests completed. After, the
tests would crash on ClearTest.ClearMaxAttachments on simulator because
of the MAX_DRAW_BUFFERS (8) * sizeof RGBA8 + sizeof stencil/depth
exceeded the simulator max 32.

There would be existing bugs related to iOS format sizes not being
adjusted. Especially the simulator has unexpectedly large sizes
for some emulated formats. These were not exercised by the tests.

Fix by:
 - Remove accounting of depth, stencil to the render attachment pixel
   size. Only account the color attachments.
 - Fix the checking of the color attachment sizes for framebuffer
   completeness. Check based on the actual Metal pixel format.
 - Fix the nullptr deref when the draw fails due to too many bytes
   per pixel being drawn.
 - Adjust the sizes for iOS pixel formats.

Adds DrawBuffersAnyFormatTestES3 suite which iterates exhaustively all
pixel formats to render to and tests a test similar to
ClearTestES3.ClearMaxAttachmentsAfterDraw, ClearMaxAttachments.

* Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/ContextMtl.mm:
(rx::ContextMtl::getRenderPassCommandEncoder):
* Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/DisplayMtl.h:
(rx::DisplayMtl::getLibraryCache):
(rx::DisplayMtl::getMaxColorTargetBits): Deleted.
* Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/DisplayMtl.mm:
(rx::DisplayMtl::ensureCapsInitialized const):
* Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/FrameBufferMtl.h:
* Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/FrameBufferMtl.mm:
(rx::FramebufferMtl::checkStatus const):
(rx::FramebufferMtl::ensureRenderPassStarted):
(rx::FramebufferMtl::totalBitsUsedIsLessThanOrEqualToMaxBitsSupported const): 
Deleted.
* Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/gen_mtl_format_table.py:
* Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_common.h:
* 
Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_format_table_autogen.mm:
(rx::mtl::FormatTable::initNativeFormatCapsAutogen):
* Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_format_utils.h:
* Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_format_utils.mm:
(rx::mtl::FormatTable::adjustFormatCapsForDevice):
* Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_pipeline_cache.mm:
* Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_utils.h:
* Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_utils.mm:
(rx::mtl::GetMaxRenderTargetSizeForDeviceInBytes):
(rx::mtl::ComputeTotalSizeUsedForMTLRenderPassDescriptor):
(rx::mtl::ComputeTotalSizeUsedForMTLRenderPipelineDescriptor):
(rx::mtl::GetMaxRenderPassColorSizeBytes):
* Source/ThirdParty/ANGLE/src/tests/gl_tests/DrawBuffersTest.cpp:

Canonical link: https://commits.webkit.org/314388@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to