From game-porting-skills
Creates and manages Metal 4 GPU resources: buffers, textures, heaps, residency sets, purgeable state, texture view pools, and deferred destruction.
How 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).
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 needednpx claudepluginhub apple/game-porting-toolkit --plugin game-porting-skillsTranslates 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, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.