Difference between revisions of "XPR"
(Add some rough information about XPRs) |
(Complete rewrite based on my reverse engineering of the XPR0 format as used by Steel Battalion and Steel Battalion: Line of Contact) |
||
Line 5: | Line 5: | ||
XPRs are storing data similar to internal structures in the D3D driver. So D3D has mechanisms to simply load such resources into D3D objects (by moving them into GPU accessible memory). | XPRs are storing data similar to internal structures in the D3D driver. So D3D has mechanisms to simply load such resources into D3D objects (by moving them into GPU accessible memory). | ||
− | + | An XPR header consists of a number of resource entries which each look something like this{{FIXME|Incomplete}}: | |
<pre> | <pre> | ||
struct { | struct { | ||
− | + | union { | |
− | + | uint32_t resource_type; // Type information and who "owns" this resource | |
− | + | struct { | |
− | } | + | uint32_t ref_count:16; // (lowest bits) |
− | + | uint32_t type:3; | |
− | + | uint32_t unk3:13; // (highest bits) | |
− | + | }; | |
+ | }; | ||
+ | uint32_t data; // Offset of this resource's data in the file | ||
+ | uint32_t unknown; // Always zero | ||
− | + | union { | |
− | union | + | struct XPR_Vertexbuffer; // Vertexbuffer (type 0x0) |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
... | ... | ||
− | } | + | } XPR_Vertexbuffer; |
− | + | struct { // Indexbuffer (type 0x1) | |
... | ... | ||
− | } | + | } XPR_Indexbuffer; |
− | + | struct { // Unknown (type 0x2) | |
... | ... | ||
} ...; | } ...; | ||
− | + | struct { // Unknown (type 0x3) | |
... | ... | ||
} ...; | } ...; | ||
− | + | struct { // Texture (type 0x4) | |
− | + | ...; | |
− | + | } XPR_Texture; | |
− | + | struct { // Unknown (type 0x5) | |
− | |||
− | |||
− | } | ||
− | |||
... | ... | ||
} ...; | } ...; | ||
− | + | struct { // Unknown (type 0x6) | |
... | ... | ||
} ...; | } ...; | ||
− | + | struct { // Unknown (type 0x7) | |
... | ... | ||
} ...; | } ...; | ||
}; | }; | ||
− | + | } XPR_Resource; | |
− | } | ||
</pre> | </pre> | ||
− | {{ | + | The XPR header as a whole looks like this: |
+ | |||
+ | <pre> | ||
+ | union { | ||
+ | struct { | ||
+ | char magic[4]; // Always "XPR0" / 0x30525058 | ||
+ | uint32_t size; // Size of XPR (including magic and this field) | ||
+ | uint32_t header_size; // Size of this header rounded up to the nearest 2048 byte boundary | ||
+ | XPR_Resource resources[]; // An array of XPR_Resource entries | ||
+ | uint32_t last_resource; // Always 0xFFFFFFFF | ||
+ | }; | ||
+ | uint8_t pad[XPR.header_size]; // Padded with 0xAD bytes | ||
+ | } XPR; | ||
+ | </pre> | ||
The headers are then followed by the resource data. | The headers are then followed by the resource data. | ||
+ | |||
+ | ---- | ||
+ | |||
+ | Texture data can be stored in a variety of hardware defined formats as specified by the architecture of the NV2A GPU. | ||
+ | The format used, along with other information such as width, height, depth, and mipmap levels is stored in the resource header for the texture. | ||
+ | |||
+ | The format for an XPR texture resource is as follows: | ||
+ | <pre> | ||
+ | struct { | ||
+ | union { | ||
+ | uint32_t gpu; // This 32-bit value is placed in the NV097_SET_TEXTURE_FORMAT GPU register | ||
+ | struct { | ||
+ | uint32_t dma : 4; (lowest bits) | ||
+ | uint32_t dimensions : 4; // Is this a 1D, 2D, or 3D texture | ||
+ | uint32_t format : 8; // The format of the texture data (see the table below) | ||
+ | uint32_t levels : 4; // Number of mipmap levels | ||
+ | uint32_t width : 4; // Width of the texture in the following format: actual_width = (1 << width) | ||
+ | uint32_t height : 4; // Height of the texture in the following format: actual_height = (1 << height) | ||
+ | uint32_t depth: 4; (highest bits) // Depth of the texture (for 3D textures) in the following format: actual_depth = (1 << depth) | ||
+ | }; | ||
+ | }; | ||
+ | union { | ||
+ | uint32_t size; // Describes the size of a texture who's dimensions are not a power-of-2 | ||
+ | struct { | ||
+ | uint32_t width : 12; (lowest bits) // The width of the texture in the following format: actual_width = width + 1 | ||
+ | uint32_t height : 12; // The height of the texture in the following format: actual_height = height + 1 | ||
+ | uint32_t depth : 8; (highest bits) // The depth of the texture (for 3D textures) in the following format: actual_depth = depth + 1 | ||
+ | } | ||
+ | }; | ||
+ | } XPR_Texture; | ||
+ | </pre> | ||
+ | |||
+ | |||
+ | For textures that use arbitrary dimensions the width, height, and depth attributes of the gpu field should be zero. For textures such as DXT that use power-of-2 dimensions the size field should be zero. | ||
+ | |||
+ | The following as a list of texture formats which can be used for the format attribute of the gpu field: | ||
+ | |||
+ | <pre> | ||
+ | NV097_SET_TEXTURE_FORMAT_COLOR_SZ_A1R5G5B5 0x02 | ||
+ | NV097_SET_TEXTURE_FORMAT_COLOR_SZ_X1R5G5B5 0x03 | ||
+ | NV097_SET_TEXTURE_FORMAT_COLOR_SZ_A4R4G4B4 0x04 | ||
+ | NV097_SET_TEXTURE_FORMAT_COLOR_SZ_R5G6B5 0x05 | ||
+ | NV097_SET_TEXTURE_FORMAT_COLOR_SZ_A8R8G8B8 0x06 | ||
+ | NV097_SET_TEXTURE_FORMAT_COLOR_SZ_X8R8G8B8 0x07 | ||
+ | NV097_SET_TEXTURE_FORMAT_COLOR_SZ_I8_A8R8G8B8 0x0B | ||
+ | NV097_SET_TEXTURE_FORMAT_COLOR_L_DXT1_A1R5G5B5 0x0C | ||
+ | NV097_SET_TEXTURE_FORMAT_COLOR_L_DXT23_A8R8G8B8 0x0E | ||
+ | NV097_SET_TEXTURE_FORMAT_COLOR_L_DXT45_A8R8G8B8 0x0F | ||
+ | NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_R5G6B5 0x11 | ||
+ | NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_A8R8G8B8 0x12 | ||
+ | NV097_SET_TEXTURE_FORMAT_COLOR_SZ_A8 0x19 | ||
+ | NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_X8R8G8B8 0x1E | ||
+ | NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_DEPTH_Y16_FIXED 0x30 | ||
+ | NV097_SET_TEXTURE_FORMAT_COLOR_SZ_A8B8G8R8 0x3A | ||
+ | NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_A8B8G8R8 0x3F | ||
+ | </pre> |
Latest revision as of 03:17, 22 September 2023
XPR probably stands for Xbox Packed Resource. It's a structure and file-format used by the Microsoft XDK. It is being used in parts of XAPI.
XPRs can store a variety of different data types that are useful for Xbox D3D. XPRs are storing data similar to internal structures in the D3D driver. So D3D has mechanisms to simply load such resources into D3D objects (by moving them into GPU accessible memory).
An XPR header consists of a number of resource entries which each look something like this[FIXME]:
struct { union { uint32_t resource_type; // Type information and who "owns" this resource struct { uint32_t ref_count:16; // (lowest bits) uint32_t type:3; uint32_t unk3:13; // (highest bits) }; }; uint32_t data; // Offset of this resource's data in the file uint32_t unknown; // Always zero union { struct XPR_Vertexbuffer; // Vertexbuffer (type 0x0) ... } XPR_Vertexbuffer; struct { // Indexbuffer (type 0x1) ... } XPR_Indexbuffer; struct { // Unknown (type 0x2) ... } ...; struct { // Unknown (type 0x3) ... } ...; struct { // Texture (type 0x4) ...; } XPR_Texture; struct { // Unknown (type 0x5) ... } ...; struct { // Unknown (type 0x6) ... } ...; struct { // Unknown (type 0x7) ... } ...; }; } XPR_Resource;
The XPR header as a whole looks like this:
union { struct { char magic[4]; // Always "XPR0" / 0x30525058 uint32_t size; // Size of XPR (including magic and this field) uint32_t header_size; // Size of this header rounded up to the nearest 2048 byte boundary XPR_Resource resources[]; // An array of XPR_Resource entries uint32_t last_resource; // Always 0xFFFFFFFF }; uint8_t pad[XPR.header_size]; // Padded with 0xAD bytes } XPR;
The headers are then followed by the resource data.
Texture data can be stored in a variety of hardware defined formats as specified by the architecture of the NV2A GPU. The format used, along with other information such as width, height, depth, and mipmap levels is stored in the resource header for the texture.
The format for an XPR texture resource is as follows:
struct { union { uint32_t gpu; // This 32-bit value is placed in the NV097_SET_TEXTURE_FORMAT GPU register struct { uint32_t dma : 4; (lowest bits) uint32_t dimensions : 4; // Is this a 1D, 2D, or 3D texture uint32_t format : 8; // The format of the texture data (see the table below) uint32_t levels : 4; // Number of mipmap levels uint32_t width : 4; // Width of the texture in the following format: actual_width = (1 << width) uint32_t height : 4; // Height of the texture in the following format: actual_height = (1 << height) uint32_t depth: 4; (highest bits) // Depth of the texture (for 3D textures) in the following format: actual_depth = (1 << depth) }; }; union { uint32_t size; // Describes the size of a texture who's dimensions are not a power-of-2 struct { uint32_t width : 12; (lowest bits) // The width of the texture in the following format: actual_width = width + 1 uint32_t height : 12; // The height of the texture in the following format: actual_height = height + 1 uint32_t depth : 8; (highest bits) // The depth of the texture (for 3D textures) in the following format: actual_depth = depth + 1 } }; } XPR_Texture;
For textures that use arbitrary dimensions the width, height, and depth attributes of the gpu field should be zero. For textures such as DXT that use power-of-2 dimensions the size field should be zero.
The following as a list of texture formats which can be used for the format attribute of the gpu field:
NV097_SET_TEXTURE_FORMAT_COLOR_SZ_A1R5G5B5 0x02 NV097_SET_TEXTURE_FORMAT_COLOR_SZ_X1R5G5B5 0x03 NV097_SET_TEXTURE_FORMAT_COLOR_SZ_A4R4G4B4 0x04 NV097_SET_TEXTURE_FORMAT_COLOR_SZ_R5G6B5 0x05 NV097_SET_TEXTURE_FORMAT_COLOR_SZ_A8R8G8B8 0x06 NV097_SET_TEXTURE_FORMAT_COLOR_SZ_X8R8G8B8 0x07 NV097_SET_TEXTURE_FORMAT_COLOR_SZ_I8_A8R8G8B8 0x0B NV097_SET_TEXTURE_FORMAT_COLOR_L_DXT1_A1R5G5B5 0x0C NV097_SET_TEXTURE_FORMAT_COLOR_L_DXT23_A8R8G8B8 0x0E NV097_SET_TEXTURE_FORMAT_COLOR_L_DXT45_A8R8G8B8 0x0F NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_R5G6B5 0x11 NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_A8R8G8B8 0x12 NV097_SET_TEXTURE_FORMAT_COLOR_SZ_A8 0x19 NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_X8R8G8B8 0x1E NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_DEPTH_Y16_FIXED 0x30 NV097_SET_TEXTURE_FORMAT_COLOR_SZ_A8B8G8R8 0x3A NV097_SET_TEXTURE_FORMAT_COLOR_LU_IMAGE_A8B8G8R8 0x3F