📄 blit.c
字号:
ui32Height = ui32Tmp;
}
if(ui32Width > psDestSurface->psContext->psPrimSurfData->ui32PixelWidth ||
ui32Height > psDestSurface->psContext->psPrimSurfData->ui32PixelHeight)
{
/* Unsupported Dest format - Punt to 2D */
return FALSE;
}
if(!GetFBFormatFromD3DMFormat(psDestSurface->eFormat, &ui32FBFormat))
{
/* Unsupported Dest format - Punt to 2D */
return FALSE;
}
s3DParams.psDstSyncInfoKM = psDestSurface->psMemInfo->psSyncInfo->psKernSyncInfo;
s3DParams.sDstDevVAddr.uiAddr = psDestSurface->psMemInfo->uiDevAddr.uiAddr;
s3DParams.ui32DstStride = psDestSurface->dwStrideByte;
s3DParams.ui32DstPixFormat = ui32FBFormat;
s3DParams.sDstRect = *(IMG_RECT*)psDestRect;
s3DParams.bUpdatePrimary = IMG_TRUE;
s3DParams.ui32SourceRotation = dwSourceRotationAngle;
/* Set up BGO for 3D Blit */
SetupBGO(&s3DParams.sBGObject, psDestSurface);
if(psSourceSurface != IMG_NULL)
{
PVR_DEVFORMAT* psFormat = GetFormatDescriptorD3DM(psSourceSurface->psContext, psSourceSurface->eFormat);
if(psFormat == NULL)
{
/* Unsupported Source format - Punt to 2D */
return FALSE;
}
s3DParams.psSrcSyncInfoKM = psSourceSurface->psMemInfo->psSyncInfo->psKernSyncInfo;
s3DParams.sSrcDevVAddr.uiAddr = psSourceSurface->psMemInfo->uiDevAddr.uiAddr;
s3DParams.ui32SrcStride = psSourceSurface->dwStrideByte;
s3DParams.ui32SrcPixFormat = psFormat->dwPVRHWFormat;
s3DParams.sSrcRect = *(IMG_RECT*)psSourceRect;
if(psSourceSurface->eSurfaceType == D3DMRTYPE_TEXTURE)
{
s3DParams.ui32SrcWidth = psSourceSurface->sDescription.sTexture.dwScaledWidth;
s3DParams.ui32SrcHeight = psSourceSurface->sDescription.sTexture.dwScaledHeight;
}
else
{
s3DParams.ui32SrcWidth = psSourceSurface->dwWidth;
s3DParams.ui32SrcHeight = psSourceSurface->dwHeight;
}
s3DParams.bColourFill = IMG_FALSE;
if(psSourceSurface->dwFlags & D3DM_SURFACE_FLAGS_TWIDDLED)
{
s3DParams.bSourceTwiddled = IMG_TRUE;
}
else
{
s3DParams.bSourceTwiddled = IMG_FALSE;
}
}
else
{
s3DParams.bColourFill = IMG_TRUE;
s3DParams.ui32ColourFillColour = dwFillColour;
}
/* Filter control */
if(Filter == D3DMTEXF_LINEAR)
{
s3DParams.bFilter = IMG_TRUE;
}
else
{
s3DParams.bFilter = IMG_FALSE;
}
/* Sampling control */
s3DParams.bD3DPixelSampling = IMG_TRUE;
/* CLIP details */
s3DParams.ui32NumClipRects = dwNumClipRects;
s3DParams.psClipRect = (IMG_RECT*) psClipRects;
if (PVRSRVSetup3Dblit(psDestSurface->psContext->psContextQueue,
GetDevInfo(psDestSurface->psContext),
&psDestSurface->psContext->sHWInfo,
&s3DParams )!= PVRSRV_OK)
{
D3DM_DPF((DPF_ERROR, "HardwareBlit:Couldn't queue the render blit. Punting Blit"));
return FALSE;
}
/* Dest Surface is no longer twiddled (if it was) */
psDestSurface->dwFlags &= ~D3DM_SURFACE_FLAGS_TWIDDLED;
PROFILE_STOP_FUNC(HARDWARE_3D_BLIT);
return TRUE;
#else
return FALSE;
#endif
}
/*----------------------------------------------------------------------------
<function>
FUNCTION : Hardware2DBlit
PURPOSE : Performs hardware blits using the 3D hardware if possible
PARAMETERS :
RETURNS : DDHAL return code.
</function>
------------------------------------------------------------------------------*/
BOOL Hardware2DBlit(LPD3DM_SURFACE psSourceSurface,
RECT *psSourceRect,
LPD3DM_SURFACE psDestSurface,
RECT *psDestRect,
D3DMTEXTUREFILTERTYPE Filter,
DWORD dwFillColour,
RECT *psClipRects,
DWORD dwNumClipRects,
DWORD dwRotationAngle)
{
DWORD dwPatternControl = 0;
DWORD dwHeader = 0;
DWORD dwClipEnable = 0;
DWORD dwCopyOrder = MBX2D_TEXTCOPY_TL2BR;
DWORD dwROP = MBX2D_ROP3_SRCCOPY;
DWORD dwDataSize = 0;
DWORD *pdwCmd = NULL;
DWORD *pdwCmdBase = NULL;
DWORD dwRotation = MBX2D_TEXTROT_NONE;
LPD3DM_CONTEXT psContext;
RECT sRDst;
PROFILE_START_FUNC(HARDWARE_2D_BLIT);
switch(dwRotationAngle)
{
case 0:
{
sRDst = *psDestRect;
break;
}
case 90:
{
dwRotation = MBX2D_TEXTROT_270DEGS;
sRDst.top = psDestRect->left;
sRDst.left = psDestRect->top;
sRDst.bottom = psDestRect->right;
sRDst.right = psDestRect->bottom;
break;
}
case 270:
{
dwRotation = MBX2D_TEXTROT_90DEGS;
sRDst.top = psDestRect->left;
sRDst.left = psDestRect->top;
sRDst.bottom = psDestRect->right;
sRDst.right = psDestRect->bottom;
break;
}
case 180:
{
dwRotation = MBX2D_TEXTROT_180DEGS;
sRDst = *psDestRect;
break;
}
}
psContext = psDestSurface->psContext;
PDUMPSTRING(psContext->psPDContext, "-- Using HardwareBlit");
if(Filter == D3DMTEXF_LINEAR) return FALSE;
/* Create command buffer */
pdwCmdBase = D3DMAllocate(MAX_BLT_SIZE * sizeof(DWORD));
if(pdwCmdBase == NULL)
{
return FALSE;
}
/* Copy Base pointer to temp pointer */
pdwCmd = pdwCmdBase;
/* Clipping */
if(dwNumClipRects > 0) dwClipEnable = MBX2D_CLIP_ENABLE;
/* Fill in the destination surface data */
if(!WriteDstSurf(psDestSurface, &pdwCmd))
{
/* Unsupported format - punt to software */
D3DMFree(pdwCmdBase);
return FALSE;
}
if(psSourceSurface == NULL)
{
/* ColourFill blit */
dwFillColour = ConvertFillColourToHWFormat(psDestSurface->eFormat, dwFillColour);
dwPatternControl = MBX2D_USE_FILL;
dwROP = MBX2D_ROP3_PATCOPY;
}
else
{
DWORD dwSourceMapLevel, dwDestMapLevel;
BOOL bTexToTex = FALSE, bSourceEqualsDest = FALSE;
if((psSourceSurface->eSurfaceType == D3DMRTYPE_TEXTURE) &&
(psDestSurface->eSurfaceType == D3DMRTYPE_TEXTURE))
{
bTexToTex = TRUE;
dwSourceMapLevel = psSourceSurface->sDescription.sTexture.dwMipMapLevel;
dwDestMapLevel = psDestSurface->sDescription.sTexture.dwMipMapLevel;
}
if(psSourceSurface->psMemInfo->uiDevAddr.uiAddr == psDestSurface->psMemInfo->uiDevAddr.uiAddr)
{
bSourceEqualsDest = TRUE;
}
/*
Get the texture copy order if this is a texture, the source and dest meminfo
is the same and the source and dest mipmap levels are the same OR if this isn't
a texture and the source and dest meminfo is the same
*/
if((bTexToTex && bSourceEqualsDest && (dwDestMapLevel == dwSourceMapLevel)) ||
(!bTexToTex && bSourceEqualsDest))
{
dwCopyOrder = GetTextureCopyOrder(psSourceRect, &sRDst);
}
if(!WriteSrcSurf(psSourceSurface, psSourceRect, &pdwCmd))
{
/* Unsupported format - punt to software */
D3DMFree(pdwCmdBase);
return FALSE;
}
if(dwRotation == 0 || dwRotation == 180)
{
/* Write the stretch block */
if (!WriteStretchBlock(psSourceRect, &sRDst, &pdwCmd))
{
/* Couldn't handle the stretch. Free the command buffer and punt the blit */
D3DMFree(pdwCmdBase);
return FALSE;
}
}
else
{
/* No stretch */
*pdwCmd++ = MBX2D_STRETCH_BH
| (MBX2D_NO_STRETCH << MBX2D_X_STRETCH_SHIFT)
| (MBX2D_NO_STRETCH << MBX2D_Y_STRETCH_SHIFT);
}
}
/* Build the block header */
dwHeader = MBX2D_BLIT_BH // Object type
| dwRotation // Rotation
| dwCopyOrder // Texture copy order
| dwClipEnable // Clipping
| dwPatternControl // Pattern
| dwROP; // ROP codes
if(dwClipEnable)
{
/*
If we have more than 4 clip rectangles, break the blit into
smaller blits of 4 clip rectangles each
*/
DWORD dwRemainingRectCnt = dwNumClipRects;
LPRECT psCurrentDestRect = psClipRects;
while(dwRemainingRectCnt > 0)
{
DWORD dwBltRectCnt = min(dwRemainingRectCnt, 4);
WriteClipBlock(dwBltRectCnt, psCurrentDestRect, &pdwCmd);
WriteBlitBlock(dwHeader, dwFillColour, &sRDst, &pdwCmd);
dwRemainingRectCnt -= dwBltRectCnt;
psCurrentDestRect += 4;
}
}
else
{
/* Write the blit block */
WriteBlitBlock(dwHeader, dwFillColour, &sRDst, &pdwCmd);
}
/* Calculate used buffer size */
dwDataSize = (DWORD) (pdwCmd - pdwCmdBase);
/* Queue the blit */
if(PVRSRVQueueBlt(psContext->psContextQueue,
psDestSurface->psMemInfo->psSyncInfo,
(psSourceSurface) ? 1 : 0,
(psSourceSurface) ? &psSourceSurface->psMemInfo->psSyncInfo : NULL,
dwDataSize,
pdwCmdBase)!= PVRSRV_OK)
{
D3DM_DPF((DPF_ERROR, "HardwareBlit:Couldn't queue the blit. Punting to software"));
D3DMFree(pdwCmdBase);
return FALSE;
}
/* Free up Instruction buffer */
D3DMFree(pdwCmdBase);
PROFILE_STOP_FUNC(HARDWARE_2D_BLIT);
return TRUE;
}
/*----------------------------------------------------------------------------
<function>
FUNCTION : TwiddleCopy
PURPOSE : Performs copy blit between Twiddled textures
</function>
------------------------------------------------------------------------------*/
void TwiddleCopy(LPD3DM_SURFACE psSourceSurface,
LPD3DM_SURFACE psDestSurface)
{
DWORD dwSourceFmt, dwDestFmt;
DWORD dwCommandPacket[10];
DWORD dwSourceAddress = ((DWORD) psSourceSurface->psMemInfo->uiDevAddr.uiAddr) +
psSourceSurface->sDescription.sTexture.dwLevelOffset;
DWORD dwDestAddress = ((DWORD) psDestSurface->psMemInfo->uiDevAddr.uiAddr) +
psDestSurface->sDescription.sTexture.dwLevelOffset;
PROFILE_START_FUNC(TWIDDLE_COPY);
switch(psSourceSurface->dwBpp)
{
case 8:
{
dwSourceFmt = MBX2D_SRC_332RGB;
break;
}
case 16:
{
dwSourceFmt = MBX2D_SRC_4444ARGB;
break;
}
case 32:
{
dwSourceFmt = MBX2D_SRC_8888ARGB;
break;
}
}
switch(psDestSurface->dwBpp)
{
case 8:
{
dwDestFmt = MBX2D_SRC_332RGB;
break;
}
case 16:
{
dwDestFmt = MBX2D_SRC_4444ARGB;
break;
}
case 32:
{
dwDestFmt = MBX2D_SRC_8888ARGB;
break;
}
}
dwCommandPacket[0] = MBX2D_DST_CTRL_BH
| dwDestFmt
| ((psDestSurface->dwStrideByte
<< MBX2D_DST_STRIDE_SHIFT)
& MBX2D_DST_STRIDE_MASK);
dwCommandPacket[1] = ((dwDestAddress
>> MBX2D_DST_ADDR_ALIGNSHIFT)
<< MBX2D_DST_ADDR_SHIFT)
& MBX2D_DST_ADDR_MASK;
dwCommandPacket[2] = MBX2D_SRC_CTRL_BH
| MBX2D_SRC_FBMEM
| dwSourceFmt
| ((psSourceSurface->dwStrideByte
<< MBX2D_SRC_STRIDE_SHIFT)
& MBX2D_SRC_STRIDE_MASK);
dwCommandPacket[3] = (( dwSourceAddress
>> MBX2D_SRC_ADDR_ALIGNSHIFT)
<< MBX2D_SRC_ADDR_SHIFT)
& MBX2D_SRC_ADDR_MASK;
/* Write the starting pixel coordinate */
dwCommandPacket[4] = MBX2D_SRC_OFF_BH
| ((0 << MBX2D_SRCOFF_XSTART_SHIFT) & MBX2D_SRCOFF_XSTART_MASK)
| ((0 << MBX2D_SRCOFF_YSTART_SHIFT) & MBX2D_SRCOFF_YSTART_MASK);
dwCommandPacket[5] = MBX2D_STRETCH_BH
| (MBX2D_NO_STRETCH<<MBX2D_X_STRETCH_SHIFT)
| (MBX2D_NO_STRETCH<<MBX2D_Y_STRETCH_SHIFT);
dwCommandPacket[6] = MBX2D_BLIT_BH | MBX2D_ROP3_SRCCOPY;
dwCommandPacket[7] = 0;/* colour */
dwCommandPacket[8] = 0;/* Starting point */
dwCommandPacket[9] = (psDestSurface->dwStridePixel << MBX2D_DST_XEND_SHIFT)
| (psDestSurface->sDescription.sTexture.dwScaledHeight << MBX2D_DST_YEND_SHIFT);
/* Queue the blit */
if(PVRSRVQueueBlt( psSourceSurface->psContext->psContextQueue,
psDestSurface->psMemInfo->psSyncInfo,
1,
&psSourceSurface->psMemInfo->psSyncInfo ,
10,
dwCommandPacket)!= PVRSRV_OK)
{
D3DM_DPF((DPF_ERROR, "TwiddleCopy:Couldn't queue the blit. Failing"));
psSourceSurface->psContext->hrLastError = D3DMERR_DRIVERINTERNALERROR;
return;
}
psDestSurface->dwFlags |= D3DM_SURFACE_FLAGS_TWIDDLED;
}
/*----------------------------------------------------------------------------
<function>
FUNCTION : PVRTCCopy
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -