Initial conversion to markdown
This commit is contained in:
parent
a96a114403
commit
5e10794a24
362 changed files with 67353 additions and 0 deletions
73
57-04.md
Normal file
73
57-04.md
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
------------------------ --------------------------------- --------------------
|
||||
[Previous](57-03.html) [Table of Contents](index.html) [Next](58-01.html)
|
||||
------------------------ --------------------------------- --------------------
|
||||
|
||||
Within Listing 57.2, all the important optimization is in the loop that
|
||||
draws across each destination scan line, near the end of the listing.
|
||||
One optimization is elimination of the call to the set-pixel routine
|
||||
used to draw each pixel in Listing 57.1. Function calls are expensive
|
||||
operations, to be avoided when performance matters. Also, although Mode
|
||||
X (the undocumented 320x240 256-color VGA mode X-Sharp runs in) doesn’t
|
||||
lend itself well to pixel-oriented operations like line drawing or
|
||||
texture mapping, the inner loop has been set up to minimize Mode X’s
|
||||
overhead. A rotating plane mask is maintained in AL, with DX pointing to
|
||||
the Map Mask register; thus, only a rotate and an **OUT** are required
|
||||
to select the plane to which to write, cycling from plane 0 through
|
||||
plane 3 and wrapping back to 0. Better yet, because we know that we’re
|
||||
simply stepping horizontally across the destination scan line, we can
|
||||
use a clever optimization to both step the destination and reduce the
|
||||
overhead of maintaining the mask. Two copies of the current plane mask
|
||||
are maintained, one in each nibble of AL. (The Map Mask register pays
|
||||
attention only to the lower nibble.) Then, when one copy rotates out of
|
||||
the lower nibble, the other copy rotates into the lower nibble and is
|
||||
ready to be used. This approach eliminates the need to test for the mask
|
||||
wrapping from plane 3 to plane 0, all the more so because a carry is
|
||||
generated when wrapping occurs, and that carry can be added to DI to
|
||||
advance the screen pointer. (Check out the next chapter, however, to see
|
||||
the best Map Mask optimization of all—setting it once and leaving it
|
||||
unchanged.)
|
||||
|
||||
In all, the overhead of drawing each pixel is reduced from a call to the
|
||||
set-pixel routine and full calculation of the screen address and plane
|
||||
mask to five instructions and no branches. This is an excellent example
|
||||
of converting full, from-scratch calculations to incremental processing,
|
||||
whereby only information that has changed since the last operation (the
|
||||
plane mask moving one pixel, for example) is recalculated.
|
||||
|
||||
Incremental processing and knowing where the cycles go are both
|
||||
important in the final optimization in Listing 57.2, speeding up the
|
||||
retrieval of pixels from the texture map. This operation looks very
|
||||
efficient in Listing 57.1, consisting of only two adds and the macro
|
||||
**GET- IMAGE-PIXEL**. However, those adds are fixed-point adds, so they
|
||||
take four instructions apiece, and the macro hides not only conversion
|
||||
from fixed-point to integer, but also a time-consuming multiplication.
|
||||
Incremental approaches are excellent at avoiding multiplication, because
|
||||
cumulative additions can often replace multiplication. That’s the case
|
||||
with stepping through the source texture in Listing 57.2; ten
|
||||
instructions, with a maximum of two branches, replace all the texture
|
||||
calculations of Listing 57.1. Listing 57.2 simply detects when the
|
||||
fractional part of the source x or y coordinate turns over and advances
|
||||
the source texture pointer accordingly.
|
||||
|
||||
As you might expect, all this optimization is pretty hard to implement,
|
||||
and makes Listing 57.2 much more complicated than Listing 57.1. Is it
|
||||
worth the trouble? Indeed it is. Listing 57.2 is more than twice as fast
|
||||
as Listing 57.1, and the difference is very noticeable when large,
|
||||
texture-mapped areas are animated. Whether more than doubling
|
||||
performance is significant is a matter of opinion, I suppose, but
|
||||
imagine that you’re in William Gibson’s *Neuromancer*, trying to crack a
|
||||
corporate database. Which texture-mapping routine would you rather have
|
||||
interfacing you to Cyberspace?
|
||||
|
||||
I’m always interested in getting your feedback on and hearing about
|
||||
potential improvements to X-Sharp. Contact me through the publisher.
|
||||
There is no truth to the rumor that I can be reached under the alias
|
||||
“sheep-shearer,” at least not for another 9,999 sheep.
|
||||
|
||||
------------------------ --------------------------------- --------------------
|
||||
[Previous](57-03.html) [Table of Contents](index.html) [Next](58-01.html)
|
||||
------------------------ --------------------------------- --------------------
|
||||
|
||||
* * * * *
|
||||
|
||||
Graphics Programming Black Book © 2001 Michael Abrash
|
||||
Loading…
Reference in a new issue