//---------------------------------------------------------------------------- // // setup.hpp // // Setup declarations. // // Copyright (C) Microsoft Corporation, 1997. // //---------------------------------------------------------------------------- #ifndef _SETUP_HPP_ #define _SETUP_HPP_ #pragma warning(disable:4786) #include "stp_base.h" // PrimProcessor flags. #define PPF_IN_BEGIN 0x00000001 #define PPF_STATE_CHANGED 0x00000002 #define PPF_NORMALIZE_RHW 0x00000004 #define PPF_DRAW_LAST_LINE_PIXEL 0x00000008 // Bounds for normalized RHWs. These are not quite the ideal bounds to // avoid over- and underflow after normalization when at least one RHW is // guaranteed to be at the bounds. There is no reason it // has to be normalized to [0,1] anway, other than to try and spread // the values across the desired range. #define NORMALIZED_RHW_MIN g_fZero #define NORMALIZED_RHW_MAX g_fp95 //---------------------------------------------------------------------------- // // PrimProcessor // // Accepts primitives to be rasterized. Primitive and span descriptions // are put into a buffer for later processing by the span-level code. // //---------------------------------------------------------------------------- class DllExport PrimProcessor { public: PrimProcessor(void); HRESULT Initialize(void); ~PrimProcessor(void); inline UINT GetFlags(void); inline void SetFlags(UINT uFlags); inline void ClrFlags(UINT uFlags); inline void StateChanged(); void SetCtx(PD3DI_RASTCTX pCtx); void BeginPrimSet(D3DPRIMITIVETYPE PrimType, RAST_VERTEX_TYPE VertType); HRESULT Point(LPD3DTLVERTEX pV0, LPD3DTLVERTEX pFlatVtx); HRESULT Line(LPD3DTLVERTEX pV0, LPD3DTLVERTEX pV1, LPD3DTLVERTEX pFlatVtx); HRESULT Tri(LPD3DTLVERTEX pV0, LPD3DTLVERTEX pV1, LPD3DTLVERTEX pV2); void Begin(void); HRESULT End(void); HRESULT AllocSpans(PUINT pcSpans, PD3DI_RASTSPAN *ppSpan); void FreeSpans(UINT cSpans); private: // Original FP control word. UINT16 m_uFpCtrl; // Buffer space and current pointer. PUINT8 m_pBuffer; PUINT8 m_pBufferStart; PUINT8 m_pBufferEnd; PUINT8 m_pCur; // Flags. UINT m_uPpFlags; // // Intermediate results shared between methods. // SETUPCTX m_StpCtx; // Previous primitive, for primitive chaining. PD3DI_RASTPRIM m_pOldPrim; // Attribute function table index. INT m_iAttrFnIdx; // Old primitive and vertex types. D3DPRIMITIVETYPE m_PrimType; RAST_VERTEX_TYPE m_VertType; // // Triangle values. // // Y values and trapezoid heights. INT m_iY1, m_iY2; UINT m_uHeight10, m_uHeight21, m_uHeight20; // Triangle X extent. INT m_iXWidth; // Original RHW saved during RHW normalization. D3DVALUE m_dvV0RHW; D3DVALUE m_dvV1RHW; D3DVALUE m_dvV2RHW; // // Point methods. // void NormalizePointRHW(LPD3DTLVERTEX pV0); void FillPointSpan(LPD3DTLVERTEX pV0, PD3DI_RASTSPAN pSpan); // // Line methods. // void NormalizeLineRHW(LPD3DTLVERTEX pV0, LPD3DTLVERTEX pV1); BOOL PointDiamondCheck(INT32 iXFrac, INT32 iYFrac, BOOL bSlopeIsOne, BOOL bSlopeIsPosOne); BOOL LineSetup(LPD3DTLVERTEX pV0, LPD3DTLVERTEX pV1); // // Triangle methods. // void NormalizeTriRHW(LPD3DTLVERTEX pV0, LPD3DTLVERTEX pV1, LPD3DTLVERTEX pV2); BOOL TriSetup(LPD3DTLVERTEX pV0, LPD3DTLVERTEX pV1, LPD3DTLVERTEX pV2); inline void SetTriFunctions(void); // // Buffer management methods. // inline void ResetBuffer(void); HRESULT Flush(void); HRESULT FlushPartial(void); HRESULT AppendPrim(void); #if DBG // // Debug methods. Only callable within DBG builds. // inline HRESULT ValidateVertex(LPD3DTLVERTEX pV); #endif }; //---------------------------------------------------------------------------- // // PrimProcessor::GetFlags // // Returns the current PrimProcessor flags. // //---------------------------------------------------------------------------- inline UINT PrimProcessor::GetFlags(void) { return m_uPpFlags; } //---------------------------------------------------------------------------- // // PrimProcessor::SetFlags // // Sets the given flags. // //---------------------------------------------------------------------------- inline void PrimProcessor::SetFlags(UINT uFlags) { m_uPpFlags |= uFlags; } //---------------------------------------------------------------------------- // // PrimProcessor::ClrFlags // // Clears the given flags. // //---------------------------------------------------------------------------- inline void PrimProcessor::ClrFlags(UINT uFlags) { m_uPpFlags &= ~uFlags; } //---------------------------------------------------------------------------- // // PrimProcessor::StateChanged // // Notifies the PrimProcessor that state has changed. // Could be done through SetFlags but this hides the actual implementation. // //---------------------------------------------------------------------------- inline void PrimProcessor::StateChanged(void) { m_uPpFlags |= PPF_STATE_CHANGED; } //---------------------------------------------------------------------------- // // PrimProcessor::ComputeIntCarry // // Takes an FP coordinate value and span delta and computes integer form // for int/carry arithmetic. // // NOTE: Assumes iV already computed. // // Written as a macro because the compiler doesn't inline it even when // declared as an inline method. // //---------------------------------------------------------------------------- // Prototype is: // inline void // PrimProcessor::ComputeIntCarry(FLOAT fV, FLOAT fDVDS, PINTCARRYVAL pICY) // // Fraction is biased by one to handle exactly-integer coordinate // values properly. #define ComputeIntCarry(fV, fDVDS, pICY) \ ((pICY)->iFrac = (SCALED_FRACTION((fV) - FLOORF(fV)) - 1) & 0x7fffffff, \ (pICY)->iNC = FTOI(fDVDS), \ (pICY)->iDFrac = SCALED_FRACTION((fDVDS) - (pICY)->iNC), \ (pICY)->iCY = FLOAT_LTZ(fDVDS) ? (pICY)->iNC - 1 : (pICY)->iNC + 1) //---------------------------------------------------------------------------- // // PrimProcessor::GetPrim // // Moves prim pointer to the next position in the buffer, flushing // to make space if necessary. Checks to see if there's space for // at least one span also since it doesn't make much sense to not // flush if there's exactly enough space for just the prim structure. // // Does not update m_pCur until CommitPrim. m_pCur == pPrim // indicates pPrim is not fully valid. // // Written as a macro because the compiler doesn't inline it even when // declared as an inline method. // //---------------------------------------------------------------------------- #define GET_PRIM() \ { \ if (m_pCur + (sizeof(D3DI_RASTPRIM) + sizeof(D3DI_RASTSPAN)) > \ m_pBufferEnd) \ { \ HRESULT hr; \ \ RSHRRET(Flush()); \ } \ \ m_StpCtx.pPrim = (PD3DI_RASTPRIM)m_pCur; \ } //---------------------------------------------------------------------------- // // PrimProcessor::CommitPrim // // Commits the current primitive space so that spans may be added. // The primitive data can be partly or fulled cleared as part of // the commit. // // Written as a macro because the compiler doesn't inline it even when // declared as an inline method. // //---------------------------------------------------------------------------- #define COMMIT_PRIM(bClearAll) \ { \ m_pCur = (PUINT8)(m_StpCtx.pPrim + 1); \ \ if (m_pOldPrim != NULL) \ { \ m_pOldPrim->pNext = m_StpCtx.pPrim; \ } \ m_pOldPrim = m_StpCtx.pPrim; \ \ if (bClearAll) \ { \ memset(m_StpCtx.pPrim, 0, sizeof(*m_StpCtx.pPrim)); \ } \ else \ { \ m_StpCtx.pPrim->uSpans = 0; \ m_StpCtx.pPrim->pNext = NULL; \ } \ } #define ALLOC_SPANS(pStpCtx, pcSpans, ppSpan) \ ((PrimProcessor *)pStpCtx->PrimProcessor)->AllocSpans(pcSpans, ppSpan) #define FREE_SPANS(pStpCtx, cSpans) \ ((PrimProcessor *)pStpCtx->PrimProcessor)->FreeSpans(cSpans) // Compute texture difference times 1/W. #define PERSP_TEXTURE_DELTA(fTb, fRb, fTa, fTRa, iWrap) \ ((TextureDiff((fTb), (fTa), (iWrap)) + (fTa)) * (fRb) - (fTRa)) // Extract components from a packed color. #define SPLIT_COLOR(uPacked, uB, uG, uR, uA) \ ((uB) = (UINT)RGBA_GETBLUE(uPacked), \ (uG) = (UINT)RGBA_GETGREEN(uPacked), \ (uR) = (UINT)RGBA_GETRED(uPacked), \ (uA) = (UINT)RGBA_GETALPHA(uPacked)) // Compute FP deltas from the difference of the given packed color // and the given components. #define COLOR_DELTA(uPacked, uB, uG, uR, uA, fDB, fDG, fDR, fDA) \ ((fDB) = (FLOAT)((INT)((UINT)RGBA_GETBLUE(uPacked)-(uB)) << COLOR_SHIFT), \ (fDG) = (FLOAT)((INT)((UINT)RGBA_GETGREEN(uPacked)-(uG)) << COLOR_SHIFT),\ (fDR) = (FLOAT)((INT)((UINT)RGBA_GETRED(uPacked)-(uR)) << COLOR_SHIFT), \ (fDA) = (FLOAT)((INT)((UINT)RGBA_GETALPHA(uPacked)-(uA)) << COLOR_SHIFT)) // Extract components from a packed index color. // Applies a .5F offset to the color index to effect rounding // when the color index is truncated. #define SPLIT_IDX_COLOR(uPacked, iIdx, iA) \ ((iIdx) = (INT32)CI_MASKALPHA(uPacked) + (1<<(INDEX_COLOR_VERTEX_SHIFT-1)), \ (iA) = (INT32)CI_GETALPHA(uPacked)) #define IDX_COLOR_DELTA(uPacked, iIdx, iA, fDIdx, fDA) \ ((fDIdx) = (FLOAT)((((INT32)CI_MASKALPHA(uPacked) + \ (1<<(INDEX_COLOR_VERTEX_SHIFT-1))) - (iIdx)) << \ INDEX_COLOR_FIXED_SHIFT), \ (fDA) = (FLOAT)(((INT32)CI_GETALPHA(uPacked) - (iA)) << \ INDEX_COLOR_SHIFT)) #endif // #ifndef _SETUP_HPP_