Skip to content

Metallib file format

Jack Rickard edited this page Mar 11, 2020 · 15 revisions

Metallibs are very simple files, however there is no documentation on them and it's unlikely there ever will be. Hopefully, Naga will be able to produce these files directly without having to pas through a text representation and then be compiled for a second time.

In some bastardised rust notation this is the file format (all numbers little endian):

struct Value {
   /// Length of the following data
   length: u16,
   data: [u8],
}

struct Metallib {
    magic_number = b"MTLB",
    /// Seen 0x00028001
    unknown: u32,
    /// Seen 3, 2
    unknown: u64,
    /// Total length including what has come before
    file_size: u64,
    /// Seen 0x58
    unknown: u64,
    /// Seen 0x18B, 0x106
    unknown: u64,
    /// Seen 0x1EB, 0x166
    unknown: u64,
    /// Seen 0x34, 0x2C
    unknown: u64,
    /// Seen 0x21F, 0x192
    unknown: u64,
    /// Seen 0x18, 0x10
    unknown: u64,
    bitcode_start: u64,
    total_bitcode_length: u64,

    num_entries: u32,
    headers: [Header; num_entries],
    endt_ tag = b"ENDT",

    len_?:u32,
    vatt_tag = b"VATT",
    /// No idea, seen [0x0001, b"position\0", 0x8000]
    vatt: Value,
    vaty_tag = b"VATY",
    /// No clue, seen [0x01, 0x00, 0x06]
    vaty: Value,
    endt_tag = b"ENDT",

    /// Empty things??
    empties: [Empty; 6],

    /// Code!
    bitcode: [LLVMBitcode; num_entries],
}

struct Header {
    /// Total length of this header
    length: u32,

    name_tag = b"NAME",
    /// Name of the entry point, null terminated
    name: Value,

    type_tag = b"TYPE",
    /// 0 for vertex shaders, 1 for fragment shaders, seems to always be 1 byte
    type: Value,

    hash_tag = b"HASH",
    /// The SHA256 hash of this entrypoint's bitcode
    hash: Value,

    mdsz_tag = b"MDSZ",
    /// Size of this entry point's LLVM bitcode, seems to always be 8 bytes long
    mdsz: Value,

    offt_tag = b"OFFT",
    /// No idea, seems to be [u64; 3], seen [0,0,0],[0x24,0x8,0xA60],[0x2C,0x10,0x1490]
    offt: Value, 

    vers_ tag = b"VERS",
    /// No idea, seems to be [2,2,2,2]: [u16; 4]
    vers: Value, 

    endt_ tag = b"ENDT",
}

struct Empty {
    /// Always 4 for obvious reasons
    length: u32 = 4,
    endt_tag = b"ENDT",
}
Clone this wiki locally