📄 clear.c
字号:
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 + -