📄 vertex.c
字号:
/*
** Check each of the clipping planes by examining the ui32AllClipCodes
** mask. Note that no bits will be set in ui32AllClipCodes for clip
** planes that are not enabled.
*/
if (ui32AllClipCodes)
{
/* Now clip against the clipping planes */
ppsOutVert = &psContext->sTState.sSWTNLState.apsOutputVert[0][0];
psPlane = &asFrustumClipPlanes[0];
do {
if (ui32AllClipCodes & (D3DM_CLIPFLAG_NEAR >> D3DM_CLIPFLAG_SHIFT))
{
ui32NumOut = FastclipToPlane(psContext, ppsInVert, ui32NumIn, ppsOutVert, psPlane);
if (ui32NumOut < 3)
{
return 0;
}
ppsInVert = ppsOutVert;
ppsOutVert += D3DM_MAX_CLIP_VERTICES;
}
ui32AllClipCodes >>= 1;
psPlane++;
ui32NumIn = ui32NumOut;
} while (ui32AllClipCodes);
/*
** Calculate final screen coordinates. Next phase of polygon
** processing assumes that window coordinates are already computed.
*/
ppsOutVert = ppsInVert;
psContext->sTState.sSWTNLState.ppsOutputArray = ppsOutVert;
for (i = 0; i < ui32NumOut; i++)
{
NTV_TYPE x, y, z, invw;
psTemp = *ppsOutVert++;
invw = psTemp->sClip.w ? DivPR_Y(D3DM_One, psTemp->sClip.w) : D3DM_Zero;
x = psTemp->sClip.x;
y = psTemp->sClip.y;
z = psTemp->sClip.z;
/* Rotate if this is a presentable rendertarget */
if(psContext->dwRotationAngle == 0 ||
psContext->dwRotationAngle == 180 ||
psContext->psCurrentRenderTarget->eSurfaceType == D3DMRTYPE_SURFACE ||
psContext->psCurrentRenderTarget->eSurfaceType == D3DMRTYPE_TEXTURE)
{
wx = Add(Mul(Mul(x, psVPTransform->XScale), PR_UNSHIFT(invw)), psVPTransform->XOffset);
wy = Add(Mul(Mul(y, psVPTransform->YScale), PR_UNSHIFT(invw)), psVPTransform->YOffset);
}
else
{
wx = Add(Mul(Mul(y, psVPTransform->XScale), PR_UNSHIFT(invw)), psVPTransform->XOffset);
wy = Add(Mul(Mul(x, psVPTransform->YScale), PR_UNSHIFT(invw)), psVPTransform->YOffset);
}
psTemp->sWindow.x = wx;
psTemp->sWindow.y = wy;
psTemp->sWindow.z = Add(MulPR_XY(MulPR_X(z, psVPTransform->ZScale), invw), PR_SHIFT(psVPTransform->ZOffset));
psTemp->sWindow.w = invw;
}
}
PROFILE_STOP_FUNC(DO_POLYGON_CLIP);
return ui32NumOut;
}
/***********************************************************************************
Function Name : OutputVertices
Returns :
Description : Writes transformed and lit vertices to the slave port
************************************************************************************/
IMG_VOID OutputVertices(LPD3DM_CONTEXT psContext, PVR_NATIVE_VERTEX **ppsVertex, IMG_UINT32 ui32VertexCount)
{
IMG_UINT32 i, ui32ISPTSPCtl = psContext->sHWState.sTACtl3DState.dwISPTSPCtl;
IMG_UINT32 ui32RequiredDataSize, ui32BytesObtained, ui32DWWritten = 0;
IMG_UINT32 ui32VertexSizeDW;
PVR_NATIVE_VERTEX *psVertex;
PVR_COLORVALUE *psFlatDiffuse = psContext->sTState.sSWTNLState.psCurrentFlatShadeDiffuse;
PVR_COLORVALUE *psFlatSpecular = psContext->sTState.sSWTNLState.psCurrentFlatShadeSpecular;
PPVRSRV_DEV_SLAVE_PORT psSlavePort = &psContext->sHWInfo.sDeviceSpecific.sMBX.sTASlavePort;
IMG_VOID *pvLinPortAddr = psSlavePort->pvData;
PVRSRV_DEV_DATA *psDevData = &psContext->sDevData;
#if defined (PDUMP)
NTV_TYPE ntvZero = D3DM_Zero;
IMG_UINT32 ui32Colour;
#endif
PROFILE_START_FUNC(OUTPUT_VERTICES);
if (ui32VertexCount == 0)
{
/* no vertices to write */
PROFILE_STOP_FUNC(OUTPUT_VERTICES);
return;
}
/* Calc vertex size */
ui32VertexSizeDW = CalcNativeVertexOutputSizeDW(psContext, *ppsVertex);
ui32RequiredDataSize = ui32VertexSizeDW * ui32VertexCount;
/* Ensure we have space required */
while(psContext->dwAllocatedFifoSpaceDWORDS < ui32RequiredDataSize)
{
PVRSRVAcquire3DFifoSpace (psDevData->psDevInfoUM,
&psContext->sHWInfo,
&ui32BytesObtained);
psContext->dwAllocatedFifoSpaceDWORDS = (ui32BytesObtained >> 2);
}
while(ui32VertexCount--)
{
psVertex = *ppsVertex++;
#if defined (FIX_HW_PRN_725_MBXLITE)
if((ui32ISPTSPCtl & MBX1_ISPTSPCTL_OFFSET) &&
((ui32ISPTSPCtl & MBX1_ISPTSPCTL_UVCOUNT) >> MBX1_ISPTSPCTL_UVCOUNTSHIFT) == 1)
{
/* We have an offset colour and 2 sets of tex coords so we need to limit strip length */
D3DM_PRIM_FUNCTION eFunction;
if(psContext->dwHWPRN725Flags & HW_PRN_725_FLAGS_INDEXED)
{
eFunction = (D3DM_PRIM_FUNCTION) sIndexedPrimLookup[(psContext->eCurrentPrimType * 3) + psContext->ePrimFillMode];
}
else
{
eFunction = (D3DM_PRIM_FUNCTION) sPrimLookup[(psContext->eCurrentPrimType * 3) + psContext->ePrimFillMode];
}
switch(eFunction)
{
case TRIANGLELIST:
case INDEXEDTRIANGLELIST:
{
if(psContext->dwNumVerticesSent == 3)
{
TACSWriteLastPrim(psContext);
TACSWritePrimHdr(psContext, psContext->dwTAPrimCtl, MBX1_TAOBJTYPE_VERTEXFACELIST);
}
break;
}
case TRIFANLINE: /* Uses line strips */
case INDEXEDTRIFANLINE: /* Uses line strips */
case TRILISTLINE: /* Uses line strips */
case INDEXEDTRILISTLINE: /* Uses line strips */
case TRISTRIPLINE: /* Uses line strips */
case INDEXEDTRISTRIPLINE: /* Uses line strips */
case LINELIST: /* Uses line strips */
case INDEXEDLINELIST: /* Uses line strips */
case LINESTRIP:
case INDEXEDLINESTRIP:
{
if(psContext->dwNumVerticesSent == 5)
{
PVR_NATIVE_VERTEX* ppsVertex;
/* End Strip */
TACSWriteEndPrim(psContext);
ppsVertex = &psContext->sVertices[1];
/* re-write last vertex */
OutputVertices(psContext, &ppsVertex, 1);
/* Ensure we have space required to continue */
while(psContext->dwAllocatedFifoSpaceDWORDS < ui32RequiredDataSize)
{
PVRSRVAcquire3DFifoSpace (psDevData->psDevInfoUM,
&psContext->sHWInfo,
&ui32BytesObtained);
psContext->dwAllocatedFifoSpaceDWORDS = (ui32BytesObtained >> 2);
}
}
break;
break;
}
case TRIANGLESTRIP:
case INDEXEDTRIANGLESTRIP:
{
if(psContext->dwHWPRN725Flags & HW_PRN_725_FLAGS_RESEND_LAST_TWO)
{
PVR_NATIVE_VERTEX* ppsVertices[2];
/* Set up our pointers */
ppsVertices[0] = &psContext->sVertices[0];
ppsVertices[1] = &psContext->sVertices[1];
/* Terminate the last triangle before continuing */
TACSWriteEndPrim(psContext);
/* Clear HW_PRN_725_FLAGS_RESEND_LAST_TWO now or we'll blow the stack */
psContext->dwHWPRN725Flags &= ~HW_PRN_725_FLAGS_RESEND_LAST_TWO;
psContext->dwHWPRN725Flags &= ~HW_PRN_725_FLAGS_STOREVERTS;
OutputVertices(psContext, ppsVertices, 2);
psContext->dwHWPRN725Flags |= HW_PRN_725_FLAGS_STOREVERTS;
/* Ensure we have space required to continue */
while(psContext->dwAllocatedFifoSpaceDWORDS < ui32RequiredDataSize)
{
PVRSRVAcquire3DFifoSpace (psDevData->psDevInfoUM,
&psContext->sHWInfo,
&ui32BytesObtained);
psContext->dwAllocatedFifoSpaceDWORDS = (ui32BytesObtained >> 2);
}
}
if(psContext->dwNumVerticesSent == 5)
{
PVR_NATIVE_VERTEX* ppsVertices[2];
/* End the strip */
TACSWriteEndPrim(psContext);
if((psContext->dwTAPrimCtl & MBX1_TAPRIM_CULLMODEMASK) != MBX1_TAPRIM_CULLMODENONE)
{
/*
The next triangle is going to have incorrect cull sense so we need
to do a bit of jiggery pokery and swap the last two vertices before
resending, then send the next, then end the strip and flag that we
need to send the last two verts if we have no more vertices to send
with this call, or just resend the last two vertices if we are continuing
the strip in this call.
*/
/* Swap the vertex order */
ppsVertices[0] = &psContext->sVertices[1];
ppsVertices[1] = &psContext->sVertices[0];
/* We don't want to update */
psContext->dwHWPRN725Flags &= ~HW_PRN_725_FLAGS_STOREVERTS;
/* Output the re-jigged vertices */
OutputVertices(psContext, ppsVertices, 2);
OutputVertices(psContext, &psVertex, 1);
psContext->dwHWPRN725Flags |= HW_PRN_725_FLAGS_STOREVERTS;
/* Mod the vertex store to reflect the correct sequence */
psContext->sVertices[0] = psContext->sVertices[1];
psContext->sVertices[1] = *psVertex;
if(ui32VertexCount-- == 0)
{
/* That was the last for this call, so return */
psContext->dwHWPRN725Flags |= HW_PRN_725_FLAGS_RESEND_LAST_TWO;
return;
}
else
{
/* Terminate the last triangle and restart the strip*/
TACSWriteEndPrim(psContext);
ppsVertices[0] = &psContext->sVertices[0];
ppsVertices[1] = &psContext->sVertices[1];
psContext->dwHWPRN725Flags &= ~HW_PRN_725_FLAGS_STOREVERTS;
OutputVertices(psContext, ppsVertices, 2);
psContext->dwHWPRN725Flags |= HW_PRN_725_FLAGS_STOREVERTS;
psVertex = *ppsVertex++;
}
}
else
{
/* We're currently not culling, so just continue */
ppsVertices[0] = &psContext->sVertices[0];
ppsVertices[1] = &psContext->sVertices[1];
OutputVertices(psContext, ppsVertices, 2);
}
/* Ensure we have space required to continue */
while(psContext->dwAllocatedFifoSpaceDWORDS < ui32RequiredDataSize)
{
PVRSRVAcquire3DFifoSpace (psDevData->psDevInfoUM,
&psContext->sHWInfo,
&ui32BytesObtained);
psContext->dwAllocatedFifoSpaceDWORDS = (ui32BytesObtained >> 2);
}
}
break;
}
case TRIANGLEFAN:
case INDEXEDTRIANGLEFAN:
{
/* HW will break fans into strips of MAX 5 vertices so Ignore this case */
break;
}
case POINTLIST:
case INDEXEDPOINTLIST:
{
if(psContext->dwNumVerticesSent == 5)
{
TACSWriteEndPrim(psContext);
}
break;
}
}
}
else
{
/* We're not using the Fix so don't store vertices */
psContext->dwHWPRN725Flags &= ~HW_PRN_725_FLAGS_STOREVERTS;
}
#endif
if(ui32DWWritten + ui32VertexSizeDW > 32)
{
/* Reset data pointer */
pvLinPortAddr = psSlavePort->pvData;
ui32DWWritten = 0;
}
/* n.b. this function won't handle Viewport (ISP only XYZ) objects */
*((NTV_TYPE*) pvLinPortAddr)++ = CLAMP_LOWER(psVertex->sWindow.x);
*((NTV_TYPE*) pvLinPortAddr)++ = CLAMP_LOWER(psVertex->sWindow.y);
PDUMPSPBATCH(psContext->psPDContext, PDUMPTAGS_SP_MBX_DATA, (DWORD*)&psVertex->sWindow.x, 2);
if(psContext->dwTAPrimCtl & MBX1_TAPRIM_WBUFFERING_ENABLE)
{
if(psContext->sTState.dwRSFlags & TSTATE_RSFLAGS_DEPTHBIAS)
{
*((NTV_TYPE*) pvLinPortAddr)++ =
CLAMPTO(Add(PR_UNSHIFT(psVertex->sWindow.w), psContext->sTState.D3DZBiasOffset), D3DM_Zero, D3DM_One);
#if defined (PDUMP)
ui32Colour = CLAMPTO(Add(PR_UNSHIFT(psVertex->sWindow.w), psContext->sTState.D3DZBiasOffset), D3DM_Zero, D3DM_One);
PDUMPSP(psContext->psPDContext, PDUMPTAGS_SP_MBX_DATA, TO_ULONG(ui32Colour));
#endif
}
else
{
*((NTV_TYPE*) pvLinPortAddr)++ = CLAMP_LOWER(PR_UNSHIFT(psVertex->sWindow.w));
PDUMPSP(psContext->psPDContext, PDUMPTAGS_SP_MBX_DATA, TO_ULONG(PR_UNSHIFT(psVertex->sWindow.w)));
}
}
else
{
if(psContext->sTState.dwRSFlags & TSTATE_RSFLAGS_DEPTHBIAS)
{
*((NTV_TYPE*) pvLinPortAddr)++ =
CLAMPTO(Add(PR_UNSHIFT(psVertex->sWindow.z), psContext->sTState.D3DZBiasOffset), D3DM_Zero, D3DM_One);
#if defined (PDUMP)
ui32Colour = CLAMPTO(Add(PR_UNSHIFT(psVertex->sWindow.z), psContext->sTState.D3DZBiasOffset), D3DM_Zero, D3DM_One);
PDUMPSP(psContext->psPDContext, PDUMPTAGS_SP_MBX_DATA, TO_ULONG(ui32Colour));
#endif
}
else
{
*((NTV_TYPE*) pvLinPortAddr)++ = CLAMP_LOWER(PR_UNSHIFT(psVertex->sWindow.z));
PDUMPSP(psContext->psPDContext, PDUMPTAGS_SP_MBX_DATA, TO_ULONG(PR_UNSHIFT(psVertex->sWindow.z)));
}
*((NTV_TYPE*) pvLinPortAddr)++ = CLAMP_LOWER(PR_UNSHIFT(psVertex->sWindow.w));
PDUMPSP(psContext->psPDContext, PDUMPTAGS_SP_MBX_DATA, TO_ULONG(PR_UNSHIFT(psVertex->sWindow.w)));
}
/* Select and copy diffuse */
if(psContext->sTState.dwRSFlags & TSTATE_RSFLAGS_FLAT_SHADING &&
psContext->eCurrentPrimType != D3DMPT_TRIANGLESTRIP &&
psContext->eCurrentPrimType != D3DMPT_LINESTRIP &&
psContext->eCurrentPrimType != D3DMPT_TRIANGLEFAN)
{
if(psVertex->ui32Flags & D3DM_HASFLAG_RHW)
{
*((IMG_UINT32*) pvLinPortAddr)++ = psFlatDiffuse->ui32Colour;
#if defined (PDUMP)
PDumpSlavePort(psContext->psPDContext, PDUMPTAGS_SP_MBX_DATA, psFlatDiffuse->ui32Colour);
#endif
}
else
{
*((IMG_UINT32*) pvLinPortAddr)++ = (AS_ULONG(Mul(psFlatDiffuse->a, LONG_AS_NTV(255)))<<24)
| (AS_ULONG(Mul(psFlatDiffuse->r, LONG_AS_NTV(255)))<<16)
| (AS_ULONG(Mul(psFlatDiffuse->g, LONG_AS_NTV(255)))<<8)
| AS_ULONG(Mul(psFlatDiffuse->b, LONG_AS_NTV(255)));
#if defined (PDUMP)
PDumpSlavePort(psContext->psPDContext, PDUMPTAGS_SP_MBX_DATA, (AS_ULONG(Mul(psFlatDiffuse->a, LONG_AS_NTV(255)))<<24)
| (AS_ULONG(Mul(psFlatDiffuse->r, LONG_AS_NTV(255)))<<16)
| (AS_ULONG(Mul(psFlatDiffuse->g, LONG_AS_NTV(255)))<<8)
| AS_ULONG(Mul(psFlatDiffuse->b, LONG_AS_NTV(255))));
#endif
}
}
else
{
if(psVertex->ui32Flags & D3DM_HASFLAG_RHW)
{
*((IMG_UINT32*) pvLinPortAddr)++ = psVertex->sDiffuseOut.ui32Colour;
#if defined (PDUMP)
PDumpSlavePort(psContext->psPDContext, PDUMPTAGS_SP_MBX_DATA, psVertex->sDiffuseOut.ui32Colour);
#endif
}
else
{
*((IMG_UINT32*) pvLinPortAddr)++ = (AS_ULONG(Mul(psVertex->sDiffuseOut.a, LONG_AS_NTV(255)))<<24)
| (AS_ULONG(Mul(psVertex->sDiffuseOut.r, LONG_AS_NTV(255)))<<16)
| (AS_ULONG(Mul(psVertex->sDiffuseOut.g, LONG_AS_NTV(255)))<<8)
| AS_ULONG(Mul(psVertex->sDiffuseOut.b, LONG_AS_NTV(255)));
#if defined (PDUMP)
PDumpSlavePort(psContext->psPDContext, PDUMPTAGS_SP_MBX_DATA, (AS_ULONG(Mul(psVertex->sDiffuseOut.a, LONG_AS_NTV(255)))<<24)
| (AS_ULONG(Mul(psVertex->sDiffuseOut.r, LONG_AS_NTV(255)))<<16)
| (AS_ULONG(Mul(psVertex->sDiffuseOut.g, LONG_AS_NTV(255)))<<8)
| AS_ULONG(Mul(psVertex->sDiffuseOut.b, LONG_AS_NTV(255))));
#endif
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -