Test Cases:

	Basically, testing the 20 rendering modes is most important, once
	we have exercised all 20 modes, must see which path has not been
	sufficiently exercised and why.

	20 rendering mode cases

		aa+z opaque surf

			surf correlation:
				in range, summed cvg <= 1.0: merge color, sum
				cvg, update z

			non surf correlation:
				< far side of range, cvg > 1.0: in front of
				fb surf, non correlated. update color, replace
				cvg, replace z.

				< near side of range, cvg < 1.0: update color,
				replace cvg, replace z.

			zbuffered out:
				> far side of range: zbuffered out.

		aa+nz opaque surf

			Let 2nd pass filter does everything. Must render
			painters back to front. just write color and sum/wrap
			coverage.

		pt+z opaque surf

????			don't sum coverage?

		pt+nz opaque surf
		
			same as aa+nz except turn off 2nd pass filter.

		DO THIS EXERCISE FOR THE REMAINING 16 MODES

	color blend

		test all mux selections for blending parameters. Can do
		RGB channels at once.

		when bsel == 1, check norm A and B range
			negative clamps to 0

		check generalized blend eq ((a*b)+(c*d))/(e+f). Make sure
		 a lerp bias toward 1.0 for range represenation

		check for cases of mux
			force_blend
			color_on_cvg && !cvg_wrap
			blend_en && blend_mask

		2 cycle mode - especially fogged/blended w/fb pixel like a
			transparent fogged surf

	coverage blend

		interpenetration coverage scaling logic

		selection of interp or non interp scaled cvg

		we_cvg generation

		cvg_wrap

		cvg summation in different cvg_dest and blend_en modes


	blender we

		check all of the following enables with respect to input
		combinations

		blend_en
		span_color_we
		span_depth_we

Misc Info:

blend.txt

This document describes in tabular form the functions of the blend unit,
excluding alpha compare and masking.

This is the high-level what's-supposed-to-happen-when for the antialiased
z-buffer modes:

color_write_enable:	    blend_enable:	      z_write_enable:

transparent line mode:
(old_depth == MAX_Z) ||	    1 (always LERP)	      0 (never write)
(new_depth < old_depth)

decal line mode:
(old_depth != MAX_Z) &&	    1 (always LERP)	      0 (never write)
((new_depth-delta) <=
 old_depth) &&
((new_depth+delta) >=
 old_depth)

opaque surface mode:
(old_depth == MAX_Z) ||	    ((new_depth+delta) >=     color_write_enable
(((ncvg+ocvg) <= 7) &&	     old_depth) &&
 ((new_depth-delta) <=	    ((ncvg+ocvg) <= 7) &&
  old_depth)) ||	    en_antialias
(((ncvg+ocvg) > 7) &&
 (new_depth < old_depth))

transparent surface mode:
(old_depth == MAX_Z) ||	    1 (LERP if wrap cvg,      0 (never write)
(new_depth < old_depth)        else save color)

decal surface mode:
(old_depth != MAX_Z) &&	    ((new_depth+delta) >=     0 (never write)
((new_depth-delta) <=	     old_depth) &&
 old_depth) &&		    ((ncvg+ocvg) <= 7) &&
((new_depth+delta) >=	    en_antialias
 old_depth)

output_cvg:				a:	b:	p:	m:

transparent line mode:
min(FULL_CVG,				alpha*	1-a	pixel	memory
    alpha*ncvg + ocvg)			ncvg		color	color

decal line mode:
ocvg					alpha*	1-a	pixel	memory
					ncvg		color	color

opaque surface mode:
(!blend_enable &&			ncvg	ocvg	pixel	memory
 (ncvg-1)) ||						color	color
(blend_enable &&
 (ncvg+ocvg))

transparent surface mode:
(ncvg+ocvg)&7	    ((ncvg+ocvg) > 7):  alpha	1-a	pixel	memory
		    ((ncvg+ocvg) <= 7): 0	1-a	color	color

decal surface mode:
(ncvg+ocvg)&7				ncvg	ocvg	pixel	memory
							color	color

In addition to the eight 2-bit blend mux selects, the following are the
mode bits for the blend unit:

blend_mask[7:0]:	mask for blended part of indexed pixel
alpha_compare_enable:	condition color write enable on alpha compare
dither_alpha_enable:	alpha dithering with pseudo-random noise
z_source_select:	select between primitive z and pixel z
antialias_enable:	if not force blend, allow blend enable - use cvg bits
z_compare_enable:	condition color write enable on depth comparison
z_update_enable:	enable writing of z if color write enabled
image_read_enable:	enable color/cvg read/modify/write memory access
cvg_dest[1:0]:		0) clamp (normal)
			1) wrap (was assume_full_cvg)
			2) zap (force to full cvg)
			3) save (don't overwrite memory cvg)
color_on_cvg:		only update color on cvg overflow (transp surf)
cvg_times_alpha:	use alpha times cvg for pixel alpha and cvg
alpha_cvg_select:	use cvg (or alpha*cvg) for pixel alpha
force_blend:		force blend enable
z_mode:			0) opaque
			1) interpenetrating
			2) transparent
			3) decal
texture_edge_mode:	enable texture edges (must also use cvg_times_alpha)

Truth table:		antialiased zbuffer	antialiased non-zbuffer
			transparent line	transparent line
			  decal line		  decal line
			    opaque surface	    opaque surface (9)
			      transparent surface     transparent surface
				decal surface (8)
				  transparent decal
				    interpenetration (1)
				      trans interpen
					texture edge	texture edge (2)
antialias_enable:	1 1 1 1 1 1 1 1 1	1 1 1 1 1
z_compare_enable:	1 1 1 1 1 1 1 1 1	0 0 0 0 0
z_update_enable:	0 0 1 0 0 0 1 0 1	0 0 0 0 0
image_read_enable:	1 1 1 1 1 1 1 1 1	1 1 1 1 1
cvg_dest:		0 3 0 1 0 1 0 1 0	0 2 1 1 1
color_on_cvg:		0 0 0 1 0 1 0 1 0	0 0 0 1 0 (4)
cvg_times_alpha:	1 1 0 0 0 0 0 0 1	1 1 0 0 1 (5)
alpha_cvg_select:	1 1 1 0 1 0 1 0 1	1 1 0 0 1
force_blend:		1 1 0 1 0 1 0 1 0	1 1 1 1 1 (6)
z_mode:			2 3 0 2 3 3 1 1 0	0 0 0 0 0
texture_edge_mode:	0 0 0 0 0 0 0 0 1	0 0 0 0 1 (7)

			point sampled zbuffer	point sampled non-zbuffer
			opaque surface		opaque surface (9)
			  transparent surface	  transparent surface
			    decal surface
			      transparent decal
antialias_enable:	0 0 0 0			0 0
z_compare_enable:	1 1 1 1			0 0
z_update_enable:	1 0 0 0			0 0
image_read_enable:	0 1 0 1			0 1
cvg_dest:		2 2 2 2			2 2 (3)
color_on_cvg:		0 0 0 0			0 0
cvg_times_alpha:	0 0 0 0			0 0 (5)
alpha_cvg_select:	1 0 1 0			0 0
force_blend:		0 1 0 1			1 1 (6)
z_mode:			0 2 3 3			0 0
texture_edge_mode:	0 0 0 0			0 0

[ Notes:
 (1) Interpenetration is only meaningful in antialiased zbuffered mode.
 (2) Texture_edge_mode is only meaningful in antialiased modes. In
     point sampled modes, alpha_compare_enable with 128 should be used
     instead, with the mode bits set for an opaque surface.
 (3) Always zap coverage in point sampled modes.
 (4) If color_on_cvg, must also force_blend.
 (5) If not cvg_times_alpha and alpha_cvg_select, must not force_blend.
 (6) Always force_blend on non-zbuffered modes.
 (7) If texture_edge_mode, must also cvg_times_alpha and alpha_cvg_select. ]
 (8) In opaque surface mode, clamp/new cvg_dest mode works better on the 
     edges of a decalled surface which closely corresponds to the edge of
     the underlying surface.  If the decalled surface will extend far (more
     than one pixel on average) beyond the underlying surface, use cvg_dest
     mode 1 (wrap) for better results.
 (9) To place new color regardless of wrap condition, use force blend with
     p=don't care;  m=pixel_color;  a=0;  b=0xFF;

					- Phil Gossett
					  8/23/94
					- modified by Acorn 9/20/94

FOR QUICK REFERENCE:
             antialias_enable
             | z_compare_enable
             | | z_update_enable
             | | | image_read_enable
             | | | | cvg_dest
             | | | | | color_on_cvg
             | | | | | | cvg_times_alpha
             | | | | | | | alpha_cvg_select
             | | | | | | | | force_blend
             | | | | | | | | | z_mode
             | | | | | | | | | | texture_edge_mode
             | | | | | | | | | | | 
mode         | | | | | | | | | | |  p         m         a           b
------------ - - - - - - - - - - -  --------- --------- ----------- -------
AA ZBUF
trans line   1 1 0 1 0 0 1 1 1 2 0  (0)pixcol (1)memcol (0)pixA*cvg (0)1-a
decal line   1 1 0 1 3 0 1 1 1 3 0  (0)pixcol (1)memcol (0)pixA*cvg (0)1-a
opaque surf  1 1 1 1 0 0 0 1 0 0 0  (0)pixcol (1)memcol (0)pixcvg   (1)memcvg
trans surf   1 1 0 1 1 1 0 0 1 2 0  (0)pixcol (1)memcol (0)pixA     (0)1-a
decal surf   1 1 0 1 1 0 0 1 0 3 0  (0)pixcol (1)memcol (0)pixcvg   (1)memcvg
trans decal  1 1 0 1 1 1 0 0 1 3 0  (0)pixcol (1)memcol (0)pixA     (0)1-a
interpen     1 1 1 1 0 0 0 1 0 1 0  (0)pixcol (1)memcol (0)pixcvg   (1)memcvg
trans interp 1 1 0 1 1 1 0 0 1 1 0  (0)pixcol (1)memcol (0)pixA     (0)1-a
texture edge 1 1 1 1 0 0 1 1 0 0 1  (0)pixcol (1)memcol (0)pixcvg   (1)memcvg

AA NONZ
trans line   1 0 0 1 0 0 1 1 1 0 0  (0)pixcol (1)memcol (0)pixA*cvg (0)1-a
decal line   1 0 0 1 2 0 1 1 1 0 0  (0)pixcol (1)memcol (0)pixA*cvg (0)1-a
opaque surf  1 0 0 1 1 0 0 0 1 0 0  (0)*DC*   (0)pixcol (3)zero     (2)one
trans surf   1 0 0 1 1 1 0 0 1 0 0  (0)pixcol (1)memcol (0)pixA     (0)1-a
texture edge 1 0 0 1 1 0 1 1 1 0 1  (0)*DC*   (0)pixcol (3)zero     (2)one
   
PT ZBUF
opaque surf  0 1 1 0 2 0 0 1 0 0 0  (0)pixcol (1)memcol (0)pixcvg   (1)memcvg
trans surf   0 1 0 1 2 0 0 0 1 2 0  (0)pixcol (1)memcol (0)pixA     (0)1-a
decal surf   0 1 0 0 2 0 0 1 0 3 0  (0)pixcol (1)memcol (0)pixcvg   (1)memcvg
trans decal  0 1 0 1 2 0 0 0 1 3 0  (0)pixcol (1)memcol (0)pixA     (0)1-a

PT NONZ
opaque surf  0 0 0 0 2 0 0 0 1 0 0  (0)*DC*   (0)pixcol (3)zero     (2)one
trans surf   0 0 0 1 2 0 0 0 1 0 0  (0)pixcol (1)memcol (0)pixA     (0)1-a