⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vertex.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    /*
    ** 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 + -