JesusClownFox said:
In regards to turning off the Z-buffer, it might give back some bandwidth when reading the current frame, but for all the overdrawing it can potentially save, it certainly would not be a very wise compromise.
Hm, in case of the GS, all the Z-buffer really does is prevent depth errors when opaque polygons intersect. To eliminate overdraw you need to render in front-to-back order, and there's simply no point in doing that on the GS. It's so fast it does 10 layers per pixel overdraw PER FRAME without even breaking a sweat. No, on the GS you don't give a f*ck about overdraw
, instead you sort by texture order and just go ahead and render the scene straight up.
You fill pixels blazing fast, but you don't have much space for storing textures or bandwidth to upload them on a frame-by-frame basis, so it's much smarter to do the rendering on a per-texture basis even if it means a lot of overdraw. It's not elegant or efficient, but who cares. It's the end result that counts.
It's rare you're ever going to be fill limited on PS2 anyway as you'll realistically bottleneck somewhere else before that happens.
I mean, the memory used in getting the entire scene at once might be more or less the same as what is used for immediate-mode rendering in multiple passes, considering the developer uses a proper front-to-back sorting method.
Problem is, efficient 3D engines don't really lend themselves to being proper front-to-back renderers, so you won't ever see full effect from the bandwidth-saving techniques on IMR-based 3D chips. It's actually faster to have some overdraw on your 3D-chip than bog down the CPU sorting through reams of triangles to eliminate overdraw. That's one of the reasons Unreal-engined games ran pretty slow in software mode, because the engine killed all the overdraw before rasterization.
Thinking about it now, it seems that the texture and framebuffer ports each have their own specialised needs, and thus it's inappropriate to mix them around.
I'm pretty sure you CAN'T. They're not likely to be connected through some kind of switchboard, they're likely hardwired to the functional units that use them.
I assume that this is not a common occurance in most games, otherwise Sony would've provided a separate "texture write" port.
I don't exactly know how common it is, but it's been done that's for sure, and because the GS is so damn quick at rasterizing, it's a blazing fast operation. You wouldn't need a specific TEXTURE write port anyway as the GS doesn't know nor care the buffer it is rendering to will be used as a texture down the road anyway.
Or you could just have VU0 do whatever special operations on the texture and send it to the eDRAM (but there's more problems there, dealing with external bandwidth and such).
Well, if you're doing a procedural texture such as a force-field or such like Unreal, wood grains, blood floating about like in Silent Hill 3 etc, you'll probably want to do it on a VU as the GS is very limited on the maths it can do on a texture, but if you want reflections for example like on a nice, shiny car's body in a racing game, it's a task for the GS.
Also, I assume the three framebuffers work like this: one after triangle setup/rasterization, another after texture ops, and a final one after framebuffer ops. Is this correct?
Um...no.
Usually you have three buffers, yes, but they don't work quite the way you think.
You have front buffer that holds graphics being displayed. Back buffer being rendered into, and Z buffer for depth and possibly stencil effects or such.
I'm no expert on the specifics, but the basic 3D pipeline in a traditional polygon renderer like those we have today (ie nothing weird like the voxel engine in the PC game "Outcast", etc), is something like this:
3D transforms + lighting -> backface culling (typically done on EE's VU1, but sometimes programmers skip the culling as the GS is so damn fast you could just draw the backfacing polys anyway) -> send to GS -> poly setup + clipping -> read texels/source/destination alpha values, do blend ops -> Z check -> if success update Z if neccessary/write pixel to back-buffer, if fail discard pixel. Keep doing until frame is finished, then wait until vertical blank, swap front buffer with back buffer, clear back buffer, clear Z and start over. Basically. There are probably some steps I missed etc, but like I said, I'm just a dabbler on the specifics here.
Of course, there are lots of ifs when it comes to PS2.
You could have a half-height front buffer to save memory for example. In that case you'll do a filter blit between back and front buffers instead of a simple swap to squash down the larger back buffer and get a flicker-fix effect at the same time. Also, a game might not neccessarily wait until the end of the frame before it swaps buffers (this happens more and more in games these days as it hides slow-down more easily but produces a tearing effect, particulary in sideways motions). You could also save the previous back buffer to read from in a blend to produce motion blur, etc... There's many possibilities and techniques.
Damn shame about the early Z-test.
Then again, it really has only been around since the days of DirectX 8.
It's not actually API-dependent. It's a hardware function that'll work regardless of DX version, or even without an API at all. For example, Gamecube's Flipper has a simple form of early Z-rejection...