abrash-black-book/69-01.md
2013-12-30 20:26:41 +11:00

125 lines
7.1 KiB
Markdown

Chapter 69\
Surface Caching and Quake's Triangle Models {#Heading1}
--------------------------------------------
### Probing Hardware-Assisted Surfaces and Fast Model Animation Without Sprites {#Heading2}
In the late '70s, I spent a summer doing contract programming at a
government-funded installation called the Northeast Solar Energy Center
(NESEC). Those were heady times for solar energy, what with the oil
shortages, and there was lots of money being thrown at places like
NESEC, which was growing fast.
NESEC was across the street from MIT, which made for good access to
resources. Unfortunately, it also meant that NESEC was in a severely
parking-impaired part of the world, what with the student population and
Boston's chronic parking shortage. The NESEC building did have its own
parking lot, but it wasn't nearly big enough, because students parked in
it at every opportunity. The lot was posted, and cars periodically got
towed, but King Canute stood a better chance against the tide than NESEC
did against the student hordes, and late arrivals to work often had to
park blocks away and hike to work, to their considerable displeasure.
Back then, I drove an aging Volvo sedan that was sorely in need of a
ring job. It ran fine but burned a quart of oil every 250 miles, so I
carried a case of oil in the trunk, and checked the level frequently.
One day, walking to the computer center a couple of blocks away, I cut
through the parking lot and checked the oil in my car. It was low, so I
topped it off, left the empty oil can next to the car so I would see it
and remember to pick it up to throw out on my way back, and headed
toward the computer center.
I'd gone only a few hundred feet when I heard footsteps and shouting
behind me, and a wild-eyed man in a business suit came running up to me,
screaming. "It's bad enough you park in our lot, but now you're leaving
your garbage lying around!" he yelled. "Don't you people have any sense
of decency?" I told him I worked at NESEC and was going to pick up the
can on my way back, and he shouted, "Don't give me that!" I repeated my
statements, calmly, and told him who I worked for and where my office
was, and he said, "Don't give me that" again, but with a little less
certainty. I kept adding detail until it was obvious that I was telling
the truth, and he suddenly said, "Oh, my God," turned red, and started
to apologize profusely. A few days later, we passed in the hallway, and
he didn't look me in the eye.
The interesting point is that there was really no useful outcome that
could have resulted from his outburst. Suppose I had been a student—what
would he have accomplished by yelling at me? He let his emotions
overrule his common sense, and as a result, did something he later
wished he hadn't. I've seen many programmers do the same thing,
especially when they're working long hours and not feeling adequately
appreciated. For example, some time back I got mail from a programmer
who complained bitterly that although he was critical to his company's
success, management didn't appreciate his hard work and talent, and
asked if I could help him find a better job. I suggested several ways
that he might look for another job, but also asked if he had tried
working his problems out with his employers; if he really was that
valuable, what did he have to lose? He admitted he hadn't, and recently
he wrote back and said that he had talked to his boss, and now he was
getting paid a lot more money, was getting credit for his work, and was
just flat-out happy.
We programmers think of ourselves as rational creatures, but most of us
get angry at times, and when we do, like everyone else, we tend to be
driven by our emotions instead of our minds. It's my experience that
thinking rationally under those circumstances can be difficult, but
produces better long-term results every time—so if you find yourself in
that situation, stay cool and think your way through it, and odds are
you'll be happier down the road.
Of course, most of the time programmers really *are* rational creatures,
and the more information we have, the better. In that spirit, let's look
at more of the stuff that makes Quake tick, starting with what I've
recently learned about surface caching.
### Surface Caching with Hardware Assistance {#Heading3}
In Chapter 68, I discussed in detail the surface caching technique that
Quake uses to do detailed, high-quality lighting without lots of
polygons. Since writing that chapter, I've gone further, and spent a
considerable amount of time working on the port of Quake to Rendition's
Verite 3-D accelerator chip. So let me start off this chapter by
discussing what I've learned about using surface caching in conjunction
with hardware.
As you'll recall, the key to surface caching is that lighting
information and polygon detail are stored separately, with lighting not
tied to polygon vertices, then combined on demand into what I call
*surfaces*: lit, textured rectangles that are used as the input to the
texture mapper. Building surfaces takes time, so performance is enhanced
by caching the surfaces from one frame to the next. As I pointed out in
Chapter 68, 3-D hardware accelerators are designed to optimize Gouraud
shading, but surface caching can also work on hardware accelerators,
with some significant quality advantages.
The surface-caching architecture of the Verite version of Quake (which
we call VQuake) is essentially the same as in the software-only version
of Quake: The CPU builds surfaces on demand, which are then downloaded
to the accelerator's memory and cached there. There are a couple of key
differences, however: the need to download surfaces, and the requirement
that the surfaces be in 16-bit-per-pixel (bpp) format.
Downloading surfaces to the accelerator is a performance hit that
doesn't exist in the software-only version. Although Verite uses DMA to
download surfaces, DMA does in fact steal performance from the CPU. This
cost is increased by the requirement for 16-bpp surfaces, because twice
as much data must be downloaded. Worse still, it takes about twice as
long to build 16-bpp surfaces as 8-bpp surfaces, so the cost of missing
the surface cache is well over twice as expensive in VQuake as in Quake.
Fortunately, there's 4 MB of memory on Verite-based adapters, so the
surface cache doesn't miss very often and VQuake runs fine (and looks
very good, thanks to bilinear texture filtering, which by itself is
pretty much worth the cost of 3-D hardware), but it's nonetheless true
that a completely straightforward port of the surface-caching model is
not as appealing for hardware as for software. This is especially true
at high resolutions, where the needs of the surface cache increase due
to more detailed surfaces but available memory decreases due to frame
buffer size.
Does my recent experience indicate that as the PC market moves to
hardware, there's no choice but to move to Gouraud shading, despite the
quality issues? Not at all. First of all, surface caching does still
work well, just not as relatively well compared to Gouraud shading as is
the case in software. Second, there are at least two alternatives that
preserve the advantages of surface caching without many of the
disadvantages noted above.