Rockstar PS2 pipelines
In GTA San Andreas for PS2 Rockstar used RenderWare's Pipeline Delivery System (RpPDS) that was introduced with RW 3.5 to create custom pipelines. This page is about Rockstar's custom pipelines specifically, PS2 pipelines in general are (not yet) described elsewhere.
All of these pipelines are initialized in init.pm/nm (see PS2 Code Overlay) so the addresses below are only valid if the init code has been loaded into memory. Addresses refer to SLES_525.41 and init.pm.
All object pipelines have even IDs, material pipelines have odd IDs.
PDS Templates
Building Pipelines
All of these pipelines use the building VU1 code.
CVBuildingPipe
53F20080 (template @ 8A3000) matGroup: 53F20081
53F20081 (template @ 8A2F70) clusters: 6 6D00000D (R* xyzw) 7 6500000D (R* uv) 8 6E00400D (R* rgba) stride: 3 vertexCount: 0x51 primCount: 0x1B vifOffset: 0xF3
CVBuildingDNPipe
53F20082 (template @ 8A30B0) matGroup: 53F20083
53F20083 (template @ 8A3020) clusters: 6 6D00000D (R* xyzw) 7 6500000D (R* uv) 8 6D00400D (R* rgba2) stride: 3 vertexCount: 0x51 primCount: 0x1B vifOffset: 0xF3
CVBuildingEnvMapPipe
53F2008C (unused by DFFs, template @ 8A3160) matGroup: 53F2008D
53F2008D (used with 53F20080, template @ 8A30D0) clusters: 6 6D00000D (R* xyzw) 7 6500000D (R* uv) 8 6E00400D (R* rgba) 9 6E00000D (R* normal) stride: 4 vertexCount: 0x38 primCount: 0x12 vifOffset: 0xE0
CVBuildingDNEnvMapPipe
53F2008E (unused by DFFs, template @ 8A3210) matGroup: 53F2008F
53F2008F (used with 53F20082, template @ 8A3180) clusters: 6 6D00000D (R* xyzw) 7 6500000D (R* uv) 8 6D00400D (R* rgba2) 9 6E00000D (R* normal) stride: 4 vertexCount: 0x38 primCount: 0x12 vifOffset: 0xE0
CVBuildingUVAPipe
53F20090 (unused by DFFs, template @ 8A32C0) matGroup: 53F20091
53F20091 (unused by DFFs, template @ 8A3230) clusters: 6 6D00000D (R* xyzw) 7 6500000D (R* uv) 8 6E00400D (R* rgba) stride: 3 vertexCount: 0x50 primCount: 0x1A vifOffset: 0xF0
CVBuildingDNUVAPipe
53F20092 (unused by DFFs, template @ 8A3370) matGroup: 53F20093
53F20093 (unused by DFFs, template @ 8A32E0) clusters: 6 6D00000D (R* xyzw) 7 6500000D (R* uv) 8 6D00400D (R* rgba2) stride: 3 vertexCount: 0x50 primCount: 0x1A vifOffset: 0xF0
Vehicle Pipelines
All of these pipelines use the vehicle VU1 code.
CVCarPipe
53F20084 (template @ 8A2F50) matGroup: 53F20084
This pipeline does not render any reflection effects:
53F20085 (template @ 8A2EC0) clusters: 6 6D00000D (R* xyzw) 7 6500000D (R* uv) 8 6E00401C (not instanced) 9 6E00000D (R* normal) stride: 4 vertexCount: 0x45 primCount: 0x17 vifOffset: 0x114
CVCarEnvMapPipe
53F20086 (unused by DFFs, template @ 8A2E00) matGroup: -
This pipeline renders environment maps (and specular maps):
53F20087 (use with 53F20084, template @ 8A2CE0) clusters: 6 6D00000D (R* xyzw) 7 6500000D (R* uv) 8 6E00401C (not instanced) 9 6E00000D (R* normal) stride: 4 vertexCount: 0x38 primCount: 0x12 vifOffset: 0xE0
This pipeline renders x-environment maps (and specular maps):
CVCarEnvMapUV2Pipe
53F2008B (use with 53F20084, template @ 8A2D70) clusters: 6 6D00000D (R* xyzw) 7 6D00000D (R* uv2) 8 6E00401C (not instanced) 9 6E00000D (R* normal) stride: 4 vertexCount: 0x38 primCount: 0x12 vifOffset: 0xE0
Skin Pipelines
This pipeline uses the skin VU1 code.
CVSkinPedPipe
53F20088 (template @ 6275A0) matGroup: 53F20089
53F20089 (template @ 627510) clusters: 6 6D00000D (R* xyzw) 7 6500000D (R* uv) 8 6E00000D (R* normal) 9 6C00000D (skin data) stride: 4 vertexCount: 0x2e primCount: 0x10 vifOffset: 0xC0
Data format and VU1 code
Normals are scaled by 128, UV coordinates by 4096.
Vertices are scaled by 128 in the building code, otherwise by 1024.
The W field of the xyzw cluster is 0x0000 or 0x8000 and written to the ADC field of the XYZF register. 0x8000 inhibits the draw kick for this vertex.
For each vertex skin value the lower 10 bits are the bone matrix offset, the upper 22 bits are the upper part of an IEEE-float.
The bone matrix offset can be converted to a bone index like this: i = off == 0 ? 0 : off/4 - 1
VU code binary: Building Vehicle Skin
VU code disassembled: Building Vehicle Skin
(NB: the disassembler has a bug and always disassembles div instructs as 'div q,vf00w,vf00x')