📄 tsstate.c
字号:
*/
static DWORD dwSourceOrder[8][4] =
{
{ 0, 1, 2, 3 }, /* S1=Src0, S2=Src1, S3=Src2, S4=Src3 */
{ 1, 0, 2, 3 }, /* S1=Src1, S2=Src0, S3=Src2, S4=Src3 */
{ 0, 1, 3, 2 }, /* etc... */
{ 1, 0, 3, 2 },
{ 2, 3, 0, 1 },
{ 3, 2, 0, 1 },
{ 2, 3, 1, 0 },
{ 3, 2, 1, 0 }
};
/*
Source validation tables. Indicating which colour/alpha sources are valid for
each of the four HW colour/alpha sources (CS1-4/AS1-4). Each bit indicating if
a particular source (see colour/alpha source-codes above) are available from
the HW.
*/
static DWORD dwValidColourSource[] =
{
0x000F00EE, /* CS1 - only CURRENT, TEXTURE, FACTOR and ONE */
0x000CFFFF, /* CS2 - no ONE */
0x000F0077, /* CS3 - only DIFFUSE, CURRENT, TEXTURE and ONE */
0x000CFFFF /* CS4 - no ONE */
};
static DWORD dwValidAlphaSource[] =
{
0x00000FEE, /* AS1 - no DIFFUSE */
0x00000CFF, /* AS2 - no ONE */
0x00000F77, /* AS3 - no FACTOR */
0x00000CFF /* AS4 - no ONE */
};
/*
Table to get the appropriate offset into the colour op layer control word
tables for a given D3D texture op.
NB: The PVR_ARGTRANSFLAG flags are used to handle special cases
such as for the first non-bump stage or those with opaque textures
*/
static DWORD dwD3DColourOpOff[] =
{
/*
No PVR_ARGTRANSFLAG flags set
*/
0, /* 0 unused */
0, /* D3DTOP_DISABLE unused */
PVR_COLOUROP_SELECTARG1,
PVR_COLOUROP_SELECTARG2,
PVR_COLOUROP_MODULATE,
PVR_COLOUROP_MODULATE2X,
PVR_COLOUROP_MODULATE4X,
PVR_COLOUROP_ADD,
PVR_COLOUROP_ADDSIGNED,
PVR_COLOUROP_ADDSIGNED2X,
PVR_COLOUROP_SUBTRACT,
PVR_COLOUROP_ADDSMOOTH,
PVR_COLOUROP_BLENDDIFFUSEALPHA,
PVR_COLOUROP_BLENDTEXTUREALPHA,
PVR_COLOUROP_BLENDFACTORALPHA,
PVR_COLOUROP_BLENDTEXTUREALPHAPM,
PVR_COLOUROP_BLENDCURRENTALPHA,
PVR_COLOUROP_PREMODULATE,
PVR_COLOUROP_MODULATEALPHA_ADDCOLOR,
PVR_COLOUROP_MODULATECOLOR_ADDALPHA,
PVR_COLOUROP_MODULATEINVALPHA_ADDCOLOR,
PVR_COLOUROP_MODULATEINVCOLOR_ADDALPHA,
PVR_COLOUROP_BUMPENVMAP,
PVR_COLOUROP_BUMPENVMAPLUMINANCE,
PVR_COLOUROP_DOTPRODUCT3,
0, /* D3DTOP_MULTIPLYADD unused */
0 /* D3DTOP_LERP unused */
};
/*
Table to get the appropriate offset into the colour op layer control word
tables for a given D3D colour arg1 or arg2
NB: The PVR_ARGTRANSFLAG flags are used to handle special cases
such as for the first non-bump stage or those with opaque textures
*/
static DWORD dwD3DColourArgOff[] =
{
/*
No PVR_ARGTRANSFLAG flags set
*/
PVR_COLOURARG_DIFFUSE,
PVR_COLOURARG_CURRENT,
PVR_COLOURARG_TEXTURE,
PVR_COLOURARG_FACTOR,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
PVR_COLOURARG_INVDIFFUSE,
PVR_COLOURARG_INVCURRENT,
PVR_COLOURARG_INVTEXTURE,
PVR_COLOURARG_INVFACTOR,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
PVR_COLOURARG_DIFFUSEALPHA,
PVR_COLOURARG_CURRENTALPHA,
PVR_COLOURARG_TEXTUREALPHA,
PVR_COLOURARG_FACTORALPHA,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
PVR_COLOURARG_INVDIFFUSEALPHA,
PVR_COLOURARG_INVCURRENTALPHA,
PVR_COLOURARG_INVTEXTUREALPHA,
PVR_COLOURARG_INVFACTORALPHA,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*
Table to get the appropriate offset into the alpha op layer control word
tables for a given D3D texture op.
NB: The PVR_ARGTRANSFLAG flags are used to handle special cases
such as for the first non-bump stage or those with opaque textures
*/
static DWORD dwD3DAlphaOpOff[] =
{
/*
No PVR_ARGTRANSFLAG flags set
*/
0, /* 0 unused */
PVR_ALPHAOP_DISABLE,
PVR_ALPHAOP_SELECTARG1,
PVR_ALPHAOP_SELECTARG2,
PVR_ALPHAOP_MODULATE,
PVR_ALPHAOP_MODULATE2X,
PVR_ALPHAOP_MODULATE4X,
PVR_ALPHAOP_ADD,
PVR_ALPHAOP_ADDSIGNED,
PVR_ALPHAOP_ADDSIGNED2X,
PVR_ALPHAOP_SUBTRACT,
PVR_ALPHAOP_ADDSMOOTH,
PVR_ALPHAOP_BLENDDIFFUSEALPHA,
PVR_ALPHAOP_BLENDTEXTUREALPHA,
PVR_ALPHAOP_BLENDFACTORALPHA,
PVR_ALPHAOP_BLENDTEXTUREALPHAPM,
PVR_ALPHAOP_BLENDCURRENTALPHA,
PVR_ALPHAOP_PREMODULATE,
PVR_ALPHAOP_DISABLE, /* MODULATEALPHA_ADDCOLOR invalid */
PVR_ALPHAOP_DISABLE, /* MODULATECOLOR_ADDALPHA invalid */
PVR_ALPHAOP_DISABLE, /* MODULATEINVALPHA_ADDCOLOR invalid */
PVR_ALPHAOP_DISABLE, /* MODULATEINVCOLOR_ADDALPHA invalid */
PVR_ALPHAOP_DISABLE, /* BUMPENVMAP invalid */
PVR_ALPHAOP_DISABLE, /* BUMPENVMAPLUMINANCE invalid */
PVR_ALPHAOP_DOTPRODUCT3,
0, /* D3DTOP_MULTIPLYADD unused */
0 /* D3DTOP_LERP unused */
};
/*
Table to get the appropriate offset into the alpha op layer control word
tables for a given D3D alpha arg1 or arg2
NB: The PVR_ARGTRANSFLAG flags are used to handle special cases
such as for the first non-bump stage or those with opaque textures
*/
static DWORD dwD3DAlphaArgOff[] =
{
/*
No PVR_ARGTRANSFLAG flags set
*/
PVR_ALPHAARG_DIFFUSEALPHA,
PVR_ALPHAARG_CURRENTALPHA,
PVR_ALPHAARG_TEXTUREALPHA,
PVR_ALPHAARG_FACTORALPHA,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
PVR_ALPHAARG_INVDIFFUSEALPHA,
PVR_ALPHAARG_INVCURRENTALPHA,
PVR_ALPHAARG_INVTEXTUREALPHA,
PVR_ALPHAARG_INVFACTORALPHA,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*----------------------------------------------------------------------------
<function>
FUNCTION : AdjustForMaxMipLevel
PURPOSE : Tweaks map levels if MaxMipLevel state is enabled.
PARAMETERS : psLState - Layer state
RETURNS : None
</function>
------------------------------------------------------------------------------*/
void AdjustForMaxMipLevel(PLAYER_TSTATE psLState)
{
DWORD dwMaxLevel;
DWORD dwAddress = 0;
DWORD dwOffset;
DWORD dwUSize;
DWORD dwVSize;
DWORD dwMipFilterCtl;
LPD3DM_SURFACE psSurface;
PMBX1_TSPLAYER_STATE psTSPLState;
psSurface = psLState->psSurfData;
psTSPLState = &psLState->sTSPLState;
dwMaxLevel = psLState->dwMaxMipLevel;
dwMipFilterCtl = psLState->dwMipFilterCtl;
/* Check first if mip mapping is enabled, otherwise just use the top map */
if(!((dwMipFilterCtl & (~MBX1_TSPPL2_MIPCTLCLRMASK)) == MBX1_TSPPL2_MIPCTLNOTMIPMAP))
{
/* Clamp to number of supplied levels */
if(dwMaxLevel >= psSurface->sDescription.sTexture.psMapDetails->dwSuppliedLevels)
{
dwMaxLevel = psLState->dwMaxMipLevel = psSurface->sDescription.sTexture.psMapDetails->dwSuppliedLevels - 1;
}
/* Find Mip map level surface */
while(psSurface->sDescription.sTexture.dwMipMapLevel != dwMaxLevel)
psSurface = psSurface->sDescription.sTexture.psNextLevel;
/* Check that the current level size is greater than the hardware min */
while(psSurface->sDescription.sTexture.dwScaledWidth < 8 ||
psSurface->sDescription.sTexture.dwScaledHeight < 8)
{
psLState->dwMaxMipLevel = --dwMaxLevel;
psSurface = psLState->psSurfData;
/* Find Mip map level surface */
while(psSurface->sDescription.sTexture.dwMipMapLevel != dwMaxLevel)
psSurface = psSurface->sDescription.sTexture.psNextLevel;
}
}
/* Store this level as current top level */
psSurface->sDescription.sTexture.psMapDetails->psCurrentTopLevel = psSurface;
/* Get offset for this level */
dwOffset = psSurface->sDescription.sTexture.dwLevelOffset;
/* Get HW Sizes */
GetSizeInfo(psSurface->sDescription.sTexture.dwScaledWidth,
&dwUSize,
NULL,
NULL);
GetSizeInfo(psSurface->sDescription.sTexture.dwScaledHeight,
&dwVSize,
NULL,
NULL);
/* Update the HW texture address */
dwAddress = ((((psSurface->psMemInfo->uiDevAddr.uiAddr) + dwOffset) >>
MBX1_TSPPL2_TEXADDRALIGNSHIFT) <<
MBX1_TSPPL2_TEXADDRSHIFT) &
(~MBX1_TSPPL2_TEXADDRCLRMASK);
psTSPLState->dwLCtl2 = psTSPLState->dwLCtl2 & (MBX1_TSPPL2_TEXADDRCLRMASK);
psTSPLState->dwLCtl2 |= dwAddress;
/* Update the HW texture dimensions */
psTSPLState->dwLCtl1 &= MBX1_TSPPL1_TUSIZECLRMASK &
MBX1_TSPPL1_TVSIZECLRMASK;
psTSPLState->dwLCtl1 |= (dwUSize << MBX1_TSPPL1_TUSIZESHIFT) |
(dwVSize << MBX1_TSPPL1_TVSIZESHIFT);
D3DM_DPF((DPF_EXIT, "<-AdjustForMaxMipLevel"));
}
/*----------------------------------------------------------------------------
<function>
FUNCTION : SortOutDAdjust
PURPOSE : Sets up D-Adjust control bits (a.k.a. MipMap LOD Bias in D3D).
PARAMETERS : psContext - Current 3D rendering context
DAdjust - D3D D-adjust value
pdwLCtl2 - The TSP per-layer control-word 2 to setup
the HW d-adjust in
RETURNS : void
</function>
------------------------------------------------------------------------------*/
void SetupDAdjust(LPD3DM_CONTEXT psContext, NTV_TYPE DAdjust, PDWORD pdwLCtl2, IMG_BOOL bMipFilter)
{
DWORD dwLCtl2;
DWORD i;
D3DM_DPF((DPF_ENTRY, "->SetupDAdjust"));
dwLCtl2 = *pdwLCtl2;
if(!bMipFilter)
{
DAdjust += FL2NTV(0.5f);
}
/* Find correct LOD bias setting */
i = 0;
while((i < (sizeof(fD3DMipLODBiasTrans)/sizeof(float))) &&
(fD3DMipLODBiasTrans[i] < NTV2FL(DAdjust)))
{
i++;
}
/* Clamp */
if(i >= (sizeof(fD3DMipLODBiasTrans)/sizeof(float)))
{
i = (sizeof(fD3DMipLODBiasTrans)/sizeof(float)) - 1;
}
/* Set new D-Adjust bitpattern into TSP Control */
dwLCtl2 &= MBX1_TSPPL2_DADJUSTCLRMASK;
dwLCtl2 |= (i << MBX1_TSPPL2_DADJUSTSHIFT) & (~MBX1_TSPPL2_DADJUSTCLRMASK);
*pdwLCtl2 = dwLCtl2;
D3DM_DPF((DPF_EXIT, "<-SetupDAdjust"));
}
/*----------------------------------------------------------------------------
<function>
FUNCTION : UpdateHWTexAddrMode
PURPOSE : Updates the HW addressing mode to use for a given coordinate
NB: This routine assumes the given coordinate number is valid
(i.e. < 2)
PARAMETERS : psContext - Current D3D context
psLState - Layer state
dwCoord - The corrdinate to update the addressing mode for
(0 = U, 1 = V)
RETURNS :
</function>
------------------------------------------------------------------------------*/
void UpdateHWTexAddrMode(LPD3DM_CONTEXT psContext,
PLAYER_TSTATE psLState,
DWORD dwCoord)
{
D3DMTEXTUREADDRESS dwD3DAddrMode;
DWORD dwHWAddrMode;
DWORD dwHWCoordShift;
DWORD dwTSPLCtl1;
D3DM_DPF((DPF_ENTRY, "->UpdateHWTexAddrMode"));
/*
Determine the HW texture addressing mode corresponding to the
requested D3D addressing-mode
*/
dwD3DAddrMode = psLState->pdwD3DAddrMode[dwCoord];
switch (dwD3DAddrMode)
{
case D3DMTADDRESS_WRAP:
{
DWORD dwWrapFlags;
DWORD dwWrapFlag;
DWORD dwCoordSet;
/*
Use the HW 'WRAP' mode if coordinate-wrapping is enabled,
otherwise map to 'REPEAT'
*/
dwCoordSet = psLState->dwCoordSetNum;
dwWrapFlags = psContext->sTState.dwWrapFlags;
dwWrapFlag = 0x1UL << ((dwCoordSet * TSTATE_WRAPFLAGS_PERCOORDSET_LSHIFT) +
(dwCoord * TSTATE_WRAPFLAGS_PERCOORD_LSHIFT));
if (dwWrapFlags & dwWrapFlag)
{
dwHWAddrMode = MBX1_TSPPL1_TADDRMODEWRAP;
}
else
{
dwHWAddrMode = MBX1_TSPPL1_TADDRMODEREPEAT;
}
break;
}
case D3DMTADDRESS_MIRROR:
{
dwHWAddrMode = MBX1_TSPPL1_TADDRMODEFLIP;
break;
}
case D3DMTADDRESS_CLAMP:
{
dwHWAddrMode = MBX1_TSPPL1_TADDRMODECLAMP;
break;
}
default:
{
D3DM_DPF((DPF_WARN,"UpdateHWTexAddrMode: Unhandled mode %d. Defaulting to REPEAT", dwD3DAddrMode));
dwHWAddrMode = MBX1_TSPPL1_TADDRMODEREPEAT;
}
}
/*
Put the new addressing mode for this coordinate into the HW control
word
*/
dwHWCoordShift = MBX1_TSPPL1_TADDRMODECOORD0SHIFT -
(dwCoord * MBX1_TSPPL1_TADDRMODE_PERCOORD_RSHIFT);
dwTSPLCtl1 = psLState->sTSPLState.dwLCtl1;
dwTSPLCtl1 &= ~(MBX1_TSPPL1_TADDRMODEMASK << dwHWCoordShift);
dwTSPLCtl1 |= dwHWAddrMode << dwHWCoordShift;
psLState->sTSPLState.dwLCtl1 = dwTSPLCtl1;
D3DM_DPF((DPF_EXIT, "<-UpdateHWTexAddrMode"));
}
/*----------------------------------------------------------------------------
<function>
FUNCTION : PostProcessTSState
PURPOSE : Performs final state-update based upon the current texture-stage
states (called by ProcessTextureStageStates)
PARAMETERS : psContext - A 3D rendering context
RETURNS : None
</function>
------------------------------------------------------------------------------*/
void PostProcessTSState(LPD3DM_CONTEXT psContext)
{
PHWTACTL3DSTATE psTACtl3DState;
PHWSTATECTL psHWStateCtl;
DWORD dwPassesReq;
DWORD i;
#if defined (FIX_HW_PRN_530)
IMG_BOOL bTextureSuperSampleUsed = IMG_FALSE;
#endif
D3DM_DPF((DPF_ENTRY, "->PostProcessTSState"));
psTACtl3DState = &psContext->sHWState.sTACtl3DState;
psHWStateCtl = &psContext->sHWStateCtl;
/* Reset the flag indicating that texture-alpha is being used */
psContext->dwFlags &= ~D3DM_CONTEXT_SWFLAGS_USESTEXTUREALPHA;
/* Process all stages upto the first disabled stage */
dwPassesReq = 0;
for (i = 0; i < MBX1_MAXTEXTURE_LAYERS; i++)
{
PMBX1_TSPLAYER_STATE psHWLState;
PLAYER_TSTATE psLState;
LPD3DM_SURFACE psTexture;
DWORD dwArg1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -