|
|
//----------------------------------------------------------------------------
//
// attrs.cpp
//
// Cross-platform attribute handling functions.
//
// Copyright (C) Microsoft Corporation, 1997.
//
//----------------------------------------------------------------------------
#include "rgb_pch.h"
#pragma hdrstop
#include "d3dutil.h"
#include "setup.hpp"
#include "attrs_mh.h"
#include "tstp_mh.h"
#include "walk_mh.h"
#include "rsdbg.hpp"
//----------------------------------------------------------------------------
//
// AddFloatAttrs_Any
//
// Adds a set of attribute deltas to an ATTRSET.
// Handles any set of attributes via USED flags.
//
//----------------------------------------------------------------------------
void FASTCALL AddFloatAttrs_Any(PATTRSET pAttr, PATTRSET pDelta, PSETUPCTX pStpCtx) { pAttr->pSurface += pDelta->ipSurface; pAttr->pZ += pDelta->ipZ;
if (pStpCtx->uFlags & PRIMSF_Z_USED) { pAttr->fZ += pDelta->fZ; }
if (pStpCtx->uFlags & PRIMSF_TEX_USED) { pAttr->fOoW += pDelta->fOoW; pAttr->fUoW[0] += pDelta->fUoW[0]; pAttr->fVoW[0] += pDelta->fVoW[0]; }
if (pStpCtx->uFlags & PRIMSF_TEX2_USED) { for (INT32 i = 1; i < (INT32)pStpCtx->pCtx->cActTex; i++) { pAttr->fUoW[i] += pDelta->fUoW[i]; pAttr->fVoW[i] += pDelta->fVoW[i]; } }
if (pStpCtx->uFlags & PRIMSF_DIFF_USED) { pAttr->fB += pDelta->fB; pAttr->fG += pDelta->fG; pAttr->fR += pDelta->fR; pAttr->fA += pDelta->fA; } else if (pStpCtx->uFlags & PRIMSF_DIDX_USED) { pAttr->fDIdx += pDelta->fDIdx; pAttr->fDIdxA += pDelta->fDIdxA; }
if (pStpCtx->uFlags & PRIMSF_SPEC_USED) { pAttr->fBS += pDelta->fBS; pAttr->fGS += pDelta->fGS; pAttr->fRS += pDelta->fRS; } if (pStpCtx->uFlags & PRIMSF_LOCAL_FOG_USED) { pAttr->fFog += pDelta->fFog; } }
//----------------------------------------------------------------------------
//
// AddScaledFloatAttrs_Any_Either
//
// Scales and adds a set of attribute deltas to an ATTRSET.
// Handles any set of attributes via USED flags.
// Uses PWL support.
//
//----------------------------------------------------------------------------
void FASTCALL AddScaledFloatAttrs_Any_Either(PATTRSET pAttr, PATTRSET pDelta, PSETUPCTX pStpCtx, INT iScale) { FLOAT fScale = (FLOAT)iScale;
pAttr->pSurface += pDelta->ipSurface * iScale; pAttr->pZ += pDelta->ipZ * iScale;
if (pStpCtx->uFlags & PRIMSF_Z_USED) { #ifdef PWL_FOG
if (pStpCtx->uPwlFlags & PWL_NEXT_FOG) { pAttr->fZ = pStpCtx->fNextZ; } else #endif
{ pAttr->fZ += pDelta->fZ * fScale; } }
if (pStpCtx->uFlags & PRIMSF_TEX_USED) { if (pStpCtx->uPwlFlags & PWL_NEXT_LOD) { pAttr->fOoW = pStpCtx->fNextOoW; pAttr->fUoW[0] = pStpCtx->fNextUoW1; pAttr->fVoW[0] = pStpCtx->fNextVoW1; } else { pAttr->fOoW += pDelta->fOoW * fScale; pAttr->fUoW[0] += pDelta->fUoW[0] * fScale; pAttr->fVoW[0] += pDelta->fVoW[0] * fScale; } }
if (pStpCtx->uFlags & PRIMSF_TEX2_USED) { for (INT32 i = 1; i < (INT32)pStpCtx->pCtx->cActTex; i++) { pAttr->fUoW[i] += pDelta->fUoW[i] * fScale; pAttr->fVoW[i] += pDelta->fVoW[i] * fScale; } }
if (pStpCtx->uFlags & PRIMSF_DIFF_USED) { pAttr->fB += pDelta->fB * fScale; pAttr->fG += pDelta->fG * fScale; pAttr->fR += pDelta->fR * fScale; pAttr->fA += pDelta->fA * fScale; } else if (pStpCtx->uFlags & PRIMSF_DIDX_USED) { pAttr->fDIdx += pDelta->fDIdx * fScale; pAttr->fDIdxA += pDelta->fDIdxA * fScale; }
if (pStpCtx->uFlags & PRIMSF_SPEC_USED) { pAttr->fBS += pDelta->fBS * fScale; pAttr->fGS += pDelta->fGS * fScale; pAttr->fRS += pDelta->fRS * fScale; }
if (pStpCtx->uFlags & PRIMSF_LOCAL_FOG_USED) { pAttr->fFog += pDelta->fFog * fScale; } }
//----------------------------------------------------------------------------
//
// FillSpanFloatAttrs_Any_Either
//
// Fills in a span structure with the given attributes.
// Handles any set of attributes via USED flags.
// Uses and updates PWL support.
//
//----------------------------------------------------------------------------
void FASTCALL FillSpanFloatAttrs_Any_Either(PATTRSET pAttr, PD3DI_RASTSPAN pSpan, PSETUPCTX pStpCtx, INT cPix) { FLOAT fPix = (FLOAT)cPix; pSpan->pSurface = pAttr->pSurface; pSpan->pZ = pAttr->pZ;
if (pStpCtx->uFlags & PRIMSF_Z_USED) { pSpan->uZ = FTOI(pAttr->fZ); }
if (pStpCtx->uFlags & PRIMSF_TEX_USED) { FLOAT fW; if (pStpCtx->uPwlFlags & PWL_NEXT_LOD) { fW = pStpCtx->fNextW; } else if (pStpCtx->uFlags & PRIMSF_PERSP_USED) { if (FLOAT_EQZ(pAttr->fOoW)) { fW = g_fZero; } else { fW = OOW_SCALE / pAttr->fOoW; } } else { fW = g_fOne; } pSpan->iW = FTOI(fW * W_SCALE);
if (pStpCtx->uFlags & PRIMSF_LOD_USED) { // Mipmapping is enabled so compute texture LOD.
// The span code can do linear LOD interpolation
// so that we can do piecewise-linear approximations
// instead of true per-pixel LOD. In order to make this
// work we need to compute the next LOD and a delta
// value. All of these values can be reused if this
// loop goes around so keep them available for the next
// iteration and set a flag to indicate that they've
// been computed.
if (pStpCtx->uPwlFlags & PWL_NEXT_LOD) { pSpan->iLOD = (INT16)pStpCtx->iNextLOD; } else { pSpan->iLOD = (INT16)ComputeLOD(pStpCtx->pCtx, (pAttr->fUoW[0] * OO_TEX_SCALE) * fW, (pAttr->fVoW[0] * OO_TEX_SCALE) * fW, fW, (pStpCtx->DAttrDX.fUoW[0] * OO_TEX_SCALE), (pStpCtx->DAttrDX.fVoW[0] * OO_TEX_SCALE), (pStpCtx->DAttrDX.fOoW * OO_OOW_SCALE), (pStpCtx->DAttrDY.fUoW[0] * OO_TEX_SCALE), (pStpCtx->DAttrDY.fVoW[0] * OO_TEX_SCALE), (pStpCtx->DAttrDY.fOoW * OO_OOW_SCALE)); } if (pStpCtx->uFlags & PRIMSF_PERSP_USED) { pStpCtx->fNextOoW = pAttr->fOoW + pStpCtx->DAttrDX.fOoW * fPix; if (FLOAT_EQZ(pStpCtx->fNextOoW)) { fW = g_fZero; } else { fW = OOW_SCALE / pStpCtx->fNextOoW; } } else { pStpCtx->fNextOoW = OOW_SCALE; fW = g_fOne; } pStpCtx->fNextW = fW; pStpCtx->fNextUoW1 = pAttr->fUoW[0] + pStpCtx->DAttrDX.fUoW[0] * fPix; pStpCtx->fNextVoW1 = pAttr->fVoW[0] + pStpCtx->DAttrDX.fVoW[0] * fPix; pStpCtx->iNextLOD = ComputeLOD(pStpCtx->pCtx, (pStpCtx->fNextUoW1 * OO_TEX_SCALE) * fW, (pStpCtx->fNextVoW1 * OO_TEX_SCALE) * fW, fW, (pStpCtx->DAttrDX.fUoW[0] * OO_TEX_SCALE), (pStpCtx->DAttrDX.fVoW[0] * OO_TEX_SCALE), (pStpCtx->DAttrDX.fOoW * OO_OOW_SCALE), (pStpCtx->DAttrDY.fUoW[0] * OO_TEX_SCALE), (pStpCtx->DAttrDY.fVoW[0] * OO_TEX_SCALE), (pStpCtx->DAttrDY.fOoW * OO_OOW_SCALE)); pStpCtx->uPwlFlags |= PWL_NEXT_LOD; pSpan->iDLOD = (INT16)(FTOI((FLOAT)(pStpCtx->iNextLOD - pSpan->iLOD) / fPix)); } else { pSpan->iLOD = 0; pSpan->iDLOD = 0; } pSpan->iOoW = FTOI(pAttr->fOoW); pSpan->UVoW[0].iUoW = FTOI(pAttr->fUoW[0]); pSpan->UVoW[0].iVoW = FTOI(pAttr->fVoW[0]); }
if (pStpCtx->uFlags & PRIMSF_TEX2_USED) { for (INT32 i = 1; i < (INT32)pStpCtx->pCtx->cActTex; i++) { pSpan->UVoW[i].iUoW = FTOI(pAttr->fUoW[i]); pSpan->UVoW[i].iVoW = FTOI(pAttr->fVoW[i]); } }
if (pStpCtx->uFlags & PRIMSF_DIFF_USED) { pSpan->uB = (UINT16)(FTOI(pAttr->fB)); pSpan->uG = (UINT16)(FTOI(pAttr->fG)); pSpan->uR = (UINT16)(FTOI(pAttr->fR)); pSpan->uA = (UINT16)(FTOI(pAttr->fA)); } else if (pStpCtx->uFlags & PRIMSF_DIDX_USED) { pSpan->iIdx = FTOI(pAttr->fDIdx); pSpan->iIdxA = FTOI(pAttr->fDIdxA); }
if (pStpCtx->uFlags & PRIMSF_SPEC_USED) { pSpan->uBS = (UINT16)(FTOI(pAttr->fBS)); pSpan->uGS = (UINT16)(FTOI(pAttr->fGS)); pSpan->uRS = (UINT16)(FTOI(pAttr->fRS)); } if (pStpCtx->uFlags & PRIMSF_LOCAL_FOG_USED) { pSpan->uFog = (UINT16)(FTOI(pAttr->fFog)); pSpan->iDFog = (INT16)(pStpCtx->iDLocalFogDX); } #ifdef PWL_FOG
else if (pStpCtx->uFlags & PRIMSF_GLOBAL_FOG_USED) { FLOAT fOoZScale; // The span code doesn't have direct global fog support.
// It's faked by setup doing PWL approximations here
// similarly to how LOD is handled.
if (pStpCtx->pCtx->iZBitCount == 16) { fOoZScale = OO_Z16_SCALE; } else { fOoZScale = OO_Z32_SCALE; } if (pStpCtx->uPwlFlags & PWL_NEXT_FOG) { pSpan->uFog = pStpCtx->uNextFog; } else { pSpan->uFog = ComputeTableFog(pStpCtx->pCtx->pdwRenderState, pAttr->fZ * fOoZScale); }
if ((pStpCtx->uPwlFlags & PWL_NO_NEXT_FOG) == 0) { pStpCtx->fNextZ = pAttr->fZ + pStpCtx->DAttrDX.fZ * fPix; pStpCtx->uNextFog = ComputeTableFog(pStpCtx->pCtx->pdwRenderState, pStpCtx->fNextZ * fOoZScale); pStpCtx->uPwlFlags |= PWL_NEXT_FOG; pSpan->iDFog = FTOI((FLOAT)((INT)pStpCtx->uNextFog - (INT)pSpan->uFog) / fPix); } else { pSpan->iDFog = 0; } } #endif
}
//
// Tables of attribute handlers.
// Indexing is with the low four PRIMSF_*_USED bits.
//
// Attribute adders.
PFN_ADDATTRS g_pfnAddFloatAttrsTable[] = { (PFN_ADDATTRS)DebugBreakFn, /* 0: -2 -1 -S -D */ AddFloatAttrs_Z_Diff, /* 1: -2 -1 -S +D */ (PFN_ADDATTRS)DebugBreakFn, /* 2: -2 -1 +S -D */ AddFloatAttrs_Z_Diff_Spec, /* 3: -2 -1 +S +D */ (PFN_ADDATTRS)DebugBreakFn, /* 4: -2 +1 -S -D */ AddFloatAttrs_Z_Diff_Tex, /* 5: -2 +1 -S +D */ (PFN_ADDATTRS)DebugBreakFn, /* 6: -2 +1 +S -D */ AddFloatAttrs_Z_Diff_Spec_Tex, /* 7: -2 +1 +S +D */ (PFN_ADDATTRS)DebugBreakFn, /* 8: +2 -1 -S -D */ (PFN_ADDATTRS)DebugBreakFn, /* 9: +2 -1 -S +D */ (PFN_ADDATTRS)DebugBreakFn, /* A: +2 -1 +S -D */ (PFN_ADDATTRS)DebugBreakFn, /* B: +2 -1 +S +D */ AddFloatAttrs_Z_Tex, /* C: +2 +1 -S -D */ (PFN_ADDATTRS)DebugBreakFn, /* D: +2 +1 -S +D */ (PFN_ADDATTRS)DebugBreakFn, /* E: +2 +1 +S -D */ (PFN_ADDATTRS)DebugBreakFn, /* F: +2 +1 +S +D */ }; #ifdef STEP_FIXED
PFN_ADDATTRS g_pfnAddFixedAttrsTable[] = { (PFN_ADDATTRS)DebugBreakFn, /* 0: -2 -1 -S -D */ AddFixedAttrs_Z_Diff, /* 1: -2 -1 -S +D */ (PFN_ADDATTRS)DebugBreakFn, /* 2: -2 -1 +S -D */ AddFixedAttrs_Z_Diff_Spec, /* 3: -2 -1 +S +D */ (PFN_ADDATTRS)DebugBreakFn, /* 4: -2 +1 -S -D */ AddFixedAttrs_Z_Diff_Tex, /* 5: -2 +1 -S +D */ (PFN_ADDATTRS)DebugBreakFn, /* 6: -2 +1 +S -D */ AddFixedAttrs_Z_Diff_Spec_Tex, /* 7: -2 +1 +S +D */ (PFN_ADDATTRS)DebugBreakFn, /* 8: +2 -1 -S -D */ (PFN_ADDATTRS)DebugBreakFn, /* 9: +2 -1 -S +D */ (PFN_ADDATTRS)DebugBreakFn, /* A: +2 -1 +S -D */ (PFN_ADDATTRS)DebugBreakFn, /* B: +2 -1 +S +D */ AddFixedAttrs_Z_Tex, /* C: +2 +1 -S -D */ (PFN_ADDATTRS)DebugBreakFn, /* D: +2 +1 -S +D */ (PFN_ADDATTRS)DebugBreakFn, /* E: +2 +1 +S -D */ (PFN_ADDATTRS)DebugBreakFn, /* F: +2 +1 +S +D */ }; #endif
// Scaled attribute adders without PWL support.
PFN_ADDSCALEDATTRS g_pfnAddScaledFloatAttrsTable[] = { (PFN_ADDSCALEDATTRS)DebugBreakFn, /* 0: -2 -1 -S -D */ AddScaledFloatAttrs_Z_Diff, /* 1: -2 -1 -S +D */ (PFN_ADDSCALEDATTRS)DebugBreakFn, /* 2: -2 -1 +S -D */ AddScaledFloatAttrs_Z_Diff_Spec, /* 3: -2 -1 +S +D */ (PFN_ADDSCALEDATTRS)DebugBreakFn, /* 4: -2 +1 -S -D */ AddScaledFloatAttrs_Z_Diff_Tex, /* 5: -2 +1 -S +D */ (PFN_ADDSCALEDATTRS)DebugBreakFn, /* 6: -2 +1 +S -D */ AddScaledFloatAttrs_Z_Diff_Spec_Tex, /* 7: -2 +1 +S +D */ (PFN_ADDSCALEDATTRS)DebugBreakFn, /* 8: +2 -1 -S -D */ (PFN_ADDSCALEDATTRS)DebugBreakFn, /* 9: +2 -1 -S +D */ (PFN_ADDSCALEDATTRS)DebugBreakFn, /* A: +2 -1 +S -D */ (PFN_ADDSCALEDATTRS)DebugBreakFn, /* B: +2 -1 +S +D */ AddScaledFloatAttrs_Z_Tex, /* C: +2 +1 -S -D */ (PFN_ADDSCALEDATTRS)DebugBreakFn, /* D: +2 +1 -S +D */ (PFN_ADDSCALEDATTRS)DebugBreakFn, /* E: +2 +1 +S -D */ (PFN_ADDSCALEDATTRS)DebugBreakFn, /* F: +2 +1 +S +D */ };
// RASTSPAN filling functions.
PFN_FILLSPANATTRS g_pfnFillSpanFloatAttrsTable[] = { (PFN_FILLSPANATTRS)DebugBreakFn, /* 0: -2 -1 -S -D */ FillSpanFloatAttrs_Z_Diff, /* 1: -2 -1 -S +D */ (PFN_FILLSPANATTRS)DebugBreakFn, /* 2: -2 -1 +S -D */ FillSpanFloatAttrs_Z_Diff_Spec, /* 3: -2 -1 +S +D */ (PFN_FILLSPANATTRS)DebugBreakFn, /* 4: -2 +1 -S -D */ FillSpanFloatAttrs_Z_Diff_Tex, /* 5: -2 +1 -S +D */ (PFN_FILLSPANATTRS)DebugBreakFn, /* 6: -2 +1 +S -D */ FillSpanFloatAttrs_Z_Diff_Spec_Tex, /* 7: -2 +1 +S +D */ (PFN_FILLSPANATTRS)DebugBreakFn, /* 8: +2 -1 -S -D */ (PFN_FILLSPANATTRS)DebugBreakFn, /* 9: +2 -1 -S +D */ (PFN_FILLSPANATTRS)DebugBreakFn, /* A: +2 -1 +S -D */ (PFN_FILLSPANATTRS)DebugBreakFn, /* B: +2 -1 +S +D */ FillSpanFloatAttrs_Z_Tex, /* C: +2 +1 -S -D */ (PFN_FILLSPANATTRS)DebugBreakFn, /* D: +2 +1 -S +D */ (PFN_FILLSPANATTRS)DebugBreakFn, /* E: +2 +1 +S -D */ (PFN_FILLSPANATTRS)DebugBreakFn, /* F: +2 +1 +S +D */ }; #ifdef STEP_FIXED
PFN_FILLSPANATTRS g_pfnFillSpanFixedAttrsTable[] = { (PFN_FILLSPANATTRS)DebugBreakFn, /* 0: -2 -1 -S -D */ FillSpanFixedAttrs_Z_Diff, /* 1: -2 -1 -S +D */ (PFN_FILLSPANATTRS)DebugBreakFn, /* 2: -2 -1 +S -D */ FillSpanFixedAttrs_Z_Diff_Spec, /* 3: -2 -1 +S +D */ (PFN_FILLSPANATTRS)DebugBreakFn, /* 4: -2 +1 -S -D */ FillSpanFixedAttrs_Z_Diff_Tex, /* 5: -2 +1 -S +D */ (PFN_FILLSPANATTRS)DebugBreakFn, /* 6: -2 +1 +S -D */ FillSpanFixedAttrs_Z_Diff_Spec_Tex, /* 7: -2 +1 +S +D */ (PFN_FILLSPANATTRS)DebugBreakFn, /* 8: +2 -1 -S -D */ (PFN_FILLSPANATTRS)DebugBreakFn, /* 9: +2 -1 -S +D */ (PFN_FILLSPANATTRS)DebugBreakFn, /* A: +2 -1 +S -D */ (PFN_FILLSPANATTRS)DebugBreakFn, /* B: +2 -1 +S +D */ FillSpanFixedAttrs_Z_Tex, /* C: +2 +1 -S -D */ (PFN_FILLSPANATTRS)DebugBreakFn, /* D: +2 +1 -S +D */ (PFN_FILLSPANATTRS)DebugBreakFn, /* E: +2 +1 +S -D */ (PFN_FILLSPANATTRS)DebugBreakFn, /* F: +2 +1 +S +D */ }; #endif
// Float-to-fixed attribute converters.
#ifdef STEP_FIXED
PFN_FLOATATTRSTOFIXED g_pfnFloatAttrsToFixedTable[] = { (PFN_FLOATATTRSTOFIXED)DebugBreakFn, /* 0: -2 -1 -S -D */ FloatAttrsToFixed_Z_Diff, /* 1: -2 -1 -S +D */ (PFN_FLOATATTRSTOFIXED)DebugBreakFn, /* 2: -2 -1 +S -D */ FloatAttrsToFixed_Z_Diff_Spec, /* 3: -2 -1 +S +D */ (PFN_FLOATATTRSTOFIXED)DebugBreakFn, /* 4: -2 +1 -S -D */ FloatAttrsToFixed_Z_Diff_Tex, /* 5: -2 +1 -S +D */ (PFN_FLOATATTRSTOFIXED)DebugBreakFn, /* 6: -2 +1 +S -D */ FloatAttrsToFixed_Z_Diff_Spec_Tex, /* 7: -2 +1 +S +D */ (PFN_FLOATATTRSTOFIXED)DebugBreakFn, /* 8: +2 -1 -S -D */ (PFN_FLOATATTRSTOFIXED)DebugBreakFn, /* 9: +2 -1 -S +D */ (PFN_FLOATATTRSTOFIXED)DebugBreakFn, /* A: +2 -1 +S -D */ (PFN_FLOATATTRSTOFIXED)DebugBreakFn, /* B: +2 -1 +S +D */ FloatAttrsToFixed_Z_Tex, /* C: +2 +1 -S -D */ (PFN_FLOATATTRSTOFIXED)DebugBreakFn, /* D: +2 +1 -S +D */ (PFN_FLOATATTRSTOFIXED)DebugBreakFn, /* E: +2 +1 +S -D */ (PFN_FLOATATTRSTOFIXED)DebugBreakFn, /* F: +2 +1 +S +D */ }; #endif
//
// Tables of ramp mode attribute handlers.
// Indexing is with PRIMSF_TEX1_USED and PRIMSF_DIDX_USED.
//
// Attribute adders.
PFN_ADDATTRS g_pfnRampAddFloatAttrsTable[] = { (PFN_ADDATTRS)DebugBreakFn, /* 0: -I -1 */ AddFloatAttrs_Z_Tex, /* 1: -I +1 */ AddFloatAttrs_Z_DIdx, /* 2: +I -1 */ AddFloatAttrs_Z_DIdx_Tex, /* 3: +I +1 */ };
// Scaled attribute adders without PWL support.
PFN_ADDSCALEDATTRS g_pfnRampAddScaledFloatAttrsTable[] = { (PFN_ADDSCALEDATTRS)DebugBreakFn, /* 0: -I -1 */ AddScaledFloatAttrs_Z_Tex, /* 1: -I +1 */ AddScaledFloatAttrs_Z_DIdx, /* 2: +I -1 */ AddScaledFloatAttrs_Z_DIdx_Tex, /* 3: +I +1 */ };
// RASTSPAN filling functions.
PFN_FILLSPANATTRS g_pfnRampFillSpanFloatAttrsTable[] = { (PFN_FILLSPANATTRS)DebugBreakFn, /* 0: -I -1 */ FillSpanFloatAttrs_Z_Tex, /* 1: -I +1 */ FillSpanFloatAttrs_Z_DIdx, /* 2: +I -1 */ FillSpanFloatAttrs_Z_DIdx_Tex, /* 3: +I +1 */ };
|