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.
|
|
//----------------------------------------------------------------------------
//
// primproc.cpp
//
// Miscellaneous PrimProcessor methods.
//
// Copyright (C) Microsoft Corporation, 1997.
//
//----------------------------------------------------------------------------
#include "pch.cpp"
#pragma hdrstop
DBG_DECLARE_FILE();
//----------------------------------------------------------------------------
//
// PrimProcessor::BeginPrimSet
//
// Marks the start of a set of primitives that have the same vertex type.
// Computes attributes used from the current state and the vertex type.
//
//----------------------------------------------------------------------------
void PrimProcessor::BeginPrimSet(D3DPRIMITIVETYPE PrimType, RAST_VERTEX_TYPE VertType) { // If state hasn't changed and the primitive and vertex types match the
// ones we're already set up for there's no work to do.
if ((m_uPpFlags & PPF_STATE_CHANGED) == 0 && VertType == m_VertType && PrimType == m_PrimType) { return; }
m_StpCtx.uFlags &= ~PRIMSF_ALL;
if (m_StpCtx.pCtx->pdwRenderState[D3DRENDERSTATE_ZENABLE] || m_StpCtx.pCtx->pdwRenderState[D3DRENDERSTATE_ZWRITEENABLE] || m_StpCtx.pCtx->pdwRenderState[D3DRENDERSTATE_STENCILENABLE]) { m_StpCtx.uFlags |= PRIMSF_Z_USED; }
if (m_StpCtx.pCtx->BeadSet == D3DIBS_RAMP) { // Index is unused during copy mode texturing.
if (m_StpCtx.pCtx->pdwRenderState [D3DRENDERSTATE_TEXTUREMAPBLEND] != D3DTBLEND_COPY || m_StpCtx.pCtx->cActTex == 0) { m_StpCtx.uFlags |= PRIMSF_DIDX_USED; } } else { // ATTENTION - Don't set these for copy mode texture? Is
// copy mode texture meaningful in RGB?
m_StpCtx.uFlags |= PRIMSF_DIFF_USED; if (m_StpCtx.pCtx->pdwRenderState[D3DRENDERSTATE_SPECULARENABLE]) { m_StpCtx.uFlags |= PRIMSF_SPEC_USED; } }
if (m_StpCtx.pCtx->pdwRenderState[D3DRENDERSTATE_SHADEMODE] == D3DSHADE_FLAT) { m_StpCtx.uFlags |= PRIMSF_FLAT_SHADED; }
if (m_StpCtx.pCtx->cActTex > 0) { m_StpCtx.uFlags |= PRIMSF_TEX1_USED; DDASSERT((m_StpCtx.pCtx->pTexture[0]->uFlags & D3DI_SPANTEX_NON_POWER_OF_2) == 0);
if (m_StpCtx.pCtx->cActTex > 1) { m_StpCtx.uFlags |= PRIMSF_TEX2_USED; DDASSERT((m_StpCtx.pCtx->pTexture[1]->uFlags & D3DI_SPANTEX_NON_POWER_OF_2) == 0); } }
if ((m_StpCtx.uFlags & PRIMSF_TEX_USED) && m_StpCtx.pCtx->pdwRenderState[D3DRENDERSTATE_TEXTUREPERSPECTIVE]) { m_StpCtx.uFlags |= PRIMSF_PERSP_USED; }
// Currently only tex1 can be mipmapped.
if (((m_StpCtx.uFlags & PRIMSF_TEX1_USED) && (PrimType == D3DPT_TRIANGLELIST || PrimType == D3DPT_TRIANGLESTRIP || PrimType == D3DPT_TRIANGLEFAN) && (m_StpCtx.pCtx->pdwRenderState[D3DRENDERSTATE_FILLMODE] == D3DFILL_SOLID)) &&
(((m_StpCtx.pCtx->pTexture[0]->cLOD >= 1) && (m_StpCtx.pCtx->pTexture[0]->uMipFilter != D3DTFP_NONE)) || // need LOD if we need to dynamically switch between different min
// and mag filters
(m_StpCtx.pCtx->pTexture[0]->uMinFilter != m_StpCtx.pCtx->pTexture[0]->uMagFilter))) { m_StpCtx.uFlags |= PRIMSF_LOD_USED; }
// select between min and mag filters for TEX2
if (((m_StpCtx.uFlags & PRIMSF_TEX2_USED) && (PrimType == D3DPT_TRIANGLELIST || PrimType == D3DPT_TRIANGLESTRIP || PrimType == D3DPT_TRIANGLEFAN) && (m_StpCtx.pCtx->pdwRenderState[D3DRENDERSTATE_FILLMODE] == D3DFILL_SOLID)) &&
(((m_StpCtx.pCtx->pTexture[1]->cLOD >= 1) && (m_StpCtx.pCtx->pTexture[1]->uMipFilter != D3DTFP_NONE)) || // need LOD if we need to dynamically switch between different min
// and mag filters
(m_StpCtx.pCtx->pTexture[1]->uMinFilter != m_StpCtx.pCtx->pTexture[1]->uMagFilter))) { m_StpCtx.uFlags |= PRIMSF_LOD_USED; }
if (m_StpCtx.pCtx->pdwRenderState[D3DRENDERSTATE_FOGENABLE]) { // Note, if PWL_FOG is ever brought back to life, enabling
// PRIMSF_GLOBAL_FOG_USED with no Z buffer will not trivially work
// if (m_StpCtx.uFlags & PRIMSF_Z_USED)
{ switch (m_StpCtx.pCtx->pdwRenderState[D3DRENDERSTATE_FOGTABLEMODE]) { case D3DFOG_EXP: case D3DFOG_EXP2: case D3DFOG_LINEAR: m_StpCtx.uFlags |= PRIMSF_GLOBAL_FOG_USED; #ifndef PWL_FOG
// The span routines don't support table fog directly.
// Instead table fog is computed per vertex and used to
// set up local fog.
m_StpCtx.uFlags |= PRIMSF_LOCAL_FOG_USED; #endif
break; default: m_StpCtx.uFlags |= PRIMSF_LOCAL_FOG_USED; break; } } }
PFN_ADDATTRS *ppfnAddAttrsTable; PFN_ADDSCALEDATTRS *ppfnAddScaledAttrsTable; PFN_FILLSPANATTRS *ppfnFillSpanAttrsTable;
if (m_StpCtx.pCtx->BeadSet == D3DIBS_RAMP) { // Ramp does not support multitexture.
RSASSERT((m_StpCtx.uFlags & PRIMSF_TEX2_USED) == 0);
RSASSERT((PRIMSF_TEX1_USED | PRIMSF_DIDX_USED) == 0x14);
// Derive a function table index from bits 2 and 4 of usage
// information.
// An alternative method would be to use bits 0-4 and have the
// ramp information in the top 16 entries, but splitting the
// ramp and RGB tables is cleaner and decouples the table sizes.
// Decoupling is useful since the ramp possibilities are much
// more limited so its table can be smaller.
m_iAttrFnIdx = ((m_StpCtx.uFlags & PRIMSF_TEX1_USED) >> 2) | ((m_StpCtx.uFlags & PRIMSF_DIDX_USED) >> 3);
ppfnAddAttrsTable = g_pfnRampAddFloatAttrsTable; ppfnAddScaledAttrsTable = g_pfnRampAddScaledFloatAttrsTable; ppfnFillSpanAttrsTable = g_pfnRampFillSpanFloatAttrsTable; } else { RSASSERT((PRIMSF_DIFF_USED | PRIMSF_SPEC_USED | PRIMSF_TEX1_USED | PRIMSF_TEX2_USED) == 0xf);
// Derive a function table index from the lower four bits of
// usage information. The lower bits are deliberately chosen
// to represent the more performance-sensitive cases while
// the upper bits generally represent cases handled by generic
// code.
//
// Even restricted to only four bits the index contains unimportant
// and unreachable cases, such as specular without diffuse or
// tex2 without tex1. Tables indexed must account for this.
m_iAttrFnIdx = m_StpCtx.uFlags & (PRIMSF_DIFF_USED | PRIMSF_SPEC_USED | PRIMSF_TEX1_USED | PRIMSF_TEX2_USED);
ppfnAddAttrsTable = g_pfnAddFloatAttrsTable; ppfnAddScaledAttrsTable = g_pfnAddScaledFloatAttrsTable; ppfnFillSpanAttrsTable = g_pfnFillSpanFloatAttrsTable; }
//
// These functions only depend on the index and so can be set here.
// Other functions depend on per-triangle information and are set
// later.
//
if ((m_StpCtx.uFlags & PRIMSF_SLOW_USED) != PRIMSF_Z_USED) { // If any slow attrs are on or Z is off use the general functions.
m_StpCtx.pfnAddScaledAttrs = AddScaledFloatAttrs_Any_Either; #ifndef STEP_FIXED
m_StpCtx.pfnAddAttrs = AddFloatAttrs_Any; m_StpCtx.pfnFillSpanAttrs = FillSpanFloatAttrs_Any_Either; #endif
} else { m_StpCtx.pfnAddScaledAttrs = ppfnAddScaledAttrsTable[m_iAttrFnIdx]; #ifndef STEP_FIXED
m_StpCtx.pfnAddAttrs = ppfnAddAttrsTable[m_iAttrFnIdx]; m_StpCtx.pfnFillSpanAttrs = ppfnFillSpanAttrsTable[m_iAttrFnIdx]; #endif
}
// Attribute beads can be set here.
PFN_SETUPTRIATTR *ppfnSlot;
ppfnSlot = &m_StpCtx.pfnTriSetupFirstAttr; if (m_StpCtx.uFlags & PRIMSF_Z_USED) { if (m_StpCtx.pCtx->iZBitCount == 16) { *ppfnSlot = TriSetup_Z16; } else { *ppfnSlot = TriSetup_Z32; } ppfnSlot = &m_StpCtx.pfnTriSetupZEnd; } if (m_StpCtx.uFlags & PRIMSF_TEX1_USED) { if (m_StpCtx.uFlags & PRIMSF_PERSP_USED) { *ppfnSlot = TriSetup_Persp_Tex1; } else { *ppfnSlot = TriSetup_Affine_Tex1; } ppfnSlot = &m_StpCtx.pfnTriSetupTex1End; } if (m_StpCtx.uFlags & PRIMSF_TEX2_USED) { // Code assumes that tex1 is enabled if tex2 is enabled.
RSASSERT(m_StpCtx.uFlags & PRIMSF_TEX1_USED);
if (m_StpCtx.uFlags & PRIMSF_PERSP_USED) { *ppfnSlot = TriSetup_Persp_Tex2; } else { *ppfnSlot = TriSetup_Affine_Tex2; } ppfnSlot = &m_StpCtx.pfnTriSetupTex2End; } if (m_StpCtx.uFlags & PRIMSF_DIFF_USED) { if (m_StpCtx.uFlags & PRIMSF_FLAT_SHADED) { *ppfnSlot = TriSetup_DiffFlat; } else { *ppfnSlot = TriSetup_Diff; } ppfnSlot = &m_StpCtx.pfnTriSetupDiffEnd; } else if (m_StpCtx.uFlags & PRIMSF_DIDX_USED) { if (m_StpCtx.uFlags & PRIMSF_FLAT_SHADED) { *ppfnSlot = TriSetup_DIdxFlat; } else { *ppfnSlot = TriSetup_DIdx; } ppfnSlot = &m_StpCtx.pfnTriSetupDiffEnd; } if (m_StpCtx.uFlags & PRIMSF_SPEC_USED) { if (m_StpCtx.uFlags & PRIMSF_FLAT_SHADED) { *ppfnSlot = TriSetup_SpecFlat; } else { *ppfnSlot = TriSetup_Spec; } ppfnSlot = &m_StpCtx.pfnTriSetupSpecEnd; } if (m_StpCtx.uFlags & PRIMSF_LOCAL_FOG_USED) { *ppfnSlot = TriSetup_Fog; ppfnSlot = &m_StpCtx.pfnTriSetupFogEnd; } *ppfnSlot = TriSetup_End;
// Remember the primitive and vertex type and clear the state change bit.
m_PrimType = PrimType; m_VertType = VertType; m_uPpFlags &= ~PPF_STATE_CHANGED; }
|