The Metal compiler turns .metal source into intermediate files and links
them into a Metal library, .metallib, which an app loads at run time.
Apple publishes no specification of the library file. Everything in the
tables below comes from reverse engineering, chiefly the MetalLibraryArchive project, and
is unconfirmed by Apple; fields that project could not identify are marked unknown. Only
the data type codes at the end come from Apple’s own headers.
Header (unconfirmed)
Numbers are little-endian.
| Offset | Size | Meaning |
|---|---|---|
0 | 4 | Magic MTLB. |
4 | 2 | Target platform: 0x8001 macOS, 0x0001 iOS. |
6 | 2 + 2 | File format version, major then minor. |
10 | 1 | Library type: 0x00 executable, 0x01 Core Image, 0x02 dynamic, 0x03 symbol companion. |
11 | 1 | Target operating system; see below. |
12 | 2 + 2 | Target OS version, major then minor. |
16 | 8 | Size of the whole file. |
24 | 8 + 8 | Offset and size of the function list. |
40 | 8 + 8 | Offset and size of the public metadata. |
56 | 8 + 8 | Offset and size of the private metadata. |
72 | 8 + 8 | Offset and size of the bitcode section. |
| Target OS | Meaning | Target OS | Meaning |
|---|---|---|---|
0x00 | unknown | 0x85 | bridgeOS (probable; no sample could be made) |
0x81 | macOS | 0x86 | Mac Catalyst |
0x82 | iOS | 0x87 | iOS Simulator |
0x83 | tvOS | 0x88 | tvOS Simulator |
0x84 | watchOS | 0x89 | watchOS Simulator |
The project notes that empty libraries built for old iOS versions are marked as macOS by mistake.
Function list (unconfirmed)
At the function-list offset: a 32-bit count of entries, then one tag group per
function. A tag group is a 32-bit size followed by tags; each tag is a four-character
name, a 16-bit size and its content. A tag group ends with ENDT.
| Tag | Content | Meaning |
|---|---|---|
NAME | NUL-terminated text | Function name. |
MDSZ | 64-bit | Size of the function’s bitcode. |
TYPE | 8-bit | Function type; see below. |
HASH | 32 bytes | SHA-256 digest of the bitcode. |
OFFT | three 64-bit | Offsets into the public metadata, the private metadata and the bitcode sections. |
SOFF | 64-bit | Offset of the function’s source archive in the embedded source section. |
VERS | four 16-bit | AIR major and minor version, language major and minor version. |
LAYR | 8-bit | Data type of render_target_array_index, for layered rendering (a data type code). |
TESS | 8-bit | Post-tessellation vertex function patch: controlPointCount << 2 | patchType, where patch type 1 is triangle and 2 quad. |
ENDT | none | End of the tag group. |
TYPE | Function |
|---|---|
0x00 | Vertex. |
0x01 | Fragment. |
0x02 | Kernel. |
0x03 | Unqualified. |
0x04 | Visible: functions in a dynamic library marked [[visible]] or [[stitchable]]. |
0x05 | Extern: functions compiled with -fcikernel. |
0x06 | Intersection. |
These file codes differ from the numbers the Metal API uses for the same function types (see function types).
Header extension (unconfirmed)
Present only when the function list’s end plus 4 is not the public metadata offset;
it then starts at function-list offset + size + 4, as a list of tags ending in
ENDT:
| Tag | Content | Meaning |
|---|---|---|
HDYN | 64-bit offset, 64-bit size | Dynamic header section. |
VLST | 64-bit offset, 64-bit size | Exported variable list. |
ILST | 64-bit offset, 64-bit size | Imported symbol list. |
HSRD / HSRC | 64-bit offset, 64-bit size | Embedded source code section. |
UUID | 16 bytes | The library’s UUID. |
ENDT | none | End of the extension. |
The dynamic header section holds a NAME tag (the install name) and
DYNL tags (linked dynamic libraries), each NUL-terminated text. The
variable list and imported symbol list are laid out like the function list; their tags
are unknown.
Metadata, source and bitcode (unconfirmed)
| Section | Contents |
|---|---|
| Public metadata | Function constants, tessellation patches, return types and arguments, in tags including CNST, VATT, VATY, RETR and ARGR; their layouts are not fully known. |
| Private metadata | Paths of the shader sources (DEBI) and of the .air files (DEPF). |
| Embedded source | Only when the library was built with its source: a 16-bit item count, NUL-terminated link options, then (in HSRD only) a working directory, then a tag group with a SARC tag (32-bit size) holding a NUL-terminated archive ID and a bzip2-compressed archive (starting BZh). |
| Bitcode | Each function’s compiled module, found through OFFT and MDSZ and checked with the SHA-256 in HASH. |
Metal data type codes
Tags such as LAYR, VATY and CNST name types with
Metal’s data type codes. Apple’s MTLDataType enumeration gives the public
values below; the MetalLibraryArchive table runs to 0x78 and includes
further values used inside libraries that the public enumeration does not list.
| Code | Type | Code | Type | Code | Type |
|---|---|---|---|---|---|
| 0 | None | 36 | UInt4 | 72 | RGBA8Snorm |
| 1 | Struct | 37 | Short | 73 | RGBA16Unorm |
| 2 | Array | 38 | Short2 | 74 | RGBA16Snorm |
| 3 | Float | 39 | Short3 | 75 | RGB10A2Unorm |
| 4 | Float2 | 40 | Short4 | 76 | RG11B10Float |
| 5 | Float3 | 41 | UShort | 77 | RGB9E5Float |
| 6 | Float4 | 42 | UShort2 | 78 | RenderPipeline |
| 7 | Float2x2 | 43 | UShort3 | 79 | ComputePipeline |
| 8 | Float2x3 | 44 | UShort4 | 80 | IndirectCommandBuffer |
| 9 | Float2x4 | 45 | Char | 81 | Long |
| 10 | Float3x2 | 46 | Char2 | 82 | Long2 |
| 11 | Float3x3 | 47 | Char3 | 83 | Long3 |
| 12 | Float3x4 | 48 | Char4 | 84 | Long4 |
| 13 | Float4x2 | 49 | UChar | 85 | ULong |
| 14 | Float4x3 | 50 | UChar2 | 86 | ULong2 |
| 15 | Float4x4 | 51 | UChar3 | 87 | ULong3 |
| 16 | Half | 52 | UChar4 | 88 | ULong4 |
| 17 | Half2 | 53 | Bool | 115 | VisibleFunctionTable |
| 18 | Half3 | 54 | Bool2 | 116 | IntersectionFunctionTable |
| 19 | Half4 | 55 | Bool3 | 117 | PrimitiveAccelerationStructure |
| 20 | Half2x2 | 56 | Bool4 | 118 | InstanceAccelerationStructure |
| 21 | Half2x3 | 58 | Texture | 121 | BFloat |
| 22 | Half2x4 | 59 | Sampler | 122 | BFloat2 |
| 23 | Half3x2 | 60 | Pointer | 123 | BFloat3 |
| 24 | Half3x3 | 62 | R8Unorm | 124 | BFloat4 |
| 25 | Half3x4 | 63 | R8Snorm | 139 | DepthStencilState |
| 26 | Half4x2 | 64 | R16Unorm | 140 | Tensor |
| 27 | Half4x3 | 65 | R16Snorm | ||
| 28 | Half4x4 | 66 | RG8Unorm | ||
| 29 | Int | 67 | RG8Snorm | ||
| 30 | Int2 | 68 | RG16Unorm | ||
| 31 | Int3 | 69 | RG16Snorm | ||
| 32 | Int4 | 70 | RGBA8Unorm | ||
| 33 | UInt | 71 | RGBA8Unorm_sRGB | ||
| 34 | UInt2 | ||||
| 35 | UInt3 |
Codes not shown (57, 61, 89–114, 119, 120, 125–138) are not in the public enumeration.
Sources
- MetalLibraryArchive – Yu Ao’s reverse-engineered description of the
.metallibformat (README): every unconfirmed table above - MTLDataType.hpp – Apple’s metal-cpp header (a copy published with Babylon Native): the data type codes
- Building a shader library by precompiling source files – Apple: how libraries are built