//---------------------------------------------------------------------------- // // 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 { }