📄 vgpcommon.c
字号:
dwVGPIFType = MBX1_VGPIFDEF_SREG_4D_ARGB;
dwVGPIFShift = MBX1_VGPIFDEF_SREG0_SHIFT + (psComponent->dwVGPIFReg * MBX1_VGPIFDEF_SREG_LSHIFT);
dwVGPIFDef &= ~(MBX1_VGPIFDEF_SREG0_CLRMASK << dwVGPIFShift);
dwVGPIFDef |= dwVGPIFType << dwVGPIFShift;
/*
Flag that a diffuse-colour component is present, and update the
overall vertex-size and next-component position
*/
dwFFComponents |= FFVTXCOMPONENT_TYPE_DIFFUSE;
dwVtxSize += 1 * sizeof(DWORD);
dwComponentOffset += 1 * sizeof(DWORD);
psComponent++;
}
/*
Specular-colour present?
*/
if(dwFVFCode & D3DMFVF_SPECULAR)
{
/*
Add a component for the specular-colour to the stream-format
component-list
*/
psComponent->dwVGPIFReg = FFVTXCOMPONENT_INPUTREG_SPECULAR;
psComponent->bFixedPoint = IMG_FALSE;
psComponent->dwSize = 1 * sizeof(DWORD);
psComponent->dwOffset = dwComponentOffset;
psComponent->bColour = IMG_TRUE;
/*
Read the colour as 4 colour-components into input-register 5
*/
dwVGPIFType = MBX1_VGPIFDEF_SREG_4D_ARGB;
dwVGPIFShift = MBX1_VGPIFDEF_SREG0_SHIFT + (psComponent->dwVGPIFReg * MBX1_VGPIFDEF_SREG_LSHIFT);
dwVGPIFDef &= ~(MBX1_VGPIFDEF_SREG0_CLRMASK << dwVGPIFShift);
dwVGPIFDef |= dwVGPIFType << dwVGPIFShift;
/*
Flag that a specular-colour component is present, and update
the overall vertex-size and next-component position
*/
dwFFComponents |= FFVTXCOMPONENT_TYPE_SPECULAR;
dwVtxSize += 1 * sizeof(DWORD);
dwComponentOffset += 1 * sizeof(DWORD);
psComponent++;
}
/*
Determine the texture-coordinate sets prsent
NB: We only handle two coordinate sets at present. Any additional
sets present are ignored and subsequently skipped during vertex
copying
*/
dwCoordSetCount = (dwFVFCode & D3DMFVF_TEXCOUNT_MASK) >> D3DMFVF_TEXCOUNT_SHIFT;
if (dwCoordSetCount > MBX1_MAXTEXTURE_LAYERS)
{
//DPF("VSIFDefSetupForFVF: %d tex-coord sets present. Only using %d", dwCoordSetCount, MBX1_MAXTEXTURE_LAYERS);
dwCoordSetCount = MBX1_MAXTEXTURE_LAYERS;
}
for (i = 0; i < dwCoordSetCount; i++)
{
DWORD dwFVFTexCoordSetSize;
/*
How many coordinates present in this coordinate set?
*/
dwFVFTexCoordSetSize = (dwFVFCode >> (i*2 + 16)) & 0x3;
switch (dwFVFTexCoordSetSize)
{
case D3DMFVF_TEXCOORDCOUNT1:
{
/*
A 1-D coordinate-set. Read as 1-float into the register
*/
dwComponentSize = 1 * sizeof(IMG_FLOAT);
dwVGPIFType = MBX1_VGPIFDEF_SREG_1D_FLOAT;
break;
}
case D3DMFVF_TEXCOORDCOUNT2:
{
/*
A 2-D coordinate-set. Read as 2-floats into the register
*/
dwComponentSize = 2 * sizeof(IMG_FLOAT);
dwVGPIFType = MBX1_VGPIFDEF_SREG_2D_FLOAT;
break;
}
case D3DMFVF_TEXCOORDCOUNT3:
{
/*
A 3-D coordinate-set. Read as 3-floats into the register
*/
dwComponentSize = 3 * sizeof(IMG_FLOAT);
dwVGPIFType = MBX1_VGPIFDEF_SREG_3D_FLOAT;
break;
}
default:
{
//DPF("VSIFDefSetupForFVF: Unhandled FVF tex-coord set size %d", dwFVFTexCoordSetSize);
return FALSE;
}
}
if (dwComponentSize)
{
/*
Add a component for the coordinate-set to the stream-format
component-list
*/
psComponent->bFixedPoint = (((dwFVFCode >>(24+(i*2))) & 0x3) == D3DMFVF_TEXCOORDFORMAT_FIXED);
psComponent->dwSize = dwComponentSize;
psComponent->dwOffset = dwComponentOffset;
dwComponentOffset += dwComponentSize;
psComponent->bColour = IMG_FALSE;
/*
Flag that this texture coordinate-set is present, and update
the overall vertex-size
*/
dwFFComponents |= FFVTXCOMPONENT_TYPE_TEX0 << i;
dwVtxSize += dwComponentSize;
/*
Update the VGP input format
*/
psComponent->dwVGPIFReg = FFVTXCOMPONENT_INPUTREG_TEX0 + i;
dwVGPIFShift = MBX1_VGPIFDEF_SREG0_SHIFT +
(psComponent->dwVGPIFReg * MBX1_VGPIFDEF_SREG_LSHIFT);
dwVGPIFDef &= ~(MBX1_VGPIFDEF_SREG0_CLRMASK << dwVGPIFShift);
dwVGPIFDef |= dwVGPIFType << dwVGPIFShift;
psComponent++;
}
}
/*
Update the vertex-shader input-format data
*/
psVSIFDef->dwFFComponents = dwFFComponents;
psVSIFDef->dwVGPIFDef = dwVGPIFDef;
psVSIFDef->dwNumComponents = psComponent - psVSIFDef->psComponents;
//DPFL3("VSIFDefSetupForFVF: Num components %d, components used 0x%lX (%hs)", psStreamFormat->dwNumComponents, dwFFComponents, DBG_DECODEFFCOMPONENTS(dwFFComponents));
PostProcessComponents(psVSIFDef);
return TRUE;
}
/*****************************************************************************
FUNCTION : VGPTNLGenerateFogSection
PURPOSE : Compiles Fog section according to current software state
PARAMETERS : psContext - The current 3D rendering context
dwNum - Constant to be updated
RETURNS : void
****************************************************************************/
VOID VGPTNLGenerateFogSection(LPD3DM_CONTEXT psContext,
PDWORD pdwSectionSize,
PHWVGPINST psSection)
{
PTRANSIENT_STATE psTState;
PSWTNLSTATE psSWTNLState;
DWORD dwInst = 0;
psTState = &psContext->sTState;
psSWTNLState = &psTState->sSWTNLState;
if(psContext->sTState.dwD3DVertexFogMode != D3DMFOG_NONE)
{
/* Calculate Fog value */
if(psContext->sTState.dwRSFlags & TSTATE_RSFLAGS_RANGE_FOG)
{
/* SquareRt(psVertex->sEye * psVertex->sEye) to r9.x */
VGPINSTG(psSection[dwInst].field, DP3, DEST(R9, MASKX), SRC_RN(VGPTNL_RVIEWSPACEPOS), SRC_RN(VGPTNL_RVIEWSPACEPOS), 0, 0);
dwInst++;
VGPINSTG(psSection[dwInst].field, RSQRT, DEST(R9, MASKY), SRC_SWZRN(9, SWZ_XXXX), 0, 0, 0);
dwInst++;
VGPINSTG(psSection[dwInst].field, RCP, DEST(R9, MASKX), SRC_SWZRN(9, SWZ_YYYY), 0, 0, 0);
dwInst++;
}
else
{
/* (D = (psVertex->sEye.z < D3DM_Zero) ? -(psVertex->sEye.z) : psVertex->sEye.z) to r9.x */
VGPINSTG(psSection[dwInst].field, MAX, DEST(R9, MASKX), SRC_SWZRN(VGPTNL_RVIEWSPACEPOS, SWZ_ZZZZ), SRC_NEGSWZRN(VGPTNL_RVIEWSPACEPOS, SWZ_ZZZZ), 0, 0);
dwInst++;
}
switch (psContext->sTState.dwD3DVertexFogMode)
{
case D3DMFOG_EXP:
{
/* (D * -density) to r10.w */
VGPINSTG(psSection[dwInst].field, MUL, DEST(R10, MASKW), SRC_SWZRN(9, SWZ_XXXX), SRC_NEGSWZCN(CONST_FOG_PARAMS, SWZ_XXXX), 0, 0);
dwInst++;
/* Move D3DM_E to r10.y */
VGPINSTG(psSection[dwInst].field, MOV, DEST(R10, MASK_XY), SRC_SWZCN(CONST_FOG_PARAMS, SWZ_YYYY), 0, 0, 0);
dwInst++;
/* Pow(D3DM_E, -(D * Density)) to R10.z */
VGPINSTG(psSection[dwInst].field, LIT, DEST(R10, MASKZ), SRC_RN(10), 0, 0, 0);
dwInst++;
/* move R10.z to Output.specular.w */
VGPINSTG(psSection[dwInst].field, MOV, DEST(OOFF, MASKW), SRC_SWZRN(10, SWZ_ZZZZ), 0, 0, 0);
dwInst++;
break;
}
case D3DMFOG_EXP2:
{
/* (Density * Distance) to r9.z */
VGPINSTG(psSection[dwInst].field, MUL, DEST(R9, MASKZ), SRC_SWZRN(9, SWZ_XXXX), SRC_SWZCN(CONST_FOG_PARAMS, SWZ_XXXX), 0, 0);
dwInst++;
/* (Density * Distance)^2 to r10.w */
VGPINSTG(psSection[dwInst].field, MUL, DEST(R10, MASKW), SRC_SWZRN(9, SWZ_ZZZZ), SRC_NEGSWZRN(9, SWZ_ZZZZ), 0, 0);
dwInst++;
/* Move D3DM_E to r10.y */
VGPINSTG(psSection[dwInst].field, MOV, DEST(R10, MASK_XY), SRC_SWZCN(CONST_FOG_PARAMS, SWZ_YYYY), 0, 0, 0);
dwInst++;
/* Pow(D3DM_E, -(D * Density)^2) o R10.z */
VGPINSTG(psSection[dwInst].field, LIT, DEST(R10, MASKZ), SRC_RN(10), 0, 0, 0);
dwInst++;
/* move R10.z to Output.specular.w */
VGPINSTG(psSection[dwInst].field, MOV, DEST(OOFF, MASKW), SRC_SWZRN(10, SWZ_ZZZZ), 0, 0, 0);
dwInst++;
break;
}
case D3DMFOG_LINEAR:
{
/* (end - distance) to r9.y */
VGPINSTG(psSection[dwInst].field, ADD, DEST(R9, MASKY), SRC_SWZCN(CONST_FOG_PARAMS, SWZ_ZZZZ), SRC_NEGSWZRN(9, SWZ_XXXX), 0, 0);
dwInst++;
/* (end - distance) * (1 / (end - start)) to Output.specular.w */
VGPINSTG(psSection[dwInst].field, MUL, DEST(OOFF, MASKW), SRC_SWZRN(9, SWZ_YYYY), SRC_SWZCN(CONST_FOG_PARAMS, SWZ_WWWW), 0, 0);
dwInst++;
break;
}
}
}
else
{
/* Just pass through specular alpha */
VGPINSTG(psSection[dwInst].field, MOV, DEST(OOFF, MASKW), SRC_SWZVN(VSPECULAR, SWZ_WWWW), 0, 0, 0);
dwInst++;
}
*pdwSectionSize = dwInst;
}
/*****************************************************************************
FUNCTION : VGPTNLGenerateTextureCoordSection
PURPOSE : Compiles Tex gen section according to current software state
PARAMETERS : psContext - The current 3D rendering context
dwNum - Constant to be updated
RETURNS : void
****************************************************************************/
VOID VGPTNLGenerateTextureCoordSection(LPD3DM_CONTEXT psContext,
PDWORD pdwSectionSize,
PHWVGPINST psSection)
{
PTRANSIENT_STATE psTState;
PSWTNLSTATE psSWTNLState;
DWORD dwInst = 0;
DWORD dwSrcReg = 0xFFFFFFFF;
DWORD dwDoneGen = 0;
DWORD dwTcCount;
DWORD i;
IMG_BOOL b3DCoordsUsed = (psContext->sTState.sSWTNLState.dwPVDestTexLayerCoordCount[0] == 3) ||
(psContext->sTState.sSWTNLState.dwPVDestTexLayerCoordCount[1] == 3);
psTState = &psContext->sTState;
psSWTNLState = &psTState->sSWTNLState;
dwTcCount = psSWTNLState->dwTNLFlags & PVRD3DTNL_FLAGS_TC_COUNT_MASK;
dwTcCount >>= PVRD3DTNL_FLAGS_TC_COUNT_SHIFT;
/* Initialize the address register to the base of the texture matrices. */
VGPINSTG(psSection[dwInst].field, AMV, DEST_A0X, SRC_CN(CONST_TEXMAT_BASE), 0, 0, 0);
dwInst++;
for (i = 0; i < MBX1_MAXTEXTURE_LAYERS; i++)
{
PLAYER_TSTATE psLState;
DWORD dwXFlags;
DWORD dwTexGenMode;
psLState = &psTState->sLState[i];
dwXFlags = psLState->dwD3DTexTransFlags & ~D3DMTTFF_PROJECTED;
dwTexGenMode = psLState->dwCoordAutoGenMode;
switch (dwTexGenMode)
{
case D3DMTSS_TCI_CAMERASPACEPOSITION:
{
if (!(dwDoneGen & D3DMTSS_TCI_CAMERASPACEPOSITION))
{
VGPINSTG(psSection[dwInst].field, MOV, DEST(VGPTNL_OUT_RVIEWSPACEPOS, MASKW), SRC_CN(CONST_ONE), 0, 0, 0);
dwInst++;
dwDoneGen |= D3DMTSS_TCI_CAMERASPACEPOSITION;
}
dwSrcReg = SRC_RN(VGPTNL_RVIEWSPACEPOS);
break;
}
case D3DMTSS_TCI_CAMERASPACENORMAL:
{
if (!(dwDoneGen & D3DMTSS_TCI_CAMERASPACENORMAL))
{
VGPINSTG(psSection[dwInst].field, MOV, DEST(VGPTNL_OUT_RNORMAL, MASKW), SRC_CN(CONST_ONE), 0, 0, 0);
dwInst++;
dwDoneGen |= D3DMTSS_TCI_CAMERASPACENORMAL;
}
dwSrcReg = SRC_RN(VGPTNL_RNORMAL);
break;
}
case D3DMTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
{
if (!(dwDoneGen & D3DMTSS_TCI_CAMERASPACEREFLECTIONVECTOR))
{
/* dp3 r9.x, rL, rN */
VGPINSTG(psSection[dwInst].field, DP3, DEST(R9, MASKX), SRC_RN(VGPTNL_RLOCALVIEWERPOS), SRC_RN(VGPTNL_RNORMAL), 0, 0);
dwInst++;
/* add r9.x, r9.x, r9.x */
VGPINSTG(psSection[dwInst].field, ADD, DEST(R9, MASKX), SRC_SWZRN(9, SWZ_XXXX), SRC_SWZRN(9, SWZ_XXXX), 0, 0);
dwInst++;
/* mul r9.xyz, r9.x, rN */
VGPINSTG(psSection[dwInst].field, MUL, DEST(R9, MASK_XYZ), SRC_SWZRN(9, SWZ_XXXX), SRC_RN(VGPTNL_RNORMAL), 0, 0);
dwInst++;
/* add r4.xyz, r9, -rL */
VGPINSTG(psSection[dwInst].field, ADD, DEST(R4, MASK_XYZ), SRC_RN(9), SRC_NEGRN(8), 0, 0);
dwInst++;
/* mov r4.w, 1 */
VGPINSTG(psSection[dwInst].field, MOV, DEST(R4, MASKW), SRC_CN(CONST_ONE), 0, 0, 0);
dwInst++;
dwDoneGen |= D3DMTSS_TCI_CAMERASPACEREFLECTIONVECTOR;
}
dwSrcReg = SRC_RN(4);
break;
}
case D3DMTSS_TCI_PASSTHRU:
{
if (i >= dwTcCount)
{
continue;
}
dwSrcReg = SRC_VN(VTEX0 + i);
break;
}
}
if(dwXFlags != D3DMTTFF_DISABLE)
{
if(psContext->dwFlags & D3DM_CONTEXT_SWFLAGS_PROCVERT_MODE && b3DCoordsUsed)
{
DWORD dwCoord1Dst, dwCoord2Dst, dwCoord3Dst;
/*
If were in process vertices mode we can output 3d texture co-ords.
It takes a bit of fudging though, We have to assign as follows
TEX0.x = L1-Coord 1
TEX0.y = L1-Coord 2
TEX1.x = L1-Coord 3
TEXKILL0.x = L1-Coord 1
TEXKILL0.y = L1-Coord 1
TEXKILL0.z = L1-Coord 1
This is because Process vertices outputs only 2 floats from each Tex coord register.
We cannot support clipstatus whilst doing this without multiple passes
*/
if(i == 0)
{
/* Layer 0 */
dwCoord1Dst = DEST(OTEX0, MASKX);
dwCoord2Dst = DEST(OTEX0, MASKY);
dwCoord3Dst = DEST(OTEX1, MASKX);
}
else
{
/* Layer 1 */
dwCoord1Dst = DEST(OCLIP0, MASKX);
dwCoord2Dst = DEST(OCLIP0, MASKY);
dwCoord3Dst = DEST(OCLIP0, MASKZ);
}
VGPINSTG(psSection[dwInst].field, DP4, dwCoord1Dst, dwSrcReg, SRC_CN((i * 4) + 0), 0, 1);
dwInst++;
VGPINSTG(psSection[dwInst].field, DP4, dwCoord2Dst, dwSrcReg, SRC_CN((i * 4) + 1), 0, 1);
dwInst++;
VGPINSTG(psSection[dwInst].field, DP4, dwCoord3Dst, dwSrcReg, SRC_CN((i * 4) + 2), 0, 1);
dwInst++;
//VGPINSTG(psSection[dwInst].field, DP4, DEST(OTEX0 + i, MASKW), dwSrcReg, SRC_CN((i * 4) + 3), 0, 1);
//dwInst++;
}
else
{
VGPINSTG(psSection[dwInst].field, DP4, DEST(OTEX0 + i, MASKX), dwSrcReg, SRC_CN((i * 4) + 0), 0, 1);
dwInst++;
VGPINSTG(psSection[dwInst].field, DP4, DEST(OTEX0 + i, MASKY), dwSrcReg, SRC_CN((i * 4) + 1), 0, 1);
dwInst++;
//VGPINSTG(psSection[dwInst].field, DP4, DEST(OTEX0 + i, MASKZ), dwSrcReg, SRC_CN((i * 4) + 2), 0, 1);
//dwInst++;
//VGPINSTG(psSection[dwInst].field, DP4, DEST(OTEX0 + i, MASKW), dwSrcReg, SRC_CN((i * 4) + 3), 0, 1);
//dwInst++;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -