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.
 
 
 
 
 
 

921 lines
31 KiB

//----------------------------------------------------------------------------
//
// setup.cpp
//
// Generic C++ setup functions.
//
// Copyright (C) Microsoft Corporation, 1997.
//
//----------------------------------------------------------------------------
include(`m4hdr.mh')dnl
#include "rgb_pch.h"
#pragma hdrstop
#include "d3dutil.h"
#include "attrs_mh.h"
#include "tstp_mh.h"
#include "walk_mh.h"
#include "rsdbg.hpp"
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 iTex is the index of texture stage to use.
dnl
define(`d_TexSetupFinish',
` pStpCtx->DAttrDX.fUoW[iTex] = ComputeADX(pStpCtx, fDU20, fDU10);
pStpCtx->DAttrDX.fVoW[iTex] = ComputeADX(pStpCtx, fDV20, fDV10);
pStpCtx->DAttrDY.fUoW[iTex] = ComputeADY(pStpCtx, fDU20, fDU10);
pStpCtx->DAttrDY.fVoW[iTex] = ComputeADY(pStpCtx, fDV20, fDV10);
CORRECT_ATTR(fUoW0 * TEX_SCALE,
pStpCtx->DAttrDX.fUoW[iTex], pStpCtx->DAttrDY.fUoW[iTex],
pStpCtx->Attr.fUoW[iTex],
pStpCtx->DAttrNC.fUoW[iTex], pStpCtx->DAttrCY.fUoW[iTex]);
CORRECT_ATTR(fVoW0 * TEX_SCALE,
pStpCtx->DAttrDX.fVoW[iTex], pStpCtx->DAttrDY.fVoW[iTex],
pStpCtx->Attr.fVoW[iTex],
pStpCtx->DAttrNC.fVoW[iTex], pStpCtx->DAttrCY.fVoW[iTex]);
if (pStpCtx->uFlags & TRIF_X_DEC)
{
pStpCtx->DAttrDX.fUoW[iTex] = NEGF(pStpCtx->DAttrDX.fUoW[iTex]);
pStpCtx->DAttrDX.fVoW[iTex] = NEGF(pStpCtx->DAttrDX.fVoW[iTex]);
}
// 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[iTex]) >= TEX_LIMIT ||
ABSF(pStpCtx->DAttrDX.fVoW[iTex]) >= TEX_LIMIT ||
ABSF(pStpCtx->DAttrDY.fUoW[iTex]) >= TEX_LIMIT ||
ABSF(pStpCtx->DAttrDY.fVoW[iTex]) >= TEX_LIMIT)
{
pStpCtx->uFlags |= TRIF_RASTPRIM_OVERFLOW;
#ifdef DBG_OVERFLOW
RSDPF(("Overflow delta for tex$1: %f,%f,%f,%f\n",
pStpCtx->DAttrDX.fUoW[iTex], pStpCtx->DAttrDX.fVoW[iTex],
pStpCtx->DAttrDY.fUoW[iTex], pStpCtx->DAttrDY.fVoW[iTex]));
#endif
}
else
{
pStpCtx->pPrim->DUVoWDX[iTex].iDUoWDX = FTOI(pStpCtx->DAttrDX.fUoW[iTex]);
pStpCtx->pPrim->DUVoWDX[iTex].iDVoWDX = FTOI(pStpCtx->DAttrDX.fVoW[iTex]);
pStpCtx->pPrim->DUVoWDY[iTex].iDUoWDY = FTOI(pStpCtx->DAttrDY.fUoW[iTex]);
pStpCtx->pPrim->DUVoWDY[iTex].iDVoWDY = FTOI(pStpCtx->DAttrDY.fVoW[iTex]);
}
#ifdef STEP_FIXED
if ((pStpCtx->uFlags & TRIF_FIXED_OVERFLOW) ||
ABSF(pStpCtx->DAttrNC.fUoW[iTex]) >= TEX_LIMIT ||
ABSF(pStpCtx->DAttrCY.fUoW[iTex]) >= TEX_LIMIT ||
ABSF(pStpCtx->DAttrNC.fVoW[iTex]) >= TEX_LIMIT ||
ABSF(pStpCtx->DAttrCY.fVoW[iTex]) >= 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;
INT32 iTex;
for (iTex = 0; iTex < (INT32)pStpCtx->pCtx->cActTex; iTex ++)
{
fUoW0 = ((PRAST_GENERIC_VERTEX)pV0)->texCoord[iTex].dvTU * pV0->dvRHW;
fVoW0 = ((PRAST_GENERIC_VERTEX)pV0)->texCoord[iTex].dvTV * pV0->dvRHW;
fDU20 =
PERSP_TEXTURE_DELTA(((PRAST_GENERIC_VERTEX)pV2)->texCoord[iTex].dvTU, pV2->dvRHW,
((PRAST_GENERIC_VERTEX)pV0)->texCoord[iTex].dvTU, fUoW0,
pStpCtx->pCtx->pdwRenderState[D3DRS_WRAP0+iTex] & D3DWRAP_U) *
TEX_SCALE;
fDU10 =
PERSP_TEXTURE_DELTA(((PRAST_GENERIC_VERTEX)pV1)->texCoord[iTex].dvTU, pV1->dvRHW,
((PRAST_GENERIC_VERTEX)pV0)->texCoord[iTex].dvTU, fUoW0,
pStpCtx->pCtx->pdwRenderState[D3DRS_WRAP0+iTex] & D3DWRAP_U) *
TEX_SCALE;
fDV20 =
PERSP_TEXTURE_DELTA(((PRAST_GENERIC_VERTEX)pV2)->texCoord[iTex].dvTV, pV2->dvRHW,
((PRAST_GENERIC_VERTEX)pV0)->texCoord[iTex].dvTV, fVoW0,
pStpCtx->pCtx->pdwRenderState[D3DRS_WRAP0+iTex] & D3DWRAP_V) *
TEX_SCALE;
fDV10 =
PERSP_TEXTURE_DELTA(((PRAST_GENERIC_VERTEX)pV1)->texCoord[iTex].dvTV, pV1->dvRHW,
((PRAST_GENERIC_VERTEX)pV0)->texCoord[iTex].dvTV, fVoW0,
pStpCtx->pCtx->pdwRenderState[D3DRS_WRAP0+iTex] & D3DWRAP_V) *
TEX_SCALE;
d_TexSetupFinish()dnl
}
}
// This was disabled when changing the rasterizers to support 8 textures
#if 0
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));
#endif
')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;
INT32 iTex;
for (iTex = 0; iTex < (INT32)pStpCtx->pCtx->cActTex; iTex ++)
{
fUoW0 = ((PRAST_GENERIC_VERTEX)pV0)->texCoord[iTex].dvTU;
fVoW0 = ((PRAST_GENERIC_VERTEX)pV0)->texCoord[iTex].dvTV;
fDU20 =
InlTextureDiff(((PRAST_GENERIC_VERTEX)pV2)->texCoord[iTex].dvTU, fUoW0,
pStpCtx->pCtx->pdwRenderState[D3DRS_WRAP0+iTex] & D3DWRAP_U) *
TEX_SCALE;
fDU10 =
InlTextureDiff(((PRAST_GENERIC_VERTEX)pV1)->texCoord[iTex].dvTU, fUoW0,
pStpCtx->pCtx->pdwRenderState[D3DRS_WRAP0+iTex] & D3DWRAP_U) *
TEX_SCALE;
fDV20 =
InlTextureDiff(((PRAST_GENERIC_VERTEX)pV2)->texCoord[iTex].dvTV, fVoW0,
pStpCtx->pCtx->pdwRenderState[D3DRS_WRAP0+iTex] & D3DWRAP_V) *
TEX_SCALE;
fDV10 =
InlTextureDiff(((PRAST_GENERIC_VERTEX)pV1)->texCoord[iTex].dvTV, fVoW0,
pStpCtx->pCtx->pdwRenderState[D3DRS_WRAP0+iTex] & D3DWRAP_V) *
TEX_SCALE;
d_TexSetupFinish()dnl
}
}
// This was disabled when changing the rasterizers to support 8 textures
#if 0
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));
#endif
')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_Tex
//
// Attribute setup for OoW and texture coordinates.
// Coordinates are set up for perspective correction.
//
//----------------------------------------------------------------------------
d_DeclSetup(`Persp_Tex')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()dnl
// Call next bead.
pStpCtx->pfnTriSetupTexEnd(pStpCtx, pV0, pV1, pV2);
}
//----------------------------------------------------------------------------
//
// Setup_Affine_Tex
//
// Attribute setup for OoW and texture coordinates.
// Coordinates are set up for affine mapping.
//
//----------------------------------------------------------------------------
d_DeclSetup(`Affine_Tex')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()dnl
// Call next bead.
pStpCtx->pfnTriSetupTexEnd(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
{
}