XaiJu
dobiestation
dobiestation

patreon


Technical Insight: The PS2 GIF and its Massive Bandwidth

The PlayStation 2's design seems almost reactionary to that of the PSX's. While the PSX GPU has a low fillrate, the Graphics Synthesizer (GS) outputs so many pixels, it can compete with the PS3's GPU in some cases! This increased fillrate requires a lot more bandwidth, so much that a single data provider isn't enough. Thus, the PS2 has not one, but three different ways data can be sent to the GS.

The GS Interface (GIF) is responsible for arbitrating between the different data providers and transferring data to the GS. Understanding how it works is paramount to fully utilizing the PS2's bandwidth.

How the GIF works

As mentioned earlier, three different sources can feed data to the GIF, through what are called PATHs. PATH1 is VU1, a custom DSP that acts as a flexible vertex shader for the GS. PATH2 is the Vector Interface (VIF), which prepares data for VU1 while also being able to transfer texture data to the GS. PATH3 is a standard DMA channel, also primarily used for transferring textures.

Ideally, all three PATHs should be doing something. However, only a single PATH can run at a time, or otherwise data from different PATHs would be interleaved, which would mess up rendering at minimum. Thus, when a PATH requests access when another PATH is already running, the GIF remembers the pending request and will activate the PATH when the current one has finished transferring data.

The PATHs are ordered by priority, with PATH1 being the highest and PATH3 being the lowest. This lends itself to a natural rendering paradigm: PATH1 is used to transfer geometry that has already been processed, and PATH2/PATH3 are used to queue new textures for the next batch of geometry. This is not set in stone, as all PATHs can transfer any kind of graphical data, but this is a simple yet effective way to utilize the bandwidth.

Managing all of this might seem unnecessarily complex. It is possible to get away with only using one PATH at a time, but the quality of the game will suffer greatly for this. Less bandwidth means less polygons and textures, which also makes it more difficult to apply post-processing. The GS has a measly 4 MB of VRAM which has to be shared with the framebuffer, depth buffer, palettes, and textures. A double-buffered 640x448 32-bit framebuffer along with a 32-bit depth buffer leaves only 753 KB of space left for textures. Extra VRAM can be saved by using less precise color and depth formats, but this creates new issues such as Mach banding and z-fighting. It is clear that the PS2 was designed with continuously streaming textures in mind.

Memory Speeds and MFIFO

Thanks to VU1's fast memory, PATH1 is able to transfer data at maximum bandwidth. PATH2 and PATH3 are not so fortunate - transferring data from the much slower RDRAM can attain only 40% of the maximum theoretical output. For this reason, the PS2 provides a 16 KB scratchpad memory. Transferring from this is just as fast as PATH1, but an obvious problem is the limited space. 16 KB is only enough for a single 32-bit 64x64 texture! This leaves no space for any other use as well, forcing the main CPU to work with main RAM.

Yet another solution is provided, the Memory FIFO (MFIFO). This is a special feature that can be used by either PATH2 or PATH3. The user defines the location and size of a buffer in main RAM, then whenever data is transferred to the scratchpad, the MFIFO feature automatically transfers this to the memory buffer. PATH2 or PATH3 then reads from main RAM as normal. This works around the limited space that the scratchpad holds while also allowing the EE to not worry about if a PATH transfer is currently active - it can just queue up new data in the FIFO.

After a discussion on how slow transferring from main RAM is, it might seem silly to say that doing that and adding another transfer helps speed. However, it does end up being an optimization. The reason is that if PATH1 is active, it can take a long time for it to finish due to all the geometry that needs to be drawn. During this time, PATH2 and PATH3 are just doing nothing! MFIFO allows the EE to queue up texture data during this stall, so while PATH2/PATH3 are not going any faster, the EE is able to do more, such as preparing display lists.

PATH3 Masking

Imagine that one wants to transfer texture data through PATH3, but that cannot be done because VU1 has yet to process all the geometry that uses the current textures in memory. Normally, the EE would have to wait until VU1 is finished, which is a huge waste of time. PATH3 masking solves this problem - the EE can safely start a PATH3 transfer, and the data will not be transferred until the mask is lifted.

VIF1 applies and lifts this mask as needed. A typical processing flow might be mask PATH3 => start VU1 microprogram => wait until VU1 is finished => unmask PATH3. All of this occurs on the VIF, freeing up precious EE time to do other tasks.

Emulating PATH3 masking can be tricky. Many games have strict masking timings, expecting a certain amount of data to be transferred before a mask is applied. Too much or too little transferred data can result in wrong textures being used or graphical corruption. In rare cases, it might even cause hangs, as the game could expect all the data in PATH3 to be transferred before a mask is applied.

Closing

The PS2 is monstrously complex, not only for emulator developers but also game developers. The GIF is only one out of many hardware components, and yet it is tightly integrated with so many parts. The PS2 can be a powerful machine when used correctly, but so many things can go wrong if one is inattentive. Dealing with the myriad bugs in games caused by improper understanding of the hardware is frustrating, yet it is fascinating to see how all the parts work together.


More Creators