📄 surface.c
字号:
LPD3DM_CONTEXT psContext = psSurface->psContext;
DWORD i;
HWND hWnd;
BOOL bRes;
/* Flush All Queues */
if(!psSurface->sDescription.sSurface.bSceneTADataSent)
{
/* Only flush if we've ended the last scene, as the call will spin otherwise */
D3DMFlushAllQueues(psContext);
}
if(psContext->SwapEffect == D3DMSWAPEFFECT_FLIP)
{
/*
Primary of Flip Chain - If were destroying the primary,
then we're destroying the whole chain, so free the render
info and mark any backbuffers invalid.
First up we need to Flip back to the primary if it's not already displayed
*/
if(psContext->psCurrentDisplay != psContext->sChain.psPrimary)
{
DWORD dwRes = 0;
/* Queue the flip */
if(PVRSRVQueueFlip(psContext->psContextQueue,
psContext->sChain.psPrimary->psMemInfo->psSyncInfo,
psContext->psCurrentDisplay->psMemInfo->psSyncInfo,
psContext->sChain.psPrimary->psMemInfo,
TRUE ,
1) != PVRSRV_OK)
{
D3DM_DPF((DPF_ERROR, "DestroySurface:Couldn't queue the flip back to the primary"));
psContext->hrLastError = D3DM_GENERICFAILURE;
return;
}
psContext->psCurrentDisplay = psContext->sChain.psPrimary;
}
D3DMDisconnectRenderTarget(psContext, psSurface);
for(i=0; i<MAX_FLIP_SURFACES-1; i++)
{
/* Mark back buffer renderinfo's as invalid */
LPD3DM_SURFACE psTarget = psContext->sChain.psBackBuffers[i];
if(psTarget)
psTarget->sDescription.sSurface.psTARenderInfo = NULL;
}
/* RefreshDesktop */
hWnd = GetForegroundWindow();
bRes = InvalidateRect(hWnd, NULL, TRUE);
bRes = UpdateWindow(hWnd);
psContext->sChain.psPrimary = NULL;
}
/* Free up surface */
D3DMFree(psSurface);
pdsd->rval = D3DM_OK;
}
/*----------------------------------------------------------------------------
<function>
FUNCTION: DestroyBackBuffer
PURPOSE: Destroys a back buffer
PARAMETERS: In: pcsd - surface creation data
RETURNS:
</function>
------------------------------------------------------------------------------*/
VOID DestroyBackBuffer(D3DM_DESTROYSURFACE_DATA *pdsd)
{
/***************************
* BACKBUFFER *
***************************/
LPD3DM_SURFACE psSurface = (LPD3DM_SURFACE) pdsd->nSurfaceId;
LPD3DM_CONTEXT psContext = psSurface->psContext;
LPD3DM_SURFACE psPrimary = psContext->sChain.psPrimary;
DWORD i;
/* Flush All Queues */
if(!psSurface->sDescription.sSurface.bSceneTADataSent)
{
/* Only flush if we've ended the last scene, as the call will fail otherwise */
D3DMFlushAllQueues(psContext);
}
if(psSurface->sDescription.sSurface.psTARenderInfo != NULL &&
!(psContext->SwapEffect == D3DMSWAPEFFECT_FLIP))
{
/* Disconnect from services */
D3DMDisconnectRenderTarget(psContext, psSurface);
/* Mark other back buffers renderinfos with NULL*/
for(i=0; i<MAX_FLIP_SURFACES -1; i++)
{
/* Remove back buffer reference */
LPD3DM_SURFACE psTarget = psContext->sChain.psBackBuffers[i];
if(psTarget)
{
psTarget->sDescription.sSurface.psTARenderInfo = NULL;
}
}
}
else
{
/* If this is the currently displayed surface, flip back to the primary */
if(psContext->psCurrentDisplay == psSurface)
{
DWORD dwRes = 0;
/* Queue the flip */
if(PVRSRVQueueFlip(psContext->psContextQueue,
psPrimary->psMemInfo->psSyncInfo,
psContext->psCurrentDisplay->psMemInfo->psSyncInfo,
psPrimary->psMemInfo,
TRUE ,
1) != PVRSRV_OK)
{
D3DM_DPF((DPF_ERROR, "DestroySurface:Couldn't queue the flip back to the primary"));
psContext->hrLastError = D3DM_GENERICFAILURE;
return;
}
psContext->psCurrentDisplay = psContext->sChain.psPrimary;
}
/* Just Destroy the Queue */
PVRSRVDestroyCommandQueue(&psContext->sDevData, psSurface->sDescription.sSurface.psQueue);
}
/* Free up surface FB mem */
D3DMFreeDeviceMem(&psContext->sDevData, psSurface->psMemInfo);
/* remove from our back buffer List */
for(i=0; i<MAX_FLIP_SURFACES -1; i++)
{
/* Remove back buffer reference */
LPD3DM_SURFACE psTarget = psContext->sChain.psBackBuffers[i];
if(psTarget == psSurface)
{
psContext->sChain.psBackBuffers[i] = NULL;
break;
}
}
/* Free up surface */
D3DMFree(psSurface);
pdsd->rval = D3DM_OK;
}
/*----------------------------------------------------------------------------
<function>
FUNCTION: DestroySurface
PURPOSE:
PARAMETERS: In: pcsd - surface creation data
RETURNS:
</function>
------------------------------------------------------------------------------*/
VOID DestroySurface(D3DM_DESTROYSURFACE_DATA *pdsd)
{
/***************************
* IMAGE_SURFACE *
***************************/
LPD3DM_SURFACE psSurface = (LPD3DM_SURFACE) pdsd->nSurfaceId;
LPD3DM_CONTEXT psContext = psSurface->psContext;
/* rendertarget so disconnect */
if(psSurface->dwUsage & D3DMUSAGE_RENDERTARGET)
{
LPD3DM_SURFACE psTemp;
if(!psSurface->sDescription.sSurface.bSceneTADataSent)
{
/* Flush Queues */
D3DMFlushAllQueues(psContext);
}
/* Disconnect from services */
D3DMDisconnectRenderTarget(psContext, psSurface);
psTemp = psContext->psNonChainRenderTargets;
/* Remove from non-chain RT list */
if(psTemp == psSurface)
{
psContext->psNonChainRenderTargets = psSurface->psNext;
}
else
{
while(psTemp->psNext != psSurface)
{
psTemp = psTemp->psNext;
}
psTemp->psNext = psTemp->psNext->psNext;
}
}
/* Flush context Queue to remove any outstanding blits */
PVRSRVFlushQueue(psContext->psContextQueue);
/* Free up surface FB mem */
D3DMFreeDeviceMem(&psContext->sDevData, psSurface->psMemInfo);
/* Free up surface */
D3DMFree(psSurface);
pdsd->rval = D3DM_OK;
}
/*----------------------------------------------------------------------------
<function>
FUNCTION: DestroyDepthBuffer
PURPOSE: Destroys a D3D mobile Depth buffer
PARAMETERS: In: pcsd - surface creation data
RETURNS:
</function>
------------------------------------------------------------------------------*/
VOID DestroyDepthBuffer(D3DM_DESTROYSURFACE_DATA *pdsd)
{
/***************************
* Z-BUFFER *
***************************/
LPD3DM_SURFACE psSurface = (LPD3DM_SURFACE) pdsd->nSurfaceId;
LPD3DM_CONTEXT psContext = psSurface->psContext;
if(psSurface->psMemInfo)
{
/* Free up surface FB mem */
D3DMFreeDeviceMem(&psContext->sDevData, psSurface->psMemInfo);
}
/* Free up surface */
D3DMFree(psSurface);
}
/*----------------------------------------------------------------------------
<function>
FUNCTION: DestroyVBuffer
PURPOSE: Destroys a D3D mobile Vertex buffer
PARAMETERS: In: pdsd - surface destruction data
RETURNS:
</function>
------------------------------------------------------------------------------*/
VOID DestroyVBuffer(D3DM_DESTROYSURFACE_DATA *pdsd)
{
LPD3DM_VBUFFER psBuffer = (LPD3DM_VBUFFER) pdsd->nSurfaceId;
D3DMFree(psBuffer->pvVertexData);
D3DMFree(psBuffer);
pdsd->rval = D3DM_OK;
}
/*----------------------------------------------------------------------------
<function>
FUNCTION: DestroyIBuffer
PURPOSE: Destroys a D3D mobile Index buffer
PARAMETERS: In: pdsd - surface destruction data
RETURNS:
</function>
------------------------------------------------------------------------------*/
VOID DestroyIBuffer(D3DM_DESTROYSURFACE_DATA *pdsd)
{
LPD3DM_IBUFFER psBuffer = (LPD3DM_IBUFFER) pdsd->nSurfaceId;
D3DMFree(psBuffer->pvIndexData);
D3DMFree(psBuffer);
pdsd->rval = D3DM_OK;
}
/*----------------------------------------------------------------------------
<function>
FUNCTION: PVRD3DM_CreateSurface
PURPOSE: Surface Creation callback - handles creation of all surface
types including Vertex and Index Buffers
PARAMETERS: In:
RETURNS: D3DM_DRIVER_HANDLED || D3DM_DRIVER_NOTHANDLED
</function>
------------------------------------------------------------------------------*/
DWORD PVRD3DM_CreateSurface(D3DM_CREATESURFACE_DATA *pcsd)
{
D3DMRESOURCETYPE eType = pcsd->SurfaceType;
switch(eType)
{
case D3DMRTYPE_FRONTBUFFER:
{
CreateFrontBuffer(pcsd);
break;
}
case D3DMRTYPE_BACKBUFFER:
{
CreateBackBuffer(pcsd);
break;
}
case D3DMRTYPE_SURFACE:
{
CreateSurface(pcsd);
break;
}
case D3DMRTYPE_TEXTURE:
{
CreateTexture(pcsd);
break;
}
case D3DMRTYPE_DEPTHSTENCIL:
{
CreateDepthBuffer(pcsd);
break;
}
case D3DMRTYPE_VERTEXBUFFER:
{
CreateVBuffer(pcsd);
break;
}
case D3DMRTYPE_INDEXBUFFER:
{
CreateIBuffer(pcsd);
break;
}
default:
{
D3DM_DPF((DPF_WARN, "PVRD3DM_CreateSurface:Invalid surface type (%u)", (DWORD) eType));
pcsd->rval = D3DMERR_INVALIDCALL;
}
}
return D3DM_DRIVER_HANDLED;
}
/*----------------------------------------------------------------------------
<function>
FUNCTION: PVRD3DM_DestroySurface
PURPOSE:
PARAMETERS: In:
RETURNS: D3DM_DRIVER_HANDLED || D3DM_DRIVER_NOTHANDLED
</function>
------------------------------------------------------------------------------*/
DWORD PVRD3DM_DestroySurface(D3DM_DESTROYSURFACE_DATA *pdsd)
{
D3DMRESOURCETYPE eType = ((LPD3DM_SURFACE)pdsd->nSurfaceId)->eSurfaceType;
switch(eType)
{
case D3DMRTYPE_FRONTBUFFER:
{
DestroyFrontBuffer(pdsd);
break;
}
case D3DMRTYPE_BACKBUFFER:
{
DestroyBackBuffer(pdsd);
break;
}
case D3DMRTYPE_SURFACE:
{
DestroySurface(pdsd);
break;
}
case D3DMRTYPE_TEXTURE:
{
DestroyTexture(pdsd);
break;
}
case D3DMRTYPE_DEPTHSTENCIL:
{
DestroyDepthBuffer(pdsd);
break;
}
case D3DMRTYPE_VERTEXBUFFER:
{
DestroyVBuffer(pdsd);
break;
}
case D3DMRTYPE_INDEXBUFFER:
{
DestroyIBuffer(pdsd);
break;
}
default:
{
D3DM_DPF((DPF_WARN, "PVRD3DM_DestroySurface:Invalid surface type (%u), (DWORD) eType"));
pdsd->rval = D3DMERR_INVALIDCALL;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -