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

📄 clear.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
				Save latest fullscreen clear depth
				if we are updating depthbuffer.
			*/
			if	(dwFlags & D3DMCLEAR_ZBUFFER)
			{
				psContext->sTState.fLastClearZ = LONG_TO_FLOAT(dwDepth);
			}
		}
		else
		{
			D3DM_DPF((DPF_MESSAGE, "not full render srf clear"));
		}
		
		/*
			Seed a polygon to clear the specifed render area.
			Flat shaded,
			Non-culled,
			Non-indexed strips of 2 (ie rectangle),
			Z Disabled,
			Z Always.
		*/
		ClearRectangle(psContext, 
					   psRect,
					   dwFillColour,
					   dwDepth,
					   dwRHW,
					   (dwFSFlags & (0x1 << i)));

		/*
			Move along to the next rectangle.
		*/
		psRect++;
	}
}








/*****************************************************************************
 FUNCTION	: Clear
    
 PURPOSE	: Handles clears for dp2 op.

 PARAMETERS	: psContext		D3D context
			  dwFlags		The type of clear to perform
			  dwFillColour	The colour to use when clearing the target
			  fFillDepth	The depth to use when clearing the depth-buffer
			  dwNumRects	The number of rects at lpRects
			  psRects		An array of dwNumRects rectangles
			  
 RETURNS	: void
*****************************************************************************/
void Clear(	LPD3DM_CONTEXT	psContext,
			DWORD			dwFlags,
			DWORD			dwFillColour,
			float			fFillDepth,
			DWORD			dwNumRects,
			LPD3DMRECT		psRects)
{
	LPD3DM_SURFACE			psRenderTarget;
	BOOL					bFullScreen;
	PVRSRV_DEV_INFO			*psDevInfo;
	LPD3DMRECT				psNewRects, psRect;
	DWORD					i, dwFirstClear = 0, dwFSFlags = 0;
	BOOL					bDeferSend = IMG_FALSE;

	D3DM_DPF((DPF_MESSAGE, "Clear"));

	psRenderTarget		= psContext->psCurrentRenderTarget;
	psDevInfo			= GetDevInfo(psContext);
	psRect				= psRects;

	if((dwFlags & ~D3DMCLEAR_STENCIL) == 0)
	{
		/* Stencil clear only */
		return;
	}

	/*
		Mask off stencil-clear flag - no stencil support on MBX1
	*/
	dwFlags &= ~D3DMCLEAR_STENCIL;

	for(i=0; i<dwNumRects; i++)
	{
		/* Is it fullscreen? */
		switch(psContext->dwRotationAngle)
		{
			case 0:
			case 180:
			{
				if((psRect->x1 == 0) && (psRect->x2 >= (int) (psRenderTarget->dwWidth  - 1)) &&
				   (psRect->y1 == 0) && (psRect->y2 >= (int) (psRenderTarget->dwHeight - 1)))
				{
					D3DM_DPF((DPF_MESSAGE, "Fullscreen Clear"));
					bFullScreen = TRUE;
				}
				else
				{
					bFullScreen = FALSE;
				}
				break;
			}
			case 90:
			case 270:
			{
				if((psRect->x1 == 0) && (psRect->y2 >= (int) (psRenderTarget->dwWidth  - 1)) &&
				   (psRect->y1 == 0) && (psRect->x2 >= (int) (psRenderTarget->dwHeight - 1)))
				{
					D3DM_DPF((DPF_MESSAGE, "Fullscreen Clear"));
					bFullScreen = TRUE;
				}
				else
				{
					bFullScreen = FALSE;
				}
				break;
			}
		}
	

		if((psRenderTarget->dwFlags & D3DM_SURFACE_FLAGS_SCENE_STARTED) == 0)
		{
			/*
				Scene hasn't yet begun, so check if this is a fullscreen clear and if so,
				store the clear details to be processed as the background object in BeginScene
			*/
			if(bFullScreen)
			{

				if(dwFlags & D3DMCLEAR_TARGET)
				{
					psRenderTarget->sDescription.sSurface.dwClearFlags |= D3DM_SURFACE_CLEARFLAGS_FULLSCREEN_TARGET;
					psContext->sTState.dwLastClearColour = dwFillColour;
				}
				if(dwFlags & D3DMCLEAR_ZBUFFER)
				{
					psRenderTarget->sDescription.sSurface.dwClearFlags |= D3DM_SURFACE_CLEARFLAGS_FULLSCREEN_DEPTH;
					psContext->sTState.fLastClearZ = fFillDepth;
				}
				
				bDeferSend	 = IMG_TRUE;			
				dwFirstClear = i;

			}
			else
			{
				/* Non fullscreen clear so we need to send this Now */
				if(bDeferSend == IMG_TRUE)
				{
					bDeferSend = IMG_FALSE;
					psRenderTarget->sDescription.sSurface.dwClearFlags &= ~(D3DM_SURFACE_CLEARFLAGS_FULLSCREEN_TARGET |
																			D3DM_SURFACE_CLEARFLAGS_FULLSCREEN_DEPTH);
				}
			}
		}
		else
		{
			/* Scene has started so we should send */
			bDeferSend = IMG_FALSE;
		}
		psRect++;

		if(bFullScreen)
		{
			dwFSFlags |= 0x1 << i;
		}
	}

	if(bDeferSend)
	{
		return;
	}
	else
	{
		dwNumRects  -= dwFirstClear;
		psRects		+= dwFirstClear;
		dwFSFlags   >>= dwFirstClear;
	}

	/* If we're running rotated we need to recalculate the positions of the clear rectangles */
	if(psContext->dwRotationAngle != 0)
	{
		psNewRects =  D3DMAllocate(dwNumRects *  sizeof(D3DMRECT));
		dwFSFlags = RotateRects(psContext, 
								psNewRects, 
								psRects, 
								dwNumRects, 
								psRenderTarget->dwWidth, 
								psRenderTarget->dwHeight);
	}
	else
	{
		psNewRects = psRects;
	}

	/* Acquire TA and Slave port */
	if(D3DMAcquireTAResources(psContext, TRUE) != PVRSRV_OK)
	{
		/* Scene is invalidated */
		return;
	}

	SendClear(psContext,
			  dwFlags,
			  dwFillColour,
			  fFillDepth,
			  dwNumRects,
			  psNewRects,
			  dwFSFlags);

	/* Release TA and Slaveport */
	D3DMReleaseTAResources(psContext, FALSE);

	if(psContext->dwRotationAngle != 0)
	{
		D3DMFree(psNewRects);
	}
}

/*****************************************************************************
############################### VIEWPORTS:####################################
*****************************************************************************/

/*****************************************************************************
 FUNCTION	: ClipRectangle
    
 PURPOSE	: 	Sends ISP Clip Mask object.
				Implements clipping for D3D viewports.

 PARAMETERS	: 	LPD3DM_CONTEXT	psContext
				LPD3DMRECT		psRect
				BOOL			bFullScreen
			  
 RETURNS	: 
*****************************************************************************/
static void ClipRectangle(LPD3DM_CONTEXT		psContext,
						  LPD3DMRECT			psRect,
						  BOOL					bFullScreen)
{
	PHWSTATE		psHWState;
	PHWSTATECTL		psHWStateCtl;
	LPD3DM_SURFACE	psRenderTarget;
	DWORD			*pdwVertex;
	DWORD			adwVertex[12];
	NTV_TYPE		ntvX1, ntvX2, ntvY1, ntvY2, ntvD3DM_One = D3DM_One;
	DWORD			dwFillDepth;
	DWORD 			dwTAPrimCtl;
#if defined (SUPPORT_VGP) || defined (SUPPORT_VGP_LITE)
	DWORD			dwVGPClipCtl;
    DWORD           dwFVFCode;
	VSIFDEF			sVSIFDef;
	DWORD			dwTnLFlags;
#endif
	DWORD			dwWidth, dwHeight;

	psHWState		 = &psContext->sHWState;			
	psHWStateCtl	 = &psContext->sHWStateCtl;
	psRenderTarget	 = psContext->psCurrentRenderTarget;

	/*
		use any depth - it should not matter
	*/
	dwFillDepth  = TO_ULONG(ntvD3DM_One);

	ntvX1 = LONG_AS_NTV(psRect->x1);
	ntvY1 = LONG_AS_NTV(psRect->y1);

	/*
		Calculate width and height rounded up to next tile boundary.
	*/
	RoundToTileBoundary(psContext,
						TRUE,
						psRenderTarget->dwWidth, 
						psRenderTarget->dwHeight, 
						&dwWidth, 
						&dwHeight, 
						NULL, 
						NULL);

	/*
		Are we fullscreen?
	*/
	if	(bFullScreen)
	{
		HWTACTL3DSTATE	sHWTACtl3DState;

		/*
			If dest rectangle is full-rendersurface,
			send single triangle scaled up in size to cover
			full screen.
		*/
		D3DM_DPF((DPF_MESSAGE, "full render srf clip - sending single tri"));

		ntvX2 = Add(ntvX1, LONG_AS_NTV(2 * dwWidth));
		ntvY2 = Add(ntvY1, LONG_AS_NTV(2 * dwHeight));

		/*
			Manually insert fullscreen region clip into control stream,
		*/
		sHWTACtl3DState.dwRegionClip = psRenderTarget->sDescription.sSurface.dwFSRegionClip;

		TACSWriteTACtlAnd3DState(psContext, 
								 MBX1_TASTATEPRES_REGIONCLIP,
								 &sHWTACtl3DState,
								 FALSE);

		/*
			Record what state we have changed
		*/
		psHWStateCtl->dwTACtl3DStateChanged |= MBX1_TASTATEPRES_REGIONCLIP;
	}
	else
	{
		/*
			If dest rectangle is smaller than full-rendersurface,
			send two-triangle quad as normal.
		*/
		D3DM_DPF((DPF_MESSAGE, "not full render srf clip - sending 2-tri quad"));

		ntvX2 = LONG_AS_NTV(psRect->x2);
		ntvY2 = LONG_AS_NTV(psRect->y2);

		/*
			Increase full-surface blits to next tilesize up.
		*/
		if	(psRect->x2 == (int) psRenderTarget->dwWidth)
		{
			ntvX2 = LONG_AS_NTV(dwWidth);
		}

		if	(psRect->y2 == (int) psRenderTarget->dwHeight)
		{
			ntvY2 = LONG_AS_NTV(dwHeight);
		}
	}

	/*
		Setup appropriate primitive block-header controls
	*/
	dwTAPrimCtl = MBX1_TAPRIM_NONPERSPCORRECT |
				  MBX1_TAPRIM_ZBIAS_MODEINCREASING |
				  (0 << MBX1_TAPRIM_ZBIAS_SHIFT) |
				  MBX1_TAPRIM_CULLMODENONE |
                  (psContext->dwTAPrimCtl & MBX1_TAPRIM_WBUFFERING_ENABLE);

#if defined (SUPPORT_VGP) || defined (SUPPORT_VGP_LITE)

    /* Set up the FVF code and Pass through shader flags */
    dwFVFCode = D3DMFVF_XYZ_FLOAT;

	dwTnLFlags = 0;	

	/*
		Configure the FVF passthough-shader for the FVF we require
	*/
	VSIFDefSetupForFVF(psContext, &sVSIFDef, dwFVFCode, 3<<2);

	/* set up the pass-through vertex-shader for this clear data type */
	VGPTNLSetUpPassThroughShader(psContext, dwTnLFlags);

	/* Ensure our VGP instructions are up to date before sending anything */
	UpdateVGPInstructions(psContext);

	/* Update the vertex-copy data */
	SetupVertexCopyData(psContext, &sVSIFDef);

	/* update Interface Def HW State */
	psContext->sHWState.sTACtl3DState.dwVGPIFDef = sVSIFDef.dwVGPIFDef;
	psContext->sHWStateCtl.dwTACtl3DStateChanged |= MBX1_TASTATEPRES_VGP_IFDEFINITION;

	/*
		Write out all the HW-state that has just changed as a result of
		loading the passthrough shader
	*/
	TACSWriteTACtlAnd3DState(psContext,
							 MBX1_TASTATEPRES_VGP_IFDEFINITION,
							 &psHWState->sTACtl3DState,
							 FALSE);

	TACSWriteVGPControlState(psContext,
							 psHWStateCtl->dwVGPCtlStateChanged,
							 &psHWState->sVGPControl,
							 FALSE);

	/*
		Reset the VGP-control 'state-changed' flags (since all changed 
		state has now been output)
	*/
	psHWStateCtl->dwVGPCtlStateChanged = 0;

	/*
		Disable stuff in the VGP-clip control word
	*/
	dwVGPClipCtl = psContext->dwVGPClipCtl;

	dwVGPClipCtl &= ~(MBX1_VGPCLIPCTL_CLIPPLANES_MASK |
					  MBX1_VGPCLIPCTL_VIEWPORTTRANS_ENABLE |
					  MBX1_VGPCLIPCTL_STARTSECTION_MASK);
#endif /* #if defined(SUPPORT_VGP) */

	/*
		Begin a new vertex-strip
	*/
	TACSWritePrimHdr(psContext, dwTAPrimCtl, MBX1_TAOBJTYPE_VERTEXFACESTRIP);

#if defined (SUPPORT_VGP) || defined (SUPPORT_VGP_LITE)
	TACSWriteVGPClipWord(psContext, dwVGPClipCtl);
#endif
	/*
		Setup vertex data for 2 triangles using 4 vertices.
		Clip the vertices to tile boundaries since TA now clips to tile boundaries.
		Only need to do bottom right hand corner since full size clears are ALWAYS from 0,0.
	*/
	pdwVertex = adwVertex;

    *pdwVertex++ = TO_ULONG(ntvX1);
    *pdwVertex++ = TO_ULONG(ntvY2);
	*pdwVertex++ = dwFillDepth;

    *pdwVertex++ = TO_ULONG(ntvX1);
    *pdwVertex++ = TO_ULONG(ntvY1);
	*pdwVertex++ = dwFillDepth;

	if (!bFullScreen)
	{
		*pdwVertex++ = TO_ULONG(ntvX2);
		*pdwVertex++ = TO_ULONG(ntvY2);
		*pdwVertex++ = dwFillDepth;
	}

	*pdwVertex++ = TO_ULONG(ntvX2);
	*pdwVertex++ = TO_ULONG(ntvY1);
	*pdwVertex++ = dwFillDepth;	


#if defined (SUPPORT_VGP) || defined (SUPPORT_VGP_LITE)

	CopySelect(psContext,
			  (IMG_UINT8 *)adwVertex, 
			  bFullScreen ? 4 : 3, 
			  &sVSIFDef);

#else

	TACSWriteData(psContext, (PVOID)adwVertex, (pdwVertex-adwVertex)<<2);

#endif

	TACSWriteLastPrim(psContext);

#if defined (SUPPORT_VGP) || defined (SUPPORT_VGP_LITE)

	/* update Interface Def HW State */
	if(psContext->psVertexSource)
	{
		psContext->sHWState.sTACtl3DState.dwVGPIFDef = psContext->psVertexSource->sVSIFDef.dwVGPIFDef;
		psContext->sHWStateCtl.dwTACtl3DStateChanged |= MBX1_TASTATEPRES_VGP_IFDEFINITION;
	}


#endif /* #if defined(SUPPORT_VGP) */

}


/*****************************************************************************
 FUNCTION	: SendViewPort
    
 PURPOSE	: Sends ISP Clipping Mask Object - first does an full surface disable,
			  then sends an enable of the D3D viewport size.

 PARAMETERS	:  LPD3DM_CONTEXT psContext, LPD3DMRECT psRect, BOOL bFullScreen
			  
 RETURNS	: 
*****************************************************************************/
void SendViewPort(LPD3DM_CONTEXT psContext, LPD3DMRECT psRect, BOOL bFullScreen)
{
	HWTACTL3DSTATE	sTACtl3DState;
	DWORD			dwStateChanged = 0;

	D3DM_DPF((DPF_MESSAGE, "SendViewPort"));
	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -