BNSH (File Format): Difference between revisions
Line 362: | Line 362: | ||
* [[Paper Mario: The Thousand-Year Door]] (Nintendo Switch) | * [[Paper Mario: The Thousand-Year Door]] (Nintendo Switch) | ||
* [[Super Mario Bros. Wonder]] | * [[Super Mario Bros. Wonder]] | ||
* [[The Legend of Zelda: Echoes of Wisdom]] | |||
* [[The Legend of Zelda: Tears of the Kingdom]] | * [[The Legend of Zelda: Tears of the Kingdom]] | ||
|} | |} |
Revision as of 21:56, 25 September 2024
BNSH (Binary NX SHader) is a shader file format used on the Nintendo Switch. It contains shader data.
File Format
Header
The file format starts with the following header:
Offset | Type | Description |
---|---|---|
0x00 | Char[8] | File magic. Always BNSH\0\0\0\0 in ASCII, or 42 4E 53 4E 00 00 00 00. |
0x08 | UInt32 | Version number. |
0x0C | UInt16 | Byte-order-mark. FE FF for big endian, FF FE for little endian. |
0x0E | Byte | Alignment shift. 1 << v, where v is this value is the alignment required by the file. |
0x0F | Byte | Target address size. Size of a pointer in bits, thus 64. |
0x10 | UInt32 | File name offset. Points directly to the string, and not to the length unlike all other strings. |
0x14 | UInt16 | A flag which is only used on runtime. One bit sets wether the file is relocated. |
0x16 | UInt16 | Offset to the first section. |
0x18 | UInt32 | Relocation table offset. |
0x1C | UInt32 | Size of the file in bytes. |
0x20 | Byte[64] | Reserved. |
Shader Container
The shader container is the root and stores some general information about the shaders.
Offset | Type | Description |
---|---|---|
0x00 | Char[4] | Section magic. Always grsc in ASCII. |
0x04 | UInt32 | Next section offset. |
0x08 | UInt32 | Size of this section in bytes. |
0x0C | Byte[4] | Reserved. |
0x10 | UInt16 | API target type. |
0x12 | UInt16 | API target version. |
0x14 | Byte | Target code type. |
0x15 | Byte[3] | Reserved. |
0x18 | UInt32 | Compiler version. |
0x1C | UInt32 | Number of shader variations. |
0x20 | Int64 | Shader variation array offset. |
0x28 | Int64 | Shader memory pool offset. |
0x30 | UInt64 | Low level compiler version. |
0x38 | Byte[40] | Reserved. |
Shader Variation
A shader variation contains a variation of a shader program. The binary program is used for binary files on the Nintendo Switch and the source program is used when testing PTCL files on a computer (which means it contains text shader data). The intermediate language program has an unknown usage. Each entry has the following structure:
Offset | Type | Description |
---|---|---|
0x00 | Int64 | Source program offset. |
0x08 | Int64 | Intermediate language program offset. |
0x10 | Int64 | Binary program offset. |
0x18 | Int64 | Parent shader container offset. |
0x20 | Byte[32] | Reserved. |
Shader Program
The shader program structure specifies a shader program, which will be run on the GPU. It has the following structure:
Offset | Type | Description | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
0x00 | Byte | Flags. 0 = Separation, 1= ResShader. | ||||||||||
0x01 | Byte | Code type.
| ||||||||||
0x02 | Byte | Source format. Only GLSL (0) is supported. | ||||||||||
0x03 | Byte | Reserved. | ||||||||||
0x04 | Int32 | Binary format. | ||||||||||
0x08 | Int64 | Vertex shader code offset. | ||||||||||
0x10 | Int64 | Hull shader code offset. | ||||||||||
0x18 | Int64 | Domain shader code offset. | ||||||||||
0x20 | Int64 | Geometry shader code offset. | ||||||||||
0x28 | Int64 | Fragment shader code offset. | ||||||||||
0x30 | Int64 | Compute shader code offset. | ||||||||||
0x38 | Byte[40] | Reserved. | ||||||||||
0x60 | UInt32 | Object size. The maximum shader size in bytes to store shader object. | ||||||||||
0x64 | Byte[4] | Reserved. | ||||||||||
0x68 | Int64 | Object offset. | ||||||||||
0x70 | Int64 | Parent shader variation offset. | ||||||||||
0x78 | Int64 | Shader reflection offset. | ||||||||||
0x80 | Byte[32] | Reserved. |
Shader Code
Depending on the code type, a different structure can be stored. This one is stored for source:
Offset | Type | Description |
---|---|---|
0x00 | Int64 | Unknown. |
0x08 | Int64 | Data 1 offset. |
0x10 | Int64 | Data 2 offset. |
0x18 | UInt32 | Data 2 size in bytes. |
0x1C | UInt32 | Data 1 size in bytes. |
0x20 | Byte[32] | Padding. |
This one is stored for source array:
Offset | Type | Description |
---|---|---|
0x00 | UInt16 | Number of codes. |
0x02 | Byte[6] | Reserved. |
0x08 | Int64 | Code size array offset. Points to an array of UInt32s which stores the code size. |
0x10 | Int64 | Code data table offset. Points to an array of Int64s which points to the code datas. |
0x18 | Byte[8] | Reserved. |
Shader Reflection
Offset | Type | Description |
---|---|---|
0x00 | Int64 | Vertex reflection offset. |
0x08 | Int64 | Hull reflection offset. |
0x10 | Int64 | Domain reflection offset. |
0x18 | Int64 | Geometry reflection offset. |
0x20 | Int64 | Fragment reflection offset. |
0x28 | Int64 | Compute reflection offset. |
0x30 | Byte[16] | Reserved. |
Shader Reflection Stage
Offset | Type | Description |
---|---|---|
0x00 | Int64 | Shader input dictionary offset. |
0x08 | Int64 | Shader output dictionary offset. |
0x10 | Int64 | Sampler dictionary offset. |
0x18 | Int64 | Constant buffer dictionary offset. |
0x20 | Int64 | Unordered access buffer dictionary offset. |
0x28 | Int32 | Shader output offset into the array. |
0x2C | Int32 | Sampler offset into the array. |
0x30 | Int32 | Constant buffer offset into the array. |
0x34 | Int32 | Unordered access buffer offset into the array. |
0x38 | Int64 | Shader slot array offset. |
0x40 | UInt32 | Compute work group size X. The size of the workgroup's X dimension for compute shaders. |
0x44 | UInt32 | Compute work group size Y. The size of the workgroup's Y dimension for compute shaders. |
0x48 | UInt32 | Compute work group size Z. The size of the workgroup's Z dimension for compute shaders. |
0x4C | Int32 | Image offset into the array. |
0x50 | Int64 | Image dictionary offset. |
0x58 | Byte[8] | Reserved. |
Memory Pool
Offset | Type | Description |
---|---|---|
0x00 | UInt32 | Memory pool property. Always 0x61. |
0x04 | UInt32 | Size of the memory pool in bytes. |
0x08 | Int64 | Offset to the memory pool. Points directly to the start of the data. |
0x10 | Byte[16] | Reserved. |
0x20 | Int64 | Memory pool offset. Points to an array of 0x140 empty bytes, with unknown use. |
0x28 | Byte[8] | Reserved. |
0x30 | Int64 | Current memory pool offset, set at runtime. |
0x38 | Byte[24] | Reserved. |
String Table
The string table is a table where all strings are stored. Each string has first the length written, which is a 16-bit integer, and then the string is stored as a null-terminated string. The string length does not include the null byte, and the 16-bit string length value is always aligned by 2. The string sorting algorithm is unknown.
Offset | Type | Description |
---|---|---|
0x00 | Char[4] | Section magic. Always _STR in ASCII. |
0x04 | UInt32 | Next section offset. |
0x08 | UInt32 | Size of this section in bytes. |
0x0C | Byte[4] | Reserved. |
0x10 | Int32 | Number of strings stored in the string table. The first string is always an empty string ("") and is not included in this count. |
Dictionary
A dictionary (sometimes known as DICT) is a common structure used in many Nintendo formats such as BFRES and BNTX. It is used for fast name look-up, in order to find a specific array item by its name. It starts with the following structure:
Offset | Type | Description |
---|---|---|
0x00 | Char[4] | Section magic. Always _DIC in ASCII. Note that in BFRES this magic is set to 00 00 00 00, most likely due to an export error. |
0x04 | Int32 | Number of entries. This does not include the root entry. |
After, the entries are specified. The root entry follows first, then all other entries are stored. Each entry has the following structure:
Offset | Type | Description |
---|---|---|
0x00 | Int32 | Ref bit. |
0x04 | UInt16[2] | Child node indices. First the left node, then the right node. |
0x08 | Int64 | Key offset, which points to the key name this entry stores. |
Relocation Table
Offset | Type | Description |
---|---|---|
0x00 | Char[4] | Section magic. Always _RLT in ASCII. |
0x04 | UInt32 | Table offset. The offset where this table starts. |
0x08 | Int32 | Number of sections. |
0x0C | Byte[4] | Padding. |
Offset | Type | Description |
---|---|---|
0x00 | Int64 | Section pointer, set on runtime. |
0x08 | UInt32 | Section offset. |
0x0C | UInt32 | Section size. |
0x10 | UInt32 | Entry ID. |
0x14 | UInt32 | Number of entries. |
Offset | Type | Description |
---|---|---|
0x00 | UInt32 | Entry offset. |
0x04 | UInt16 | Array count. |
0x06 | Byte | Offset count. |
0x07 | Byte | Padding size. |
Version List
Tools
The following tools can handle BNSH files:
- (none)