foreach mesh { BASE 0 OFFSET from pipe struct // call instanced data: foreach batch { UNPACK ITOP set vertex count MSCALF/MSCNT call micro program last batch: FLUSH (earlier: MSKPATH3 enable) } } VU == XITOP get ITOP (vertex count) XTOP get TOP (input address) VIF === BASE: set BASE OFFSET: set OFFSET TOPS <- BASE DBF <- 0 UNPACK: transfer to TOPS ITOP: set ITOPS MSCAL: TOP <- TOPS ITOP <- ITOPS TOPS <- BASE/BASE+OFFSET (DBF flag) DBF <- ~DBF 0 - OFFSET: input buffer 1 No clipping =========== Double buffered +--------------------+ 0 | | | | | Input 1 | | | | | +--------------------+ OFFSET | | | | | Input 2 | | | Triple buffered | | | | +--------------------+ ExpandBuffer1 +--------------------+ ExpandBuffer1 | | | | | | | Output 1 | | Output 1 | | | | | +--------------------+ ExpandBuffer2 | | | | +--------------------+ ExpandBuffer2 | Output 2 | | | | | | | +--------------------+ ExpandBuffer3 | Output 2 | | | | | | Output 3 | | | | | +--------------------+ vuSymbStaticDataStart +--------------------+ vuSymbStaticDataStart | | | | | Static data | | | +--------------------+ Clipping ======== Double buffered Triple buffered | | | | +--------------------+ ExpandBuffer1 +--------------------+ ExpandBuffer1 | | | | | | | Output 1 | | Output 1 | | | | | +--------------------+ XExpandBuffer2 | | | | +--------------------+ XExpandBuffer2 | Output 2 | | | | | | | +--------------------+ XExpandBuffer3 | Output 2 | | | | | | Output 3 | | | | | +--------------------+ ClippingBuffer | | | | +--------------------+ ClippingBuffer | | | | | Clipped Input | | Clipped Input | | | | | | | | | +--------------------+ vuSymbStaticDataStart +--------------------+ vuSymbStaticDataStart | | | | Clipping uses one of the idle output buffers to store a clipped polygon. This is then inserted as input triangles into the clipping buffer. Whenever the clipping buffer is full, the first pass and FX pass generators will use it to fill the output buffer(s) and XGKICK them. Then clipping continues until all input has been processed. VU program ========== General flow: setup matrix and code path for(;;){ // meshes light & animate input buffer if(clipping){ while(input buffer not empty){ foreach primitive while clip buffer not full { transform to clip space and clip in idle output buffer interpolate vertices, add to clip buffer } transform clip to screen space xgkick pass1; rotate buffers (generate pass2 xgkick pass2; rotate buffers) } }else{ transform model to screen space xgkick pass1; rotate buffers (generate pass2 xgkick pass2; rotate buffers) } halt // restart by MSCNT } Static data =========== set up in _rwSkyPipeSetupForCamera TODO: what's useFarClip? 0x3F0 vuSDmat0 combined matrix; w row = z row 0x3F1 vuSDmat1 combined matrix 0x3F2 vuSDmat2 combined matrix 0x3F3 vuSDmat3 combined matrix 0x3F4 vuSDnearClip xyzw: camera near plane vu1DataNearClip 0x3F5 vuSDfarClip xyzw: camera far plane vu1DataFarClip 0x3F6 vuSDxMaxyMax ?, ?, -255/(fogEnd-fogStart), fogEnd xMaxYMax128 0x3F7 vuSDcamWcamHzScale raster width, raster height, zScale, 0 vu1DataXYZScale 0x3F8 vuSDoffXoffYzShift 0, 0, zShift, 0 vu1DataXYZShift 0x3F9 vuSDrealOffset xoff, yoff, 0, 0 vu1DataOffset3D 0x3FA vuSDgifTag gifTag128 0x3FB vuSDcolScale material color (scaled by 128/255 when textured) 0x3FC vuSDsurfProps surface properties 0x3FD vuSDpingPongAddr obsolete 0x3FE vuSDpingPongCount obsolete 0x3FD vuSDClipvec1 cull: 2047.9374-screenWidth/2, 1/x, zScaleClip, far plane skyClipVect1 clip: screenWidth/2 + 5, 1/x, zScaleClip, far plane skyCClipVect1 0x3FE vuSDClipvec2 cull: 2047.9374-screenHeight/2, 1/x, zShiftClip, near plane skyClipVect2 clip: screenHeight/2 + 5, 1/x, zShiftClip, near plane skyCClipVect2 0x3FF vuSDVUSwitch code path switch, render system, ?, backface cull xoff = fb->width/2 + fb->offsetX - par->width/2 + 2048 yoff = fb->height/2 + fb->offsetY - par->height/2 + 2048 persp zScaleClip: -2*far*near/(far-near) persp zShiftClip: (far+near)/(far-near) paral zScaleClip: 2/(far-near) paral zShiftClip: -(far+near)/(far-near) GTA San Andreas =============== Building: DN 0x3CE x dnbalance; y 1-WetRoads 0x3CF xyz building ambient light BuildingEnvMap: DN 0x3C3 x dnbalance; y 1-WetRoads 0x3C4 xyz building ambient light 0x3C5 GIF packet env state; FOGCOL, TEX0_2 0x3C8 GIF packet diffuse state; FOGCOL, TEX0_1 0x3CB GIF tag env 0x3CC xyz env matrix; 0x3CD xyz env matrix; w lightmult 0x3CE xyz env matrix; w shininess 0x3CF xyzw env transform BuildingUVA: 0x3CD xyz building ambient light 0x3CE xy texmat right.xy; zw texmat up.xy 0x3CF zw texmat pos.xy BuildingDNUVA: 0x3CD x dnbalance; y 1-WetRoads; zw texmat pos.xy 0x3CE xyz building ambient light 0x3CF xy texmat right.xy; zw texmat up.xy Car: 0x3CD GIF packet; TEX0_1, TEX2_1 CarEnv: 0x3BD GIF packet spec state; FOGCOL, TEX0_2 0x3C0 GIF packet env state; FOGCOL, TEX0_2 0x3C3 GIF packet diffuse state; FOGCOL, TEX0_1, TEX2_1 0x3C7 GIF tag spec/env 0x3C8 xyz normal view matrix (spec); w specularity 0x3C9 xyz normal view matrix (spec); effect flags 0x3CA xyz normal view matrix (spec) 0x3CB xyz view sun direction 0x3CC xy normal world matrix (env) 0x3CD xy normal world matrix (env); w lightmult 0x3CE xy normal world matrix (env); w shininess 0x3CF xyzw env transform