Help us improve
Share bugs, ideas, or general feedback.
From game-porting-skills
Creates and manages Metal 4 GPU resources: buffers, textures, heaps, residency sets, purgeable state, texture view pools, and deferred destruction.
npx claudepluginhub apple/game-porting-toolkit --plugin game-porting-skillsHow this skill is triggered — by the user, by Claude, or both
Slash command
/game-porting-skills:managing-metal4-resourcesThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Metal 4 requires explicit residency management via `MTLResidencySet`, removes managed storage mode, and uses GPU addresses for resource binding. Command buffers do NOT retain resources — you must manage lifetimes. All Apple Silicon uses unified memory (CPU and GPU share the same physical memory pool) and Tile-Based Deferred Rendering (TBDR).
Translates graphics code to Metal 4 with cross-API mappings from Metal 3, D3D12, or Vulkan, and covers Apple GPU TBDR architecture.
Supports iOS app development: writes Swift/SwiftUI/UIKit code, architects apps, debugs crashes, handles navigation/networking/persistence/animations/performance, configures Xcode/App Store.
Creates p5.js generative art with seeded randomness, noise fields, and interactive parameter exploration. Use for algorithmic art, flow fields, or particle systems.
Share bugs, ideas, or general feedback.
Metal 4 requires explicit residency management via MTLResidencySet, removes managed storage mode, and uses GPU addresses for resource binding. Command buffers do NOT retain resources — you must manage lifetimes. All Apple Silicon uses unified memory (CPU and GPU share the same physical memory pool) and Tile-Based Deferred Rendering (TBDR).
Owns:
MTLResidencySet semantics — kernel/userspace, attachment levels, validation rules, deferred destructionDoesn't own:
translating-to-metal4-api/references/tbdr-architecture.mdCAMetalLayer.residencySet (read-only specialization) → presenting-metal-drawablesMTL4VisibilityOptions) → managing-metal4-synchronizationmanaging-metal4-synchronizationNS::SharedPtr / autorelease pool / ARC bridging → managing-metal-cpp-lifetimestranslating-to-metal4-apiRead the relevant Metal SDK header before writing resource code — the headers are the source of truth for property names, types, and method signatures.
$(xcrun --show-sdk-path)/System/Library/Frameworks/Metal.framework/Headers/ — focus on MTLResource.h, MTLResidencySet.h, MTLAllocation.h, MTLHeap.h, MTLTexture.h, MTLBuffer.h| Working on… | Read |
|---|---|
| Buffer / texture creation, storage modes (Shared / Private / Memoryless), upload via staging buffer | references/storage-and-upload.md |
| Residency sets (creation, attachment levels, validation rules), deferred destruction | references/residency.md |
| Heaps + aliasing, purgeable memory, texture view pool, view reinterpretation | references/heaps-views.md |
| Apple GPU TBDR architecture | translating-to-metal4-api/references/tbdr-architecture.md |
Tile-Based Deferred Rendering shapes nearly every storage-mode and render-pass decision on Apple Silicon — StorageModeMemoryless for tile-only intermediates, Clear/DontCare load/store actions on transient attachments, in-tile MSAA, and programmable blending all derive from it. The canonical TBDR reference for the suite lives in translating-to-metal4-api/references/tbdr-architecture.md — read it before making storage-mode or render-pass decisions. For the cross-tile fragment-output sync constraint, see managing-metal4-synchronization.
StorageModeManaged — Removed in Metal 4. Use Shared + explicit copies for CPU→GPU sync.useResource/useHeap on Metal 4 encoders — These don't exist. Use residency sets.addAllocation/removeAllocation from multiple threads requires synchronization (e.g., @synchronized in ObjC, mutex in C++). Deferred commit() at queue submit time.texture2d_array but resource is MTLTextureTypeCube, or buffer data interpreted with wrong stride/alignment), the result is silent failure (black textures, wrong data, garbled geometry). For textures, create a view with the correct type/format. For buffers, ensure the binding metadata matches the shader's expectation. GPU frame captures reveal the mismatch directly.StorageModeShared for textures that should be Private — Prevents GPU-optimal tiled memory format. Use Private with staging buffer uploads for GPU-only textures.Load/Store actions on transient attachments — Incurs unnecessary bandwidth on TBDR. Use Clear/DontCare for intermediates that don't need to persist. Enable load/store validation in Metal debug layer to catch this visually.Apple GPUs apply transparent bandwidth compression to textures in both StorageModeShared and StorageModePrivate. Compression reduces bandwidth on load/store actions and spatially coherent shader reads/samples — it does not reduce worst-case memory occupation. The ratio depends on spatial similarity of stored color values; more similar neighboring pixels compress better. StorageModePrivate may use more aggressive forms (including lossy variants) than Shared since the layout is fully GPU-controlled.
When compression is unavailable or doesn't help:
MTLTextureUsageShaderWrite disables lossless compression on GPU families prior to Universal Texture Compression support (M5+). On M5+, shader write is compatible but highly scattered write patterns may reduce the benefit.MTLTextureUsagePixelFormatView disables lossless compression for most ordinary pixel formats.The bandwidth-savings benefit is most material on uncompressed render targets and uncompressed sampled textures with usage flags that don't disable compression. For block-compressed assets and resources that opt out via usage flags, it's a non-factor.
Guidance: Set StorageModePrivate for GPU-only resources, use the minimum required usage flags, and only add ShaderWrite or pixelFormatView when the shader actually needs those capabilities.
ShaderWrite and pixelFormatView can disable lossless compressionRGBA16Float) over 128-bit (RGBA32Float) — 4x sample throughputoptimizeContentsForGPUAccess: after CPU updates to shared texturesDepth16Unorm when 32-bit depth not needed