BNSH (File Format)

From Wexos's Wiki
Revision as of 21:56, 25 September 2024 by Atlas (talk | contribs) (→‎Version List)
Jump to navigationJump to search

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.
ID Description
0x00 Binary
0x01 Intermediate language
0x02 Source
0x03 Source array
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

Version Found in
2.1.2
2.1.4
2.1.5
2.1.10
  • Nintendo Switch System BIOS (6.0.0 – 6.2.0)
  • Tetris 99
2.1.11
2.1.12
2.2.1

Tools

The following tools can handle BNSH files:

  • (none)