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.
 
 
 
 
 
 

932 lines
31 KiB

//----------------------------------------------------------------------------
//
// setup.cpp
//
// Generic C++ setup functions.
//
// Copyright (C) Microsoft Corporation, 1997.
//
//----------------------------------------------------------------------------
include(`m4hdr.mh')dnl
#include "pch.cpp"
#pragma hdrstop
DBG_DECLARE_FILE();
#if DBG
#define DBG_OVERFLOW
#endif
//----------------------------------------------------------------------------
//
// ComputeADX/ADY
//
// Computes dAttr/dAxis from given deltas and cached intermediate values.
//
//----------------------------------------------------------------------------
inline FLOAT FASTCALL
ComputeADX(PSETUPCTX pStpCtx, FLOAT fD20, FLOAT fD10)
{
return fD20 * pStpCtx->fNY10 - fD10 * pStpCtx->fNY20;
}
inline FLOAT FASTCALL
ComputeADY(PSETUPCTX pStpCtx, FLOAT fD20, FLOAT fD10)
{
return fD10 * pStpCtx->fNX20 - fD20 * pStpCtx->fNX10;
}
// Given the vertex zero attribute value and gradients,
// subpixel corrects to compute the true
// initial value and computes the span-to-span steps.
#define CORRECT_ATTR(fV0, fDVDX, fDVDY, fVCorrect, fDVNC, fDVCY) \
((fVCorrect) = (fV0) + pStpCtx->fDX * (fDVDX) + pStpCtx->fDY * (fDVDY), \
(fDVNC) = (fDVDY) + (fDVDX) * pStpCtx->fX20NC, \
(fDVCY) = pStpCtx->X20.iCY > pStpCtx->X20.iNC ? \
(fDVNC) + (fDVDX) : (fDVNC) - (fDVDX))
dnl
dnl d_ZSetup
dnl
dnl Does Z setup.
dnl
dnl $1 is the Z buffer depth.
dnl
define(`d_ZSetup',
`{
FLOAT fZ0;
FLOAT fDZ20, fDZ10;
fZ0 = pV0->dvSZ;
fDZ20 = Z$1_SCALE * (pV2->dvSZ - pV0->dvSZ);
fDZ10 = Z$1_SCALE * (pV1->dvSZ - pV0->dvSZ);
pStpCtx->DAttrDX.fZ = ComputeADX(pStpCtx, fDZ20, fDZ10);
pStpCtx->DAttrDY.fZ = ComputeADY(pStpCtx, fDZ20, fDZ10);
CORRECT_ATTR(fZ0 * Z$1_SCALE,
pStpCtx->DAttrDX.fZ, pStpCtx->DAttrDY.fZ,
pStpCtx->Attr.fZ, pStpCtx->DAttrNC.fZ, pStpCtx->DAttrCY.fZ);
if (pStpCtx->uFlags & TRIF_X_DEC)
{
pStpCtx->DAttrDX.fZ = NEGF(pStpCtx->DAttrDX.fZ);
}
if ((pStpCtx->uFlags & TRIF_RASTPRIM_OVERFLOW) ||
ABSF(pStpCtx->DAttrDX.fZ) >= Z_LIMIT)
{
pStpCtx->uFlags |= TRIF_RASTPRIM_OVERFLOW;
#ifdef DBG_OVERFLOW
RSDPF(("Overflow delta for Z: %f\n", pStpCtx->DAttrDX.fZ));
#endif
}
else
{
pStpCtx->pPrim->iDZDX = FTOI(pStpCtx->DAttrDX.fZ);
}
#ifdef STEP_FIXED
if ((pStpCtx->uFlags & TRIF_FIXED_OVERFLOW) ||
ABSF(pStpCtx->DAttrNC.fZ) >= Z_LIMIT ||
ABSF(pStpCtx->DAttrCY.fZ) >= Z_LIMIT)
{
pStpCtx->uFlags |= TRIF_FIXED_OVERFLOW;
}
#endif
// Call next bead.
pStpCtx->pfnTriSetupZEnd(pStpCtx, pV0, pV1, pV2);
}
')dnl
dnl
dnl d_TexSetupFinish
dnl
dnl Completes texture coordinate setup. Assumes values in
dnl fUoW0, fVoW0, fDU20, fDV20, fDU10 and fDV10.
dnl
dnl $1 is the coordinate index, 1 or 2.
dnl
define(`d_TexSetupFinish',
` pStpCtx->DAttrDX.fUoW$1 = ComputeADX(pStpCtx, fDU20, fDU10);
pStpCtx->DAttrDX.fVoW$1 = ComputeADX(pStpCtx, fDV20, fDV10);
pStpCtx->DAttrDY.fUoW$1 = ComputeADY(pStpCtx, fDU20, fDU10);
pStpCtx->DAttrDY.fVoW$1 = ComputeADY(pStpCtx, fDV20, fDV10);
CORRECT_ATTR(fUoW0 * TEX_SCALE,
pStpCtx->DAttrDX.fUoW$1, pStpCtx->DAttrDY.fUoW$1,
pStpCtx->Attr.fUoW$1,
pStpCtx->DAttrNC.fUoW$1, pStpCtx->DAttrCY.fUoW$1);
CORRECT_ATTR(fVoW0 * TEX_SCALE,
pStpCtx->DAttrDX.fVoW$1, pStpCtx->DAttrDY.fVoW$1,
pStpCtx->Attr.fVoW$1,
pStpCtx->DAttrNC.fVoW$1, pStpCtx->DAttrCY.fVoW$1);
if (pStpCtx->uFlags & TRIF_X_DEC)
{
pStpCtx->DAttrDX.fUoW$1 = NEGF(pStpCtx->DAttrDX.fUoW$1);
pStpCtx->DAttrDX.fVoW$1 = NEGF(pStpCtx->DAttrDX.fVoW$1);
}
// ATTENTION - If the delta values cant be represented then
// we need to make sure that the per-pixel mipmapping scan
// routine isnt called since it uses these deltas.
if ((pStpCtx->uFlags & TRIF_RASTPRIM_OVERFLOW) ||
ABSF(pStpCtx->DAttrDX.fUoW$1) >= TEX_LIMIT ||
ABSF(pStpCtx->DAttrDX.fVoW$1) >= TEX_LIMIT ||
ABSF(pStpCtx->DAttrDY.fUoW$1) >= TEX_LIMIT ||
ABSF(pStpCtx->DAttrDY.fVoW$1) >= TEX_LIMIT)
{
pStpCtx->uFlags |= TRIF_RASTPRIM_OVERFLOW;
#ifdef DBG_OVERFLOW
RSDPF(("Overflow delta for tex$1: %f,%f,%f,%f\n",
pStpCtx->DAttrDX.fUoW$1, pStpCtx->DAttrDX.fVoW$1,
pStpCtx->DAttrDY.fUoW$1, pStpCtx->DAttrDY.fVoW$1));
#endif
}
else
{
pStpCtx->pPrim->iDUoW$1DX = FTOI(pStpCtx->DAttrDX.fUoW$1);
pStpCtx->pPrim->iDVoW$1DX = FTOI(pStpCtx->DAttrDX.fVoW$1);
pStpCtx->pPrim->iDUoW$1DY = FTOI(pStpCtx->DAttrDY.fUoW$1);
pStpCtx->pPrim->iDVoW$1DY = FTOI(pStpCtx->DAttrDY.fVoW$1);
}
#ifdef STEP_FIXED
if ((pStpCtx->uFlags & TRIF_FIXED_OVERFLOW) ||
ABSF(pStpCtx->DAttrNC.fUoW$1) >= TEX_LIMIT ||
ABSF(pStpCtx->DAttrCY.fUoW$1) >= TEX_LIMIT ||
ABSF(pStpCtx->DAttrNC.fVoW$1) >= TEX_LIMIT ||
ABSF(pStpCtx->DAttrCY.fVoW$1) >= TEX_LIMIT)
{
pStpCtx->uFlags |= TRIF_FIXED_OVERFLOW;
}
#endif
')dnl
dnl
dnl d_PerspTexSetup
dnl
dnl Does perspective-corrected texture coordinate setup.
dnl
dnl $1 is the coordinate index, 1 or 2.
dnl $2 is the vertex coordinate suffix, `' or 2.
dnl
define(`d_PerspTexSetup',
`{
FLOAT fDU20, fDV20;
FLOAT fDU10, fDV10;
FLOAT fUoW0, fVoW0;
fUoW0 = ((PRAST_GENERIC_VERTEX)pV0)->dvTU$2 * pV0->dvRHW;
fVoW0 = ((PRAST_GENERIC_VERTEX)pV0)->dvTV$2 * pV0->dvRHW;
fDU20 =
PERSP_TEXTURE_DELTA(((PRAST_GENERIC_VERTEX)pV2)->dvTU$2, pV2->dvRHW,
((PRAST_GENERIC_VERTEX)pV0)->dvTU$2, fUoW0,
pStpCtx->pCtx->pdwWrap[`'decr($1)] & D3DWRAP_U) *
TEX_SCALE;
fDU10 =
PERSP_TEXTURE_DELTA(((PRAST_GENERIC_VERTEX)pV1)->dvTU$2, pV1->dvRHW,
((PRAST_GENERIC_VERTEX)pV0)->dvTU$2, fUoW0,
pStpCtx->pCtx->pdwWrap[`'decr($1)] & D3DWRAP_U) *
TEX_SCALE;
fDV20 =
PERSP_TEXTURE_DELTA(((PRAST_GENERIC_VERTEX)pV2)->dvTV$2, pV2->dvRHW,
((PRAST_GENERIC_VERTEX)pV0)->dvTV$2, fVoW0,
pStpCtx->pCtx->pdwWrap[`'decr($1)] & D3DWRAP_V) *
TEX_SCALE;
fDV10 =
PERSP_TEXTURE_DELTA(((PRAST_GENERIC_VERTEX)pV1)->dvTV$2, pV1->dvRHW,
((PRAST_GENERIC_VERTEX)pV0)->dvTV$2, fVoW0,
pStpCtx->pCtx->pdwWrap[`'decr($1)] & D3DWRAP_V) *
TEX_SCALE;
d_TexSetupFinish($1)dnl
}
RSDPFM((RSM_TEX$1, " APTex$1 %f,%f (%f,%f) (%f,%f)\n",
pStpCtx->Attr.fUoW$1, pStpCtx->Attr.fVoW$1,
pStpCtx->Attr.fUoW$1 * OO_TEX_SCALE,
pStpCtx->Attr.fVoW$1 * OO_TEX_SCALE,
(pStpCtx->Attr.fUoW$1 * OOW_SCALE) /
(pStpCtx->Attr.fOoW * TEX_SCALE),
(pStpCtx->Attr.fVoW$1 * OOW_SCALE) /
(pStpCtx->Attr.fOoW * TEX_SCALE)));
RSDPFM((RSM_TEX$1, " DUoW$1DX %f (%f) DVoW$1DX %f (%f)\n",
pStpCtx->DAttrDX.fUoW$1, pStpCtx->DAttrDX.fUoW$1 * OO_TEX_SCALE,
pStpCtx->DAttrDX.fVoW$1, pStpCtx->DAttrDX.fVoW$1 * OO_TEX_SCALE));
RSDPFM((RSM_TEX$1, " DUoW$1DY %f (%f) DVoW$1DY %f (%f)\n",
pStpCtx->DAttrDY.fUoW$1, pStpCtx->DAttrDY.fUoW$1 * OO_TEX_SCALE,
pStpCtx->DAttrDY.fVoW$1, pStpCtx->DAttrDY.fVoW$1 * OO_TEX_SCALE));
')dnl
dnl
dnl d_AffineTexSetup
dnl
dnl Does affine-only texture coordinate setup.
dnl
dnl $1 is the coordinate index, 1 or 2.
dnl $2 is the vertex coordinate suffix, `' or 2.
dnl
define(`d_AffineTexSetup',
`{
FLOAT fDU20, fDV20;
FLOAT fDU10, fDV10;
FLOAT fUoW0, fVoW0;
fUoW0 = ((PRAST_GENERIC_VERTEX)pV0)->dvTU$2;
fVoW0 = ((PRAST_GENERIC_VERTEX)pV0)->dvTV$2;
fDU20 =
InlTextureDiff(((PRAST_GENERIC_VERTEX)pV2)->dvTU$2, fUoW0,
pStpCtx->pCtx->pdwWrap[`'decr($1)] & D3DWRAP_U) *
TEX_SCALE;
fDU10 =
InlTextureDiff(((PRAST_GENERIC_VERTEX)pV1)->dvTU$2, fUoW0,
pStpCtx->pCtx->pdwWrap[`'decr($1)] & D3DWRAP_U) *
TEX_SCALE;
fDV20 =
InlTextureDiff(((PRAST_GENERIC_VERTEX)pV2)->dvTV$2, fVoW0,
pStpCtx->pCtx->pdwWrap[`'decr($1)] & D3DWRAP_V) *
TEX_SCALE;
fDV10 =
InlTextureDiff(((PRAST_GENERIC_VERTEX)pV1)->dvTV$2, fVoW0,
pStpCtx->pCtx->pdwWrap[`'decr($1)] & D3DWRAP_V) *
TEX_SCALE;
d_TexSetupFinish($1)dnl
}
RSDPFM((RSM_TEX$1, " AATex$1 %f,%f (%f,%f)\n",
pStpCtx->Attr.fUoW$1, pStpCtx->Attr.fVoW$1,
pStpCtx->Attr.fUoW$1 * OO_TEX_SCALE,
pStpCtx->Attr.fVoW$1 * OO_TEX_SCALE));
RSDPFM((RSM_TEX$1, " DUoW$1DX %f (%f) DVoW$1DX %f (%f)\n",
pStpCtx->DAttrDX.fUoW$1, pStpCtx->DAttrDX.fUoW$1 * OO_TEX_SCALE,
pStpCtx->DAttrDX.fVoW$1, pStpCtx->DAttrDX.fVoW$1 * OO_TEX_SCALE));
RSDPFM((RSM_TEX$1, " DUoW$1DY %f (%f) DVoW$1DY %f (%f)\n",
pStpCtx->DAttrDY.fUoW$1, pStpCtx->DAttrDY.fUoW$1 * OO_TEX_SCALE,
pStpCtx->DAttrDY.fVoW$1, pStpCtx->DAttrDY.fVoW$1 * OO_TEX_SCALE));
')dnl
dnl
dnl d_DeclSetup
dnl
dnl Declare a PFN_SETUPATTR from its attribute name.
dnl
dnl $1 is the attribute name.
dnl
define(`d_DeclSetup',
`void FASTCALL
TriSetup_$1(PSETUPCTX pStpCtx,
LPD3DTLVERTEX pV0,
LPD3DTLVERTEX pV1,
LPD3DTLVERTEX pV2)
')dnl
dnl
//----------------------------------------------------------------------------
//
// Setup_Start
//
// Normalizes edge deltas and calls the first attribute setup bead.
//
//----------------------------------------------------------------------------
d_DeclSetup(`Start')dnl
{
// Fold normalization value into deltas.
pStpCtx->fNX20 = pStpCtx->fOoDet * pStpCtx->fDX20;
pStpCtx->fNX10 = pStpCtx->fOoDet * pStpCtx->fDX10;
pStpCtx->fNY20 = pStpCtx->fOoDet * pStpCtx->fDY20;
pStpCtx->fNY10 = pStpCtx->fOoDet * pStpCtx->fDY10;
// Call first bead.
pStpCtx->pfnTriSetupFirstAttr(pStpCtx, pV0, pV1, pV2);
}
//----------------------------------------------------------------------------
//
// Setup_Z16
//
// Attribute setup for 16-bit Z.
//
//----------------------------------------------------------------------------
d_DeclSetup(`Z16')dnl
d_ZSetup(`16')dnl
//----------------------------------------------------------------------------
//
// Setup_Z32
//
// Attribute setup for 32-bit Z.
//
//----------------------------------------------------------------------------
d_DeclSetup(`Z32')dnl
d_ZSetup(`32')dnl
//----------------------------------------------------------------------------
//
// Setup_Persp_Tex1
//
// Attribute setup for OoW and first texture coordinates.
// Coordinates are set up for perspective correction.
//
//----------------------------------------------------------------------------
d_DeclSetup(`Persp_Tex1')dnl
{
FLOAT fDOoW20, fDOoW10;
fDOoW20 = OOW_SCALE * (pV2->dvRHW - pV0->dvRHW);
fDOoW10 = OOW_SCALE * (pV1->dvRHW - pV0->dvRHW);
pStpCtx->DAttrDX.fOoW = ComputeADX(pStpCtx, fDOoW20, fDOoW10);
pStpCtx->DAttrDY.fOoW = ComputeADY(pStpCtx, fDOoW20, fDOoW10);
CORRECT_ATTR(pV0->dvRHW * OOW_SCALE,
pStpCtx->DAttrDX.fOoW, pStpCtx->DAttrDY.fOoW,
pStpCtx->Attr.fOoW,
pStpCtx->DAttrNC.fOoW, pStpCtx->DAttrCY.fOoW);
if (pStpCtx->uFlags & TRIF_X_DEC)
{
pStpCtx->DAttrDX.fOoW = NEGF(pStpCtx->DAttrDX.fOoW);
}
// ATTENTION - If the delta values cant be represented then
// we need to make sure that the per-pixel mipmapping scan
// routine isnt called since it uses these deltas.
if ((pStpCtx->uFlags & TRIF_RASTPRIM_OVERFLOW) ||
ABSF(pStpCtx->DAttrDX.fOoW) >= OOW_LIMIT ||
ABSF(pStpCtx->DAttrDY.fOoW) >= OOW_LIMIT)
{
pStpCtx->uFlags |= TRIF_RASTPRIM_OVERFLOW;
#ifdef DBG_OVERFLOW
RSDPF(("Overflow delta for OoW: %f, %f\n",
pStpCtx->DAttrDX.fOoW, pStpCtx->DAttrDY.fOoW));
#endif
}
else
{
pStpCtx->pPrim->iDOoWDX = FTOI(pStpCtx->DAttrDX.fOoW);
pStpCtx->pPrim->iDOoWDY = FTOI(pStpCtx->DAttrDY.fOoW);
}
#ifdef STEP_FIXED
if ((pStpCtx->uFlags & TRIF_FIXED_OVERFLOW) ||
ABSF(pStpCtx->DAttrNC.fOoW) >= OOW_LIMIT ||
ABSF(pStpCtx->DAttrCY.fOoW) >= OOW_LIMIT)
{
pStpCtx->uFlags |= TRIF_FIXED_OVERFLOW;
}
#endif
RSDPFM((RSM_OOW, " AOoW %f (%f)\n",
pStpCtx->Attr.fOoW, pStpCtx->Attr.fOoW * OO_OOW_SCALE));
RSDPFM((RSM_OOW, " DOoWDX %f (%f), DOoWDY %f (%f)\n",
pStpCtx->DAttrDX.fOoW, pStpCtx->DAttrDX.fOoW * OO_OOW_SCALE,
pStpCtx->DAttrDY.fOoW, pStpCtx->DAttrDY.fOoW * OO_OOW_SCALE));
d_PerspTexSetup(`1', `')dnl
// Call next bead.
pStpCtx->pfnTriSetupTex1End(pStpCtx, pV0, pV1, pV2);
}
//----------------------------------------------------------------------------
//
// Setup_Affine_Tex1
//
// Attribute setup for OoW and first texture coordinates.
// Coordinates are set up for affine mapping.
//
//----------------------------------------------------------------------------
d_DeclSetup(`Affine_Tex1')dnl
{
pStpCtx->Attr.fOoW = OOW_SCALE;
pStpCtx->DAttrDX.fOoW = g_fZero;
pStpCtx->DAttrDY.fOoW = g_fZero;
pStpCtx->DAttrNC.fOoW = g_fZero;
pStpCtx->DAttrCY.fOoW = g_fZero;
pStpCtx->pPrim->iDOoWDX = 0;
pStpCtx->pPrim->iDOoWDY = 0;
d_AffineTexSetup(`1', `')dnl
// Call next bead.
pStpCtx->pfnTriSetupTex1End(pStpCtx, pV0, pV1, pV2);
}
//----------------------------------------------------------------------------
//
// Setup_Persp_Tex2
//
// Attribute setup for second texture coordinates.
// Coordinates are set up for perspective correction.
//
//----------------------------------------------------------------------------
d_DeclSetup(`Persp_Tex2')dnl
{
d_PerspTexSetup(`2', `2')dnl
// Call next bead.
pStpCtx->pfnTriSetupTex2End(pStpCtx, pV0, pV1, pV2);
}
//----------------------------------------------------------------------------
//
// Setup_Affine_Tex2
//
// Attribute setup for second texture coordinates.
// Coordinates are set up for affine mapping.
//
//----------------------------------------------------------------------------
d_DeclSetup(`Affine_Tex2')dnl
{
d_AffineTexSetup(`2', `2')dnl
// Call next bead.
pStpCtx->pfnTriSetupTex2End(pStpCtx, pV0, pV1, pV2);
}
//----------------------------------------------------------------------------
//
// Setup_Diff
//
// Attribute setup for interpolated diffuse color.
//
//----------------------------------------------------------------------------
d_DeclSetup(`Diff')dnl
{
UINT uB, uG, uR, uA;
FLOAT fDB20, fDG20, fDR20, fDA20;
FLOAT fDB10, fDG10, fDR10, fDA10;
SPLIT_COLOR(pV0->dcColor, uB, uG, uR, uA);
COLOR_DELTA(pV2->dcColor, uB, uG, uR, uA, fDB20, fDG20, fDR20, fDA20);
COLOR_DELTA(pV1->dcColor, uB, uG, uR, uA, fDB10, fDG10, fDR10, fDA10);
pStpCtx->DAttrDX.fB = ComputeADX(pStpCtx, fDB20, fDB10);
pStpCtx->DAttrDX.fG = ComputeADX(pStpCtx, fDG20, fDG10);
pStpCtx->DAttrDX.fR = ComputeADX(pStpCtx, fDR20, fDR10);
pStpCtx->DAttrDX.fA = ComputeADX(pStpCtx, fDA20, fDA10);
pStpCtx->DAttrDY.fB = ComputeADY(pStpCtx, fDB20, fDB10);
pStpCtx->DAttrDY.fG = ComputeADY(pStpCtx, fDG20, fDG10);
pStpCtx->DAttrDY.fR = ComputeADY(pStpCtx, fDR20, fDR10);
pStpCtx->DAttrDY.fA = ComputeADY(pStpCtx, fDA20, fDA10);
CORRECT_ATTR((FLOAT)(uB << COLOR_SHIFT),
pStpCtx->DAttrDX.fB, pStpCtx->DAttrDY.fB,
pStpCtx->Attr.fB,
pStpCtx->DAttrNC.fB, pStpCtx->DAttrCY.fB);
CORRECT_ATTR((FLOAT)(uG << COLOR_SHIFT),
pStpCtx->DAttrDX.fG, pStpCtx->DAttrDY.fG,
pStpCtx->Attr.fG,
pStpCtx->DAttrNC.fG, pStpCtx->DAttrCY.fG);
CORRECT_ATTR((FLOAT)(uR << COLOR_SHIFT),
pStpCtx->DAttrDX.fR, pStpCtx->DAttrDY.fR,
pStpCtx->Attr.fR,
pStpCtx->DAttrNC.fR, pStpCtx->DAttrCY.fR);
CORRECT_ATTR((FLOAT)(uA << COLOR_SHIFT),
pStpCtx->DAttrDX.fA, pStpCtx->DAttrDY.fA,
pStpCtx->Attr.fA,
pStpCtx->DAttrNC.fA, pStpCtx->DAttrCY.fA);
if (pStpCtx->uFlags & TRIF_X_DEC)
{
pStpCtx->DAttrDX.fB = NEGF(pStpCtx->DAttrDX.fB);
pStpCtx->DAttrDX.fG = NEGF(pStpCtx->DAttrDX.fG);
pStpCtx->DAttrDX.fR = NEGF(pStpCtx->DAttrDX.fR);
pStpCtx->DAttrDX.fA = NEGF(pStpCtx->DAttrDX.fA);
}
if ((pStpCtx->uFlags & TRIF_RASTPRIM_OVERFLOW) ||
ABSF(pStpCtx->DAttrDX.fB) >= COLOR_LIMIT ||
ABSF(pStpCtx->DAttrDX.fG) >= COLOR_LIMIT ||
ABSF(pStpCtx->DAttrDX.fR) >= COLOR_LIMIT ||
ABSF(pStpCtx->DAttrDX.fA) >= COLOR_LIMIT)
{
pStpCtx->uFlags |= TRIF_RASTPRIM_OVERFLOW;
#ifdef DBG_OVERFLOW
RSDPF(("Overflow delta for diffuse: %f,%f,%f,%f\n",
pStpCtx->DAttrDX.fB, pStpCtx->DAttrDX.fG,
pStpCtx->DAttrDX.fR, pStpCtx->DAttrDX.fA));
#endif
}
else
{
pStpCtx->pPrim->iDBDX = (INT16)FTOI(pStpCtx->DAttrDX.fB);
pStpCtx->pPrim->iDGDX = (INT16)FTOI(pStpCtx->DAttrDX.fG);
pStpCtx->pPrim->iDRDX = (INT16)FTOI(pStpCtx->DAttrDX.fR);
pStpCtx->pPrim->iDADX = (INT16)FTOI(pStpCtx->DAttrDX.fA);
}
#ifdef STEP_FIXED
if ((pStpCtx->uFlags & TRIF_FIXED_OVERFLOW) ||
ABSF(pStpCtx->DAttrNC.fB) >= COLOR_LIMIT ||
ABSF(pStpCtx->DAttrCY.fB) >= COLOR_LIMIT ||
ABSF(pStpCtx->DAttrNC.fG) >= COLOR_LIMIT ||
ABSF(pStpCtx->DAttrCY.fG) >= COLOR_LIMIT ||
ABSF(pStpCtx->DAttrNC.fR) >= COLOR_LIMIT ||
ABSF(pStpCtx->DAttrCY.fR) >= COLOR_LIMIT ||
ABSF(pStpCtx->DAttrNC.fA) >= COLOR_LIMIT ||
ABSF(pStpCtx->DAttrCY.fA) >= COLOR_LIMIT)
{
pStpCtx->uFlags |= TRIF_FIXED_OVERFLOW;
}
#endif
RSDPFM((RSM_DIFF, " diff v0 %f,%f,%f,%f\n",
pStpCtx->Attr.fB, pStpCtx->Attr.fG,
pStpCtx->Attr.fR, pStpCtx->Attr.fA));
RSDPFM((RSM_DIFF, " dx %f,%f,%f,%f\n",
pStpCtx->DAttrDX.fB, pStpCtx->DAttrDX.fG,
pStpCtx->DAttrDX.fR, pStpCtx->DAttrDX.fA));
RSDPFM((RSM_DIFF, " dy %f,%f,%f,%f\n",
pStpCtx->DAttrDY.fB, pStpCtx->DAttrDY.fG,
pStpCtx->DAttrDY.fR, pStpCtx->DAttrDY.fA));
RSDPFM((RSM_DIFF, " cy %f,%f,%f,%f\n",
pStpCtx->DAttrCY.fB, pStpCtx->DAttrCY.fG,
pStpCtx->DAttrCY.fR, pStpCtx->DAttrCY.fA));
RSDPFM((RSM_DIFF, " nc %f,%f,%f,%f\n",
pStpCtx->DAttrNC.fB, pStpCtx->DAttrNC.fG,
pStpCtx->DAttrNC.fR, pStpCtx->DAttrNC.fA));
// Call next bead.
pStpCtx->pfnTriSetupDiffEnd(pStpCtx, pV0, pV1, pV2);
}
//----------------------------------------------------------------------------
//
// Setup_DiffFlat
//
// Attribute setup for constant diffuse color.
//
//----------------------------------------------------------------------------
d_DeclSetup(`DiffFlat')dnl
{
UINT uB, uG, uR, uA;
// Use original input pV0 to avoid confusion due to vertex sorting.
SPLIT_COLOR(pStpCtx->pFlatVtx->dcColor, uB, uG, uR, uA);
pStpCtx->Attr.fB = (FLOAT)(uB << COLOR_SHIFT);
pStpCtx->Attr.fG = (FLOAT)(uG << COLOR_SHIFT);
pStpCtx->Attr.fR = (FLOAT)(uR << COLOR_SHIFT);
pStpCtx->Attr.fA = (FLOAT)(uA << COLOR_SHIFT);
pStpCtx->DAttrDX.fB = g_fZero;
pStpCtx->DAttrDX.fG = g_fZero;
pStpCtx->DAttrDX.fR = g_fZero;
pStpCtx->DAttrDX.fA = g_fZero;
pStpCtx->DAttrDY.fB = g_fZero;
pStpCtx->DAttrDY.fG = g_fZero;
pStpCtx->DAttrDY.fR = g_fZero;
pStpCtx->DAttrDY.fA = g_fZero;
pStpCtx->DAttrNC.fB = g_fZero;
pStpCtx->DAttrNC.fG = g_fZero;
pStpCtx->DAttrNC.fR = g_fZero;
pStpCtx->DAttrNC.fA = g_fZero;
pStpCtx->DAttrCY.fB = g_fZero;
pStpCtx->DAttrCY.fG = g_fZero;
pStpCtx->DAttrCY.fR = g_fZero;
pStpCtx->DAttrCY.fA = g_fZero;
pStpCtx->pPrim->iDBDX = 0;
pStpCtx->pPrim->iDGDX = 0;
pStpCtx->pPrim->iDRDX = 0;
pStpCtx->pPrim->iDADX = 0;
// Call next bead.
pStpCtx->pfnTriSetupDiffEnd(pStpCtx, pV0, pV1, pV2);
}
//----------------------------------------------------------------------------
//
// Setup_DIdx
//
// Setup for diffuse indexed color.
//
//----------------------------------------------------------------------------
d_DeclSetup(`DIdx')dnl
{
INT32 iIdx, iA;
FLOAT fDIdx20, fDA20;
FLOAT fDIdx10, fDA10;
SPLIT_IDX_COLOR(pV0->dcColor, iIdx, iA);
IDX_COLOR_DELTA(pV2->dcColor, iIdx, iA, fDIdx20, fDA20);
IDX_COLOR_DELTA(pV1->dcColor, iIdx, iA, fDIdx10, fDA10);
pStpCtx->DAttrDX.fDIdx = ComputeADX(pStpCtx, fDIdx20, fDIdx10);
pStpCtx->DAttrDX.fDIdxA = ComputeADX(pStpCtx, fDA20, fDA10);
pStpCtx->DAttrDY.fDIdx = ComputeADY(pStpCtx, fDIdx20, fDIdx10);
pStpCtx->DAttrDY.fDIdxA = ComputeADY(pStpCtx, fDA20, fDA10);
CORRECT_ATTR((FLOAT)(iIdx << INDEX_COLOR_FIXED_SHIFT),
pStpCtx->DAttrDX.fDIdx, pStpCtx->DAttrDY.fDIdx,
pStpCtx->Attr.fDIdx,
pStpCtx->DAttrNC.fDIdx, pStpCtx->DAttrCY.fDIdx);
CORRECT_ATTR((FLOAT)(iA << INDEX_COLOR_SHIFT),
pStpCtx->DAttrDX.fDIdxA, pStpCtx->DAttrDY.fDIdxA,
pStpCtx->Attr.fDIdxA,
pStpCtx->DAttrNC.fDIdxA, pStpCtx->DAttrCY.fDIdxA);
if (pStpCtx->uFlags & TRIF_X_DEC)
{
pStpCtx->DAttrDX.fDIdx = NEGF(pStpCtx->DAttrDX.fDIdx);
pStpCtx->DAttrDX.fDIdxA = NEGF(pStpCtx->DAttrDX.fDIdxA);
}
if ((pStpCtx->uFlags & TRIF_RASTPRIM_OVERFLOW) ||
ABSF(pStpCtx->DAttrDX.fDIdx) >= INDEX_COLOR_LIMIT ||
ABSF(pStpCtx->DAttrDX.fDIdxA) >= INDEX_COLOR_LIMIT)
{
pStpCtx->uFlags |= TRIF_RASTPRIM_OVERFLOW;
#ifdef DBG_OVERFLOW
RSDPF(("Overflow delta for didx: %f,%f,%f,%f\n",
pStpCtx->DAttrDX.fDIdx, pStpCtx->DAttrDX.fDIdxA));
#endif
}
else
{
pStpCtx->pPrim->iDIdxDX = FTOI(pStpCtx->DAttrDX.fDIdx);
pStpCtx->pPrim->iDIdxADX = FTOI(pStpCtx->DAttrDX.fDIdxA);
}
#ifdef STEP_FIXED
if ((pStpCtx->uFlags & TRIF_FIXED_OVERFLOW) ||
ABSF(pStpCtx->DAttrNC.fDIdx) >= COLOR_LIMIT ||
ABSF(pStpCtx->DAttrCY.fDIdx) >= COLOR_LIMIT ||
ABSF(pStpCtx->DAttrNC.fDIdxA) >= COLOR_LIMIT ||
ABSF(pStpCtx->DAttrCY.fDIdxA) >= COLOR_LIMIT)
{
pStpCtx->uFlags |= TRIF_FIXED_OVERFLOW;
}
#endif
RSDPFM((RSM_DIDX, " didx v0 %f,%f\n",
pStpCtx->Attr.fDIdx, pStpCtx->Attr.fDIdxA));
RSDPFM((RSM_DIDX, " dx %f,%f\n",
pStpCtx->DAttrDX.fDIdx, pStpCtx->DAttrDX.fDIdxA));
RSDPFM((RSM_DIDX, " dy %f,%f\n",
pStpCtx->DAttrDY.fDIdx, pStpCtx->DAttrDY.fDIdxA));
RSDPFM((RSM_DIDX, " cy %f,%f\n",
pStpCtx->DAttrCY.fDIdx, pStpCtx->DAttrCY.fDIdxA));
RSDPFM((RSM_DIDX, " nc %f,%f\n",
pStpCtx->DAttrNC.fDIdx, pStpCtx->DAttrNC.fDIdxA));
// Call next bead.
pStpCtx->pfnTriSetupDiffEnd(pStpCtx, pV0, pV1, pV2);
}
//----------------------------------------------------------------------------
//
// Setup_DIdxFlat
//
// Attribute setup for constant diffuse indexed color.
//
//----------------------------------------------------------------------------
d_DeclSetup(`DIdxFlat')dnl
{
INT32 iIdx, iA;
//
// Use original input pV0 to avoid confusion due to vertex sorting.
//
SPLIT_IDX_COLOR(pStpCtx->pFlatVtx->dcColor, iIdx, iA);
pStpCtx->Attr.fDIdx = (FLOAT)(iIdx << INDEX_COLOR_FIXED_SHIFT);
pStpCtx->Attr.fDIdxA = (FLOAT)(iA << INDEX_COLOR_SHIFT);
pStpCtx->DAttrDX.fDIdx = g_fZero;
pStpCtx->DAttrDX.fDIdxA = g_fZero;
pStpCtx->DAttrDY.fDIdx = g_fZero;
pStpCtx->DAttrDY.fDIdxA = g_fZero;
pStpCtx->DAttrNC.fDIdx = g_fZero;
pStpCtx->DAttrNC.fDIdxA = g_fZero;
pStpCtx->DAttrCY.fDIdx = g_fZero;
pStpCtx->DAttrCY.fDIdxA = g_fZero;
pStpCtx->pPrim->iDIdxDX = 0;
pStpCtx->pPrim->iDIdxADX = 0;
// Call next bead.
pStpCtx->pfnTriSetupDiffEnd(pStpCtx, pV0, pV1, pV2);
}
//----------------------------------------------------------------------------
//
// Setup_Spec
//
// Setup for interpolated specular color.
//
//----------------------------------------------------------------------------
d_DeclSetup(`Spec')dnl
{
UINT uB, uG, uR, uA;
FLOAT fDB20, fDG20, fDR20, fDA20;
FLOAT fDB10, fDG10, fDR10, fDA10;
SPLIT_COLOR(pV0->dcSpecular, uB, uG, uR, uA);
COLOR_DELTA(pV2->dcSpecular, uB, uG, uR, uA, fDB20, fDG20, fDR20, fDA20);
COLOR_DELTA(pV1->dcSpecular, uB, uG, uR, uA, fDB10, fDG10, fDR10, fDA10);
pStpCtx->DAttrDX.fBS = ComputeADX(pStpCtx, fDB20, fDB10);
pStpCtx->DAttrDX.fGS = ComputeADX(pStpCtx, fDG20, fDG10);
pStpCtx->DAttrDX.fRS = ComputeADX(pStpCtx, fDR20, fDR10);
pStpCtx->DAttrDY.fBS = ComputeADY(pStpCtx, fDB20, fDB10);
pStpCtx->DAttrDY.fGS = ComputeADY(pStpCtx, fDG20, fDG10);
pStpCtx->DAttrDY.fRS = ComputeADY(pStpCtx, fDR20, fDR10);
CORRECT_ATTR((FLOAT)(uB << COLOR_SHIFT),
pStpCtx->DAttrDX.fBS, pStpCtx->DAttrDY.fBS, pStpCtx->Attr.fBS,
pStpCtx->DAttrNC.fBS, pStpCtx->DAttrCY.fBS);
CORRECT_ATTR((FLOAT)(uG << COLOR_SHIFT),
pStpCtx->DAttrDX.fGS, pStpCtx->DAttrDY.fGS, pStpCtx->Attr.fGS,
pStpCtx->DAttrNC.fGS, pStpCtx->DAttrCY.fGS);
CORRECT_ATTR((FLOAT)(uR << COLOR_SHIFT),
pStpCtx->DAttrDX.fRS, pStpCtx->DAttrDY.fRS, pStpCtx->Attr.fRS,
pStpCtx->DAttrNC.fRS, pStpCtx->DAttrCY.fRS);
if (pStpCtx->uFlags & TRIF_X_DEC)
{
pStpCtx->DAttrDX.fBS = NEGF(pStpCtx->DAttrDX.fBS);
pStpCtx->DAttrDX.fGS = NEGF(pStpCtx->DAttrDX.fGS);
pStpCtx->DAttrDX.fRS = NEGF(pStpCtx->DAttrDX.fRS);
}
if ((pStpCtx->uFlags & TRIF_RASTPRIM_OVERFLOW) ||
ABSF(pStpCtx->DAttrDX.fBS) >= COLOR_LIMIT ||
ABSF(pStpCtx->DAttrDX.fGS) >= COLOR_LIMIT ||
ABSF(pStpCtx->DAttrDX.fRS) >= COLOR_LIMIT)
{
pStpCtx->uFlags |= TRIF_RASTPRIM_OVERFLOW;
#ifdef DBG_OVERFLOW
RSDPF(("Overflow delta for specular: %f,%f,%f\n",
pStpCtx->DAttrDX.fBS, pStpCtx->DAttrDX.fGS,
pStpCtx->DAttrDX.fRS));
#endif
}
else
{
pStpCtx->pPrim->iDBSDX = (INT16)FTOI(pStpCtx->DAttrDX.fBS);
pStpCtx->pPrim->iDGSDX = (INT16)FTOI(pStpCtx->DAttrDX.fGS);
pStpCtx->pPrim->iDRSDX = (INT16)FTOI(pStpCtx->DAttrDX.fRS);
}
#ifdef STEP_FIXED
if ((pStpCtx->uFlags & TRIF_FIXED_OVERFLOW) ||
ABSF(pStpCtx->DAttrNC.fBS) >= COLOR_LIMIT ||
ABSF(pStpCtx->DAttrCY.fBS) >= COLOR_LIMIT ||
ABSF(pStpCtx->DAttrNC.fGS) >= COLOR_LIMIT ||
ABSF(pStpCtx->DAttrCY.fGS) >= COLOR_LIMIT ||
ABSF(pStpCtx->DAttrNC.fRS) >= COLOR_LIMIT ||
ABSF(pStpCtx->DAttrCY.fRS) >= COLOR_LIMIT)
{
pStpCtx->uFlags |= TRIF_FIXED_OVERFLOW;
}
#endif
// Call next bead.
pStpCtx->pfnTriSetupSpecEnd(pStpCtx, pV0, pV1, pV2);
}
//----------------------------------------------------------------------------
//
// Setup_SpecFlat
//
// Attribute setup for constant specular color.
//
//----------------------------------------------------------------------------
d_DeclSetup(`SpecFlat')dnl
{
UINT uB, uG, uR, uA;
// Use original input pV0 to avoid confusion due to vertex sorting.
SPLIT_COLOR(pStpCtx->pFlatVtx->dcSpecular, uB, uG, uR, uA);
pStpCtx->Attr.fBS = (FLOAT)(uB << COLOR_SHIFT);
pStpCtx->Attr.fGS = (FLOAT)(uG << COLOR_SHIFT);
pStpCtx->Attr.fRS = (FLOAT)(uR << COLOR_SHIFT);
pStpCtx->DAttrDX.fBS = g_fZero;
pStpCtx->DAttrDX.fGS = g_fZero;
pStpCtx->DAttrDX.fRS = g_fZero;
pStpCtx->DAttrDY.fBS = g_fZero;
pStpCtx->DAttrDY.fGS = g_fZero;
pStpCtx->DAttrDY.fRS = g_fZero;
pStpCtx->DAttrNC.fBS = g_fZero;
pStpCtx->DAttrNC.fGS = g_fZero;
pStpCtx->DAttrNC.fRS = g_fZero;
pStpCtx->DAttrCY.fBS = g_fZero;
pStpCtx->DAttrCY.fGS = g_fZero;
pStpCtx->DAttrCY.fRS = g_fZero;
pStpCtx->pPrim->iDBSDX = 0;
pStpCtx->pPrim->iDGSDX = 0;
pStpCtx->pPrim->iDRSDX = 0;
// Call next bead.
pStpCtx->pfnTriSetupSpecEnd(pStpCtx, pV0, pV1, pV2);
}
//----------------------------------------------------------------------------
//
// Setup_Fog
//
// Attribute setup for vertex fog.
//
//----------------------------------------------------------------------------
d_DeclSetup(`Fog')dnl
{
UINT uFog0, uFog1, uFog2;
FLOAT fDFog20, fDFog10;
#ifndef PWL_FOG
// Check for global-into-local fog. If global fog is on,
// compute the local fog values from table fog rather than
// from the vertex.
if (pStpCtx->uFlags & PRIMSF_GLOBAL_FOG_USED)
{
uFog0 = ComputeTableFog(pStpCtx->pCtx->pdwRenderState,
pV0->dvSZ);
uFog1 = ComputeTableFog(pStpCtx->pCtx->pdwRenderState,
pV1->dvSZ);
uFog2 = ComputeTableFog(pStpCtx->pCtx->pdwRenderState,
pV2->dvSZ);
}
else
#endif
{
// Fog value is kept in the alpha of the specular color.
uFog0 = (UINT)RGBA_GETALPHA(pV0->dcSpecular) << FOG_SHIFT;
uFog1 = (UINT)RGBA_GETALPHA(pV1->dcSpecular) << FOG_SHIFT;
uFog2 = (UINT)RGBA_GETALPHA(pV2->dcSpecular) << FOG_SHIFT;
}
fDFog20 = (FLOAT)((INT)uFog2 - (INT)uFog0);
fDFog10 = (FLOAT)((INT)uFog1 - (INT)uFog0);
pStpCtx->DAttrDX.fFog = ComputeADX(pStpCtx, fDFog20, fDFog10);
pStpCtx->DAttrDY.fFog = ComputeADY(pStpCtx, fDFog20, fDFog10);
CORRECT_ATTR((FLOAT)uFog0,
pStpCtx->DAttrDX.fFog, pStpCtx->DAttrDY.fFog,
pStpCtx->Attr.fFog, pStpCtx->DAttrNC.fFog,
pStpCtx->DAttrCY.fFog);
if (pStpCtx->uFlags & TRIF_X_DEC)
{
pStpCtx->DAttrDX.fFog = NEGF(pStpCtx->DAttrDX.fFog);
}
if ((pStpCtx->uFlags & TRIF_RASTPRIM_OVERFLOW) ||
ABSF(pStpCtx->DAttrDX.fFog) >= FOG_LIMIT)
{
pStpCtx->uFlags |= TRIF_RASTPRIM_OVERFLOW;
#ifdef DBG_OVERFLOW
RSDPF(("Overflow delta for fog: %f\n", pStpCtx->DAttrDX.fFog));
#endif
}
else
{
pStpCtx->iDLocalFogDX = FTOI(pStpCtx->DAttrDX.fFog);
}
#ifdef STEP_FIXED
if ((pStpCtx->uFlags & TRIF_FIXED_OVERFLOW) ||
ABSF(pStpCtx->DAttrNC.fFog) >= Fog_LIMIT ||
ABSF(pStpCtx->DAttrCY.fFog) >= Fog_LIMIT)
{
pStpCtx->uFlags |= TRIF_FIXED_OVERFLOW;
}
#endif
// Call next bead.
pStpCtx->pfnTriSetupFogEnd(pStpCtx, pV0, pV1, pV2);
}
//----------------------------------------------------------------------------
//
// Setup_End
//
// Final bead.
//
//----------------------------------------------------------------------------
d_DeclSetup(`End')dnl
{
}