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.
 
 
 
 
 
 

542 lines
20 KiB

//----------------------------------------------------------------------------
//
// 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 */
};