Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

773 lines
27 KiB

///////////////////////////////////////////////////////////////////////////////
// Copyright (C) Microsoft Corporation, 1998.
//
// refrasti.hpp
//
// Direct3D Reference Rasterizer - Main Internal Header File
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _REFRASTI_HPP
#define _REFRASTI_HPP
///////////////////////////////////////////////////////////////////////////////
// //
// Pixel Component Classes //
// //
///////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// Color Component Class - Class used for color channel (alpha & rgb)
// processing.
//
// Internal format is single precision floating point. The 1.0 value maps
// to 0xff for 8 bit color.
//
//-----------------------------------------------------------------------------
class RRColorComp
{
FLOAT m_fVal;
public:
// default, UINT8, & FLOAT assignment constructor
RRColorComp(void) : m_fVal(0.F) {;}
RRColorComp(UINT8 uVal) : m_fVal((FLOAT)uVal/255.F) {;}
RRColorComp(FLOAT fVal) : m_fVal(fVal) {;}
// copy and assignment operators
RRColorComp& operator=(const RRColorComp& A) { m_fVal = A.m_fVal; return *this; }
RRColorComp& operator=(UINT8 uVal) { m_fVal = (1.f/255.f)*(FLOAT)uVal; return *this; }
RRColorComp& operator=(FLOAT fVal) { m_fVal = fVal; return *this; }
// round for integer get operations
operator UINT8() const { return (UINT8)( ( (255.f)*m_fVal) + .5f); }
operator unsigned() const { return (unsigned)( ( (255.f)*m_fVal ) + .5f); }
operator FLOAT() const { return m_fVal; }
// fixed point get function - specify number of integral and fractional bits
INT32 GetFixed( int iIntBits, int iFracBits ) const
{
// float value is in 0. to 1. range, so scale up by the total number of
// bits (the '-1' does the mapping such that (2**n)-1 is the max representable
// value, for example 0xff is max for 8 integral bits (not 0x100))
return (INT32)( ( m_fVal * (FLOAT)((1<<(iIntBits+iFracBits))-1) ) + .5f);
}
//
// overloaded arithmetic operators - not much going on here for floating
// point (would be much more interesting if internal representation was
// fixed point)
//
// use compliment operator for component inverse (1. - value)
friend RRColorComp operator~(const RRColorComp& A)
{
return RRColorComp( 1.F - A.m_fVal );
}
friend RRColorComp operator+(const RRColorComp& A, const RRColorComp& B)
{
return RRColorComp( A.m_fVal + B.m_fVal );
}
RRColorComp& operator+=(const RRColorComp& A)
{
m_fVal += A.m_fVal; return *this;
}
friend RRColorComp operator-(const RRColorComp& A, const RRColorComp& B)
{
return RRColorComp( A.m_fVal - B.m_fVal );
}
friend RRColorComp operator-(const RRColorComp& A, FLOAT fB)
{
return RRColorComp( A.m_fVal - fB );
}
friend RRColorComp operator*(const RRColorComp& A, const RRColorComp& B)
{
return RRColorComp( A.m_fVal * B.m_fVal );
}
friend RRColorComp operator*(const RRColorComp& A, FLOAT fB)
{
return RRColorComp( A.m_fVal * fB );
}
RRColorComp& operator*=(const RRColorComp& A)
{
m_fVal *= A.m_fVal; return *this;
}
RRColorComp& operator*=(const UINT8 uA)
{
m_fVal *= ((1./255.)*(FLOAT)uA); return *this;
}
friend RRColorComp minimum(const RRColorComp& A, const RRColorComp& B)
{
return RRColorComp( min( A.m_fVal, B.m_fVal ) );
}
friend RRColorComp maximum(const RRColorComp& A, const RRColorComp& B)
{
return RRColorComp( max( A.m_fVal, B.m_fVal ) );
}
};
//-----------------------------------------------------------------------------
//
// Color Value Class - Holds an Alpha,Red,Green,Blue color value consisting of
// four RRColorComp objects.
//
//-----------------------------------------------------------------------------
class RRColor
{
public:
RRColorComp A;
RRColorComp R;
RRColorComp G;
RRColorComp B;
// default and UINT32 assignment constructor
RRColor( void ) : A(0.F), R(0.F), G(0.F), B(0.F) {;}
RRColor( UINT32 uVal ) :
A (UINT8( RGBA_GETALPHA( uVal ) )),
R (UINT8( RGBA_GETRED( uVal ) )),
G (UINT8( RGBA_GETGREEN( uVal ) )),
B (UINT8( RGBA_GETBLUE( uVal ) )) {;}
RRColor( FLOAT fR, FLOAT fG, FLOAT fB, FLOAT fA ) :
R(fR), G(fG), B(fB), A(fA) {;}
// UINT32 copy operator
void operator=(const UINT32 uVal) // TODO: implement proper assignment operator?
{
A = UINT8( RGBA_GETALPHA( uVal ) );
R = UINT8( RGBA_GETRED( uVal ) );
G = UINT8( RGBA_GETGREEN( uVal ) );
B = UINT8( RGBA_GETBLUE( uVal ) );
}
// casting operator
operator UINT32() const
{
return D3DRGBA( FLOAT(R), FLOAT(G), FLOAT(B), FLOAT(A) );
}
// methods to set all channels
void SetAllChannels( const RRColorComp& Val )
{
A = Val; R = Val; G = Val; B = Val;
}
void SetAllChannels( FLOAT fVal )
{
A = fVal; R = fVal; G = fVal; B = fVal;
}
//
// conversions between surface format and RRColor - these define the
// correct way to map between resolutions
//
// convert from surface type format to RRColor
void ConvertFrom( RRSurfaceType Type, const char* pSurfaceBits )
{
UINT16 u16BITS;
switch (Type)
{
default:
case RR_STYPE_NULL: return;
case RR_STYPE_B8G8R8A8: *this = *((UINT32*)pSurfaceBits); break;
case RR_STYPE_B8G8R8X8: *this = *((UINT32*)pSurfaceBits); A = 1.F; break;
case RR_STYPE_B5G6R5:
u16BITS = *((UINT16*)pSurfaceBits);
R = ((u16BITS>>(6+5)) & 0x001F)/31.f;
G = ((u16BITS>> 5) & 0x003F)/63.f;
B = ((u16BITS ) & 0x001F)/31.f;
A = 1.F;
break;
case RR_STYPE_B5G5R5:
u16BITS = *((UINT16*)pSurfaceBits);
R = ((u16BITS>>(5+5)) & 0x001F)/31.f;
G = ((u16BITS>> 5) & 0x001F)/31.f;
B = ((u16BITS ) & 0x001F)/31.f;
A = 1.F;
break;
case RR_STYPE_B5G5R5A1:
u16BITS = *((UINT16*)pSurfaceBits);
R = ((u16BITS>>(5+5)) & 0x001F)/31.f;
G = ((u16BITS>> 5) & 0x001F)/31.f;
B = ((u16BITS ) & 0x001F)/31.f;
A = ( u16BITS & 0x8000 ) ? 1.f : 0.f;
break;
case RR_STYPE_B4G4R4A4:
u16BITS = *((UINT16*)pSurfaceBits);
R = ((u16BITS>>(4+4)) & 0x000F)/15.f;
G = ((u16BITS>> 4) & 0x000F)/15.f;
B = ((u16BITS ) & 0x000F)/15.f;
A = ((u16BITS>>(4+4+4)) & 0x000F)/15.f;
break;
case RR_STYPE_B8G8R8:
R = *((UINT8*)pSurfaceBits+2);
G = *((UINT8*)pSurfaceBits+1);
B = *((UINT8*)pSurfaceBits+0);
A = 1.F;
break;
case RR_STYPE_L8:
R = G = B = *((UINT8*)pSurfaceBits);
A = 1.F;
break;
case RR_STYPE_L8A8:
u16BITS = *((UINT16*)pSurfaceBits);
R = G = B = (UINT8)(0xff & u16BITS);
A = (UINT8)(0xff & (u16BITS >> 8));
break;
case RR_STYPE_B2G3R3:
u16BITS = *((UINT8*)pSurfaceBits);
R = ((u16BITS>>(3+2)) & 0x07)/7.f;
G = ((u16BITS>> 2) & 0x07)/7.f;
B = ((u16BITS ) & 0x03)/3.f;
A = 1.F;
break;
case RR_STYPE_L4A4:
u16BITS = *((UINT8*)pSurfaceBits);
R = G = B = (u16BITS & 0x0f)/15.f;
A = ((u16BITS>>4) & 0x0f)/15.f;
break;
case RR_STYPE_B2G3R3A8:
u16BITS = *((UINT16*)pSurfaceBits);
R = ((u16BITS>>(3+2)) & 0x07)/7.f;
G = ((u16BITS>> 2) & 0x07)/7.f;
B = ((u16BITS ) & 0x03)/3.f;
A = (UINT8)(0xff & (u16BITS >> 8));
break;
case RR_STYPE_U8V8:
{
INT8 iDU = *(( INT8*)pSurfaceBits+0);
INT8 iDV = *(( INT8*)pSurfaceBits+1);
// signed values are normalized with 2^(N-1), since -2^(N-1) can
// be exactly expressed in N bits
R = (FLOAT)iDU * (1.0F/128.0F); // fDU
G = (FLOAT)iDV * (1.0F/128.0F); // fDV
B = 1.0F; // fL
}
break;
case RR_STYPE_U5V5L6:
{
UINT16 u16BITS = *((UINT16*)pSurfaceBits);
INT8 iDU = (INT8)(u16BITS & 0x1f);
INT8 iDV = (INT8)((u16BITS>>5) & 0x1f);
UINT8 uL = (UINT8)(u16BITS >> 10);
iDU <<= 3; iDU >>= 3; // sign extension
iDV <<= 3; iDV >>= 3;
// signed values are normalized with 2^(N-1), since -2^(N-1) can
// be exactly expressed in N bits
R = (FLOAT)iDU * (1.0F/16.0F); // fDU
G = (FLOAT)iDV * (1.0F/16.0F); // fDV
// the unsigned uL is normalized with 2^N - 1, since this is the
// largest representable value
B = (FLOAT)uL * (1.0F/63.0F); // fL
}
break;
case RR_STYPE_U8V8L8:
{
INT8 iDU = *(( INT8*)pSurfaceBits+0);
INT8 iDV = *(( INT8*)pSurfaceBits+1);
UINT8 uL = *((UINT8*)pSurfaceBits+2);
// signed values are normalized with 2^(N-1), since -2^(N-1) can
// be exactly expressed in N bits
R = (FLOAT)iDU * (1.0F/128.0F); // fDU
G = (FLOAT)iDV * (1.0F/128.0F); // fDV
// the unsigned uL is normalized with 2^N - 1, since this is the
// largest representable value
B = (FLOAT)uL * (1.0F/255.0F); // fL
}
break;
// shadow map texture formats (read only, not needed for ConvertTo)
case RR_STYPE_Z16S0:
{
UINT16 u16BITS = *((UINT16*)pSurfaceBits);
R = 0.0F;
G = (FLOAT)u16BITS * (1.0F/(FLOAT)0xffff);
B = 0.0F;
}
break;
case RR_STYPE_Z24S8:
case RR_STYPE_Z24S4:
{
UINT32 u32BITS = *((UINT32*)pSurfaceBits);
R = 0.0F;
G = (FLOAT)(u32BITS>>8) * (1.0F/(FLOAT)0xffffff);
B = 0.0F;
}
break;
case RR_STYPE_S8Z24:
case RR_STYPE_S4Z24:
{
UINT32 u32BITS = *((UINT32*)pSurfaceBits);
R = 0.0F;
G = (FLOAT)(u32BITS&0x00ffffff) * (1.0F/(FLOAT)0xffffff);
B = 0.0F;
}
break;
case RR_STYPE_Z15S1:
{
UINT16 u16BITS = *((UINT16*)pSurfaceBits);
R = 0.0F;
G = (FLOAT)(u16BITS>>1) * (1.0F/(FLOAT)0x7fff);
B = 0.0F;
}
break;
case RR_STYPE_S1Z15:
{
UINT16 u16BITS = *((UINT16*)pSurfaceBits);
R = 0.0F;
G = (FLOAT)(u16BITS&0x7fff) * (1.0F/(FLOAT)0x7fff);
B = 0.0F;
}
break;
case RR_STYPE_Z32S0:
{
UINT32 u32BITS = *((UINT32*)pSurfaceBits);
R = 0.0F;
G = (FLOAT)u32BITS * (1.0F/(FLOAT)0xffffffff);
B = 0.0F;
}
break;
}
}
// Convert surface type format to RRColor
void ConvertTo( RRSurfaceType Type, float fRoundOffset, char* pSurfaceBits ) const
{
int iR, iG, iB, iA;
switch (Type)
{
case RR_STYPE_B8G8R8A8:
*((UINT8*)pSurfaceBits+0) = (UINT8)((FLOAT)B * 255. + fRoundOffset);
*((UINT8*)pSurfaceBits+1) = (UINT8)((FLOAT)G * 255. + fRoundOffset);
*((UINT8*)pSurfaceBits+2) = (UINT8)((FLOAT)R * 255. + fRoundOffset);
*((UINT8*)pSurfaceBits+3) = (UINT8)((FLOAT)A * 255. + fRoundOffset);
break;
case RR_STYPE_B8G8R8X8:
*((UINT8*)pSurfaceBits+0) = (UINT8)((FLOAT)B * 255. + fRoundOffset);
*((UINT8*)pSurfaceBits+1) = (UINT8)((FLOAT)G * 255. + fRoundOffset);
*((UINT8*)pSurfaceBits+2) = (UINT8)((FLOAT)R * 255. + fRoundOffset);
*((UINT8*)pSurfaceBits+3) = 0x00;
break;
case RR_STYPE_B8G8R8:
*((UINT8*)pSurfaceBits+0) = (UINT8)((FLOAT)B * 255. + fRoundOffset);
*((UINT8*)pSurfaceBits+1) = (UINT8)((FLOAT)G * 255. + fRoundOffset);
*((UINT8*)pSurfaceBits+2) = (UINT8)((FLOAT)R * 255. + fRoundOffset);
break;
case RR_STYPE_B4G4R4A4:
iA = (FLOAT)A * 15. + fRoundOffset;
iR = (FLOAT)R * 15. + fRoundOffset;
iG = (FLOAT)G * 15. + fRoundOffset;
iB = (FLOAT)B * 15. + fRoundOffset;
*((UINT16*)pSurfaceBits) = (iA<<12) | (iR<<8) | (iG<<4) | iB;
break;
case RR_STYPE_B5G6R5:
iR = (FLOAT)R * 31. + fRoundOffset; // apply rounding bias then truncate
iG = (FLOAT)G * 63. + fRoundOffset;
iB = (FLOAT)B * 31. + fRoundOffset;
*((UINT16*)pSurfaceBits) = (iR<<11) | (iG<<5) | iB;
break;
case RR_STYPE_B5G5R5A1:
iA = (FLOAT)A * 1. + fRoundOffset;
iR = (FLOAT)R * 31. + fRoundOffset;
iG = (FLOAT)G * 31. + fRoundOffset;
iB = (FLOAT)B * 31. + fRoundOffset;
*((UINT16*)pSurfaceBits) = (iA<<15) | (iR<<10) | (iG<<5) | iB;
break;
case RR_STYPE_B5G5R5:
iR = (FLOAT)R * 31. + fRoundOffset;
iG = (FLOAT)G * 31. + fRoundOffset;
iB = (FLOAT)B * 31. + fRoundOffset;
*((UINT16*)pSurfaceBits) = (iR<<10) | (iG<<5) | iB;
break;
case RR_STYPE_B2G3R3:
iR = (FLOAT)R * 7. + fRoundOffset;
iG = (FLOAT)G * 7. + fRoundOffset;
iB = (FLOAT)B * 3. + fRoundOffset;
*((UINT8*)pSurfaceBits) = (iR<<5) | (iG<<2) | iB;
break;
}
}
};
//-----------------------------------------------------------------------------
//
// RRDepth - Class for storing and manipulating pixel depth values. Underlying
// storage is a double precision floating point, which has sufficient precision
// and range to support 16 and 32 bit fixed point and 32 bit floating point.
//
// The UINT32 methods receive a 24 or 32 bit value, and the UINT16
// methods receive a 15 or 16 bit value.
//
//-----------------------------------------------------------------------------
class RRDepth
{
DOUBLE m_dVal;
RRSurfaceType m_DepthSType;
DOUBLE dGetValClamped(void) const { return min(1.,max(0.,m_dVal)); }
DOUBLE dGetCnvScale(void) const
{
switch(m_DepthSType)
{
case RR_STYPE_Z16S0:
return DOUBLE((1<<16)-1);
case RR_STYPE_Z24S8:
case RR_STYPE_S8Z24:
case RR_STYPE_Z24S4:
case RR_STYPE_S4Z24:
return DOUBLE((1<<24)-1);
case RR_STYPE_Z15S1:
case RR_STYPE_S1Z15:
return DOUBLE((1<<15)-1);
case RR_STYPE_Z32S0:
return DOUBLE(0xffffffff); // too big to be generated as above without INT64's
default:
DPFRR(0, "RRDepth not initialized correctly");
return DOUBLE(0.0);
}
}
public:
// default and UINT16/32 assignment constructor
// default only for Pixel class, and requires that SetSType be called later
RRDepth() : m_dVal(0.F), m_DepthSType(RR_STYPE_NULL) {;}
RRDepth(RRSurfaceType SType) : m_dVal(0.F), m_DepthSType(SType) {;}
RRDepth(UINT16 uVal, RRSurfaceType SType): m_DepthSType(SType), m_dVal((DOUBLE)uVal/dGetCnvScale()) {;}
RRDepth(UINT32 uVal, RRSurfaceType SType): m_DepthSType(SType), m_dVal((DOUBLE)uVal/dGetCnvScale()) {;}
// copy and assignment operators
RRDepth& operator=(const RRDepth& A) { m_dVal = A.m_dVal; m_DepthSType = A.m_DepthSType; return *this; }
RRDepth& operator=(UINT16 uVal) { m_dVal = (DOUBLE)uVal/dGetCnvScale(); return *this; }
RRDepth& operator=(UINT32 uVal) { m_dVal = (DOUBLE)uVal/dGetCnvScale(); return *this; }
RRDepth& operator=(FLOAT fVal) { m_dVal = (DOUBLE)fVal; return *this; }
// round for integer get operations
operator UINT16() const { return (UINT16)( (dGetValClamped()*dGetCnvScale()) + .5); }
operator UINT32() const { return (UINT32)( (dGetValClamped()*dGetCnvScale()) + .5); }
operator DOUBLE() const { return dGetValClamped(); }
operator FLOAT() const { return (FLOAT)dGetValClamped(); }
void SetSType(RRSurfaceType SType) { m_DepthSType = SType; }
RRSurfaceType GetSType(void) const { return m_DepthSType; }
};
//-----------------------------------------------------------------------------
//
// RRPixel - Class for encapsulation of all pixel information passed from
// scan conversion to pixel and fragment processing.
//
//-----------------------------------------------------------------------------
class RRPixel
{
public:
INT16 iX; // pixel location
INT16 iY; //
RRColor Color; // pixel diffuse color
RRColor Specular; // pixel specular color (rgb only - alpha unused)
RRDepth Depth; // pixel depth
FLOAT fW; // pixel W value (unnormalized)
RRColorComp FogIntensity; // fog intensity (scalar)
RRCvgMask CvgMask; // coverage mask
};
///////////////////////////////////////////////////////////////////////////////
// //
// Setup & Scan Convert //
// //
///////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// Scan Converter State - Holds input and current state of scan converter.
// Filled in by setup.
//
//-----------------------------------------------------------------------------
struct _RRSCANCNVSTATE
{
// primitive vertex data
FLOAT fX0, fY0, fRHW0;
FLOAT fX1, fY1, fRHW1;
FLOAT fX2, fY2, fRHW2;
// primitive transformed texture coord data
FLOAT fTexCoord[D3DHAL_TSS_MAXSTAGES][3][4];
FLOAT fRHQW[D3DHAL_TSS_MAXSTAGES][3];
BOOL bWrap[D3DHAL_TSS_MAXSTAGES][4];
// x,y deltas
FLOAT fDelX10, fDelX02, fDelX21;
FLOAT fDelY01, fDelY20, fDelY12;
// triangle edge functions and gradient data
RREdgeFunc EdgeFuncs[4]; // A,B,C values and A,B sign bits for 4 edges
// the fourth edge is only used to scan convert points
// triangle bounding box
INT16 iXMin, iXMax;
INT16 iYMin, iYMax;
// line drawing data
INT64 iLineEdgeFunc[3]; // line function: Pminor = ([0]*Pmajor + [1])/[2]
BOOL bXMajor; // TRUE if X major; else Y major
INT16 iLineMin, iLineMax; // min and max pixel extent in major direction
INT16 iLineStep; // +1 or -1 depending on line major direction
// depth range for primitive (for clamp when sampling outside primitive area)
// may be Z or W
FLOAT fDepthMin, fDepthMax;
//
// attribute functions - static (per-primitive) data, non-texture,
// and texture functions
//
RRAttribFuncStatic AttribFuncStatic;
#define ATTRFUNC_R 0
#define ATTRFUNC_G 1
#define ATTRFUNC_B 2
#define ATTRFUNC_A 3
#define ATTRFUNC_SR 4
#define ATTRFUNC_SG 5
#define ATTRFUNC_SB 6
#define ATTRFUNC_SA 7
#define ATTRFUNC_F 8
#define ATTRFUNC_Z 9
#define RR_N_ATTRIBS 10
RRAttribFunc AttribFuncs[RR_N_ATTRIBS];
#define TEXFUNC_0 0
#define TEXFUNC_1 1
#define TEXFUNC_2 2
#define TEXFUNC_3 3
#define RR_N_TEX_ATTRIBS 4
RRAttribFunc TextureFuncs[D3DHAL_TSS_MAXSTAGES][RR_N_TEX_ATTRIBS];
//
// per-pixel data
//
// current position
INT16 iX,iY;
};
//-----------------------------------------------------------------------------
//
// Texture
//
//-----------------------------------------------------------------------------
//
// structure containing texture coordinate and gradient information
// for lookup and filtering
//
class RRTextureCoord
{
public:
FLOAT fU; // texture coordinate
FLOAT fV;
FLOAT fDUDX; // texture gradient dU/dX
FLOAT fDUDY; // texture gradient dU/dY
FLOAT fDVDX; // texture gradient dV/dX
FLOAT fDVDY; // texture gradient dV/dY
};
//
// structure containing normal and gradient information
// for environment map lookup and filtering
//
class RREnvTextureCoord
{
public:
FLOAT fNX; // normal or reflection normal
FLOAT fNY;
FLOAT fNZ;
// FLOAT fENX; // eye normal
// FLOAT fENY;
// FLOAT fENZ;
FLOAT fDNXDX; // normal gradient dNX/dX
FLOAT fDNXDY; // normal gradient dNX/dY
FLOAT fDNYDX; // normal gradient dNY/dX
FLOAT fDNYDY; // normal gradient dNY/dY
FLOAT fDNZDX; // normal gradient dNZ/dX
FLOAT fDNZDY; // normal gradient dNZ/dY
};
//
// routines to compute level of detail (texel->pixel coverage)
//
// (texfilt.cpp)
void
ComputeSimpleLevelOfDetail(
const RRTextureCoord& TCoord, // inputs
FLOAT& fLOD ); // outputs
void
ComputeEnvMapLevelOfDetail(
const RRTextureCoord& TCoord, // inputs
FLOAT& fLOD ); // outputs
void
ComputeAnisotropicLevelOfDetail(
const RRTextureCoord& TCoord, FLOAT fMaxAniso, // inputs
FLOAT& fLOD, FLOAT& fRatio, FLOAT fDelta[] ); // outputs
///////////////////////////////////////////////////////////////////////////////
// //
// Pixel Engine //
// //
///////////////////////////////////////////////////////////////////////////////
// coverage mask values
#define TL_CVGFULL 0xffff
#define TL_CVGZERO 0x0000
#define TL_CVGBITS 16
#define TL_CVGBITSm 4
typedef UINT16 CVGMASK;
// fragment - fragmented pixels have linked lists of these
struct _RRFRAGMENT
{
RRColor Color;
RRDepth Depth;
CVGMASK CvgMask;
void* pNext;
};
int CountFrags(RRFRAGMENT* pFrag);
void DPFFrags(RRFRAGMENT* pFrag);
//-----------------------------------------------------------------------------
//
// Fragment Resolution Accumulator - accumulates fragments presented in
// front-to-back order; does fully correct transparency computations for
// non-opaque fragments
//
//-----------------------------------------------------------------------------
class FragResolveAccum
{
public:
// coverage accumulation array - holds up to CVGBITS different
// alpha values and associated coverage masks; UsageMask indicates
// which entries are currently in use - each set bit in Usage mask
// indicates that the array entry corresponding to the index of the
// that bit holds a valid mask and alpha;
//
// the general idea here is that, in cases in which there are few
// fragments, numerous sample locations (within the pixel) will have
// the same alpha value, and thus can be grouped for the accumulation
struct {
CVGMASK Mask;
FLOAT fAlpha;
} m_CvgArray[TL_CVGBITS];
CVGMASK m_ArrayUsageMask;
// accumulated color and alpha value
FLOAT m_fA, m_fR, m_fG, m_fB;
// mask where set bit indicates a subpixel with opaque alpha
CVGMASK m_CvgOpaqueMask;
// reset before each use...
void Reset( void );
// accumulate new fragment (front to back) - returns TRUE if
// full coverage achieved, FALSE otherwise
BOOL Accum( const CVGMASK CvgMask, const RRColor& Color );
// get RRColor from accumulator
void GetColor( RRColor& Color );
};
//-----------------------------------------------------------------------------
//
// statistics
//
//-----------------------------------------------------------------------------
struct _RRSTATS
{
INT32 cFragsAllocd;
INT32 cMaxFragsAllocd;
INT32 cFragsMerged;
INT32 cFragsMergedToFull;
};
//-----------------------------------------------------------------------------
//
// utilities
//
//-----------------------------------------------------------------------------
// compute pixel address from base, pitch, and surface type
char*
PixelAddress( int iX, int iY, char* pBits, int iYPitch, RRSurfaceType SType );
//-----------------------------------------------------------------------------
//
// color interpolation utilities
//
//-----------------------------------------------------------------------------
void LerpColor(RRColor& Color,
const RRColor& Color0, const RRColor& Color1, UINT8 uT);
void BiLerpColor( RRColor& OutColor,
const RRColor& Color00, const RRColor& Color01,
const RRColor& Color10, const RRColor& Color11,
UINT8 uA, UINT8 uB);
//-----------------------------------------------------------------------------
//
// Globals
//
//-----------------------------------------------------------------------------
// something to experiment with sometime - this sets the threshold at which
// pixel samples are considered opaque (and thus don't generate fragment
// buffer entries when doing D3DRENDERSTATE_TRANSLUCENTSORTINDEPENDENT);
// no need to have all those 0xfe's generate fragments...
extern UINT8 g_uTransparencyAlphaThreshold;
//-----------------------------------------------------------------------------
//
// One special legacy texture op we can't easily map into the new texture
// ops.
//
//-----------------------------------------------------------------------------
#define D3DTOP_LEGACY_ALPHAOVR (0x7fffffff)
///////////////////////////////////////////////////////////////////////////////
#endif // _REFRASTI_HPP