📄 halblit.c
字号:
PURPOSE : Write blit data to the 2D hardware.
PARAMETERS : DWORD dwHeader - Block header
DWORD dwFillColor - Fill colour
PRECTL psRect - Destination surface dimensions
RETURNS : void
<function/>
*****************************************************************************/
void WriteBlitBlock(DWORD dwHeader, DWORD dwFillColor, PRECTL psRect, ULONG **ppuCmd)
{
DWORD dwDstXStart = 0;
DWORD dwDstXEnd = 0;
DWORD dwDstYStart = 0;
DWORD dwDstYEnd = 0;
//// PDUMPSTRING(GetDriverData(NULL)->psPDContext, "-- Blit Command");
// Write block header.
*(*ppuCmd)++ = dwHeader;
// Write the fill colour if MBX2D_USE_FILL is specified.
// ??? Check format of this - should be same as dest ???
if ((dwHeader & MBX2D_PAT_MASK) == MBX2D_USE_FILL)
{
*(*ppuCmd)++ = dwFillColor;
}
// Build the destination size control words.
// For each word, cast it to SHORT (maintaining sign), shift appropriately,
// then mask out unnecessary bits.
dwDstXStart = (((SHORT)psRect->left ) << MBX2D_DST_XSTART_SHIFT) & MBX2D_DST_XSTART_MASK;
dwDstYStart = (((SHORT)psRect->top ) << MBX2D_DST_YSTART_SHIFT) & MBX2D_DST_YSTART_MASK;
dwDstXEnd = (((SHORT)psRect->right ) << MBX2D_DST_XEND_SHIFT ) & MBX2D_DST_XEND_MASK;
dwDstYEnd = (((SHORT)psRect->bottom) << MBX2D_DST_YEND_SHIFT ) & MBX2D_DST_YEND_MASK;
// Write the Dst control words.
*(*ppuCmd)++ = dwDstXStart | dwDstYStart;
*(*ppuCmd)++ = dwDstXEnd | dwDstYEnd;
}
/*****************************************************************************
<function>
FUNCTION : WriteClipBlock
PURPOSE : Write clip data to the 2D hardware.
PARAMETERS : DWORD dwRectCnt - Number of clip rectangles
PRECTL prDestRects - List of clip rectangles
RETURNS : void
<function/>
*****************************************************************************/
void WriteClipBlock(DWORD dwRectCnt, LPRECT prDestRects, ULONG **ppuCmd)
{
DWORD dwClipCount = (dwRectCnt << MBX2D_CLIPCOUNT_SHIFT) & MBX2D_CLIPCOUNT_MASK;
DWORD i = 0;
//// PDUMPSTRING(GetDriverData(NULL)->psPDContext, "-- Clipping Setup");
// Hardware only supports 4 rectangles.
// TODO: split blit up if >4 clip rectangles.
ASSERT(dwRectCnt <= 4);
// Write block header.
*(*ppuCmd)++ = MBX2D_CLIP_BH | dwClipCount;
// Write each clip rectangle.
for(i = 0; i < dwRectCnt; i++, prDestRects++)
{
// ??Need to check for massive clips???
DWORD dwClipXMax = ((SHORT)prDestRects->right << MBX2D_CLIP_XMAX_SHIFT) & MBX2D_CLIP_XMAX_MASK;
DWORD dwClipXMin = ((SHORT)prDestRects->left << MBX2D_CLIP_XMIN_SHIFT) & MBX2D_CLIP_XMIN_MASK;
DWORD dwClipYMax = ((SHORT)prDestRects->bottom << MBX2D_CLIP_YMAX_SHIFT) & MBX2D_CLIP_YMAX_MASK;
DWORD dwClipYMin = ((SHORT)prDestRects->top << MBX2D_CLIP_YMIN_SHIFT) & MBX2D_CLIP_YMIN_MASK;
*(*ppuCmd)++ = dwClipXMax | dwClipXMin;
*(*ppuCmd)++ = dwClipYMax | dwClipYMin;
}
}
/*****************************************************************************
<function>
FUNCTION : WriteDwordBlitBlock
PURPOSE : Write dword blit data to the 2D hardware.
A dword blit writes a 32 bit value into framebuffer using a
1 pixel ARGB colourfill blit.
PARAMETERS : DWORD dwPhysAddress - Physical address to blit dword to
DWORD dwValue - Value
RETURNS : void
<function/>
*****************************************************************************/
void WriteDwordBlitBlock(DWORD dwPhysAddress, DWORD dwValue, ULONG **ppuCmd)
{
// ARGB dest surface starting at dwAddress.
//// PDUMPSTRING(GetDriverData(NULL)->psPDContext, "-- Dword Dest Command");
*(*ppuCmd)++ = MBX2D_DST_CTRL_BH | MBX2D_DST_8888ARGB;
*(*ppuCmd)++ = ((dwPhysAddress
>> MBX2D_DST_ADDR_ALIGNSHIFT)
<< MBX2D_DST_ADDR_SHIFT)
& MBX2D_DST_ADDR_MASK;
// 1 pixel colourfill blit using dwValue for colour.
//// PDUMPSTRING(GetDriverData(NULL)->psPDContext, "-- Dword Blit Command");
*(*ppuCmd)++ = MBX2D_BLIT_BH | MBX2D_USE_FILL | MBX2D_ROP3_PATCOPY;
*(*ppuCmd)++ = dwValue;
*(*ppuCmd)++ = 0;
*(*ppuCmd)++ = (1 << MBX2D_DST_XEND_SHIFT) | (1 << MBX2D_DST_YEND_SHIFT);
}
/*****************************************************************************
<function>
FUNCTION : HardwareDDBlt
PURPOSE : Called on DirectDraw Blit if hardware flag is on
PARAMETERS : psBlitData -
RETURNS : DDHAL return code.
<function/>
*****************************************************************************/
DWORD __stdcall HardwareDDBlt(LPDDHAL_BLTDATA psBlitData,
PSURFDATA psSrcData,
PSURFDATA psDestData)
{
DWORD dwResult = DDHAL_DRIVER_HANDLED;
DWORD dwFlags = psBlitData->dwFlags;
// Hardware control flags (and local flags).
DWORD dwHeader = 0;
DWORD dwClipEnable = 0;
DWORD dwCopyOrder = MBX2D_TEXTCOPY_TL2BR;
DWORD dwPatternControl = MBX2D_USE_PAT;
DWORD dwROP = MBX2D_ROP3_PATCOPY;
DWORD dwRotation = MBX2D_TEXTROT_NONE;
DWORD dw2DDataPresent = 0;
DWORD dwColorKeyType = ColorKeyNone;
DWORD dwDstCKControl = MBX2D_DSTCK_DISABLE;
DWORD dwSrcCKControl = MBX2D_SRCCK_DISABLE;
DWORD dwAlphaControl = 0;
// Colours.
DWORD dwDstCKValue = 0;
DWORD dwSrcCKValue = 0;
DWORD dwFillColor = 0; // Could set to 'that pink' to throw up errors...
DWORD dwAlphaConst = 0;
/* Command buffer stuff */
DWORD dwDataSize = 0;
DWORD dwBytesObtained = 0;
DWORD *pdwCmd = NULL;
/* Driver structs */
PVRSRV_QUEUE_INFO *psQueue;
PVRSRV_DEV_INFO *psDevInfo;
IMG_UINT32 i = 0;
IMG_BOOL bStart = IMG_FALSE, bTimeout = IMG_TRUE;
IMG_UINT32 uiStart = 0;
RECT sRDst;
sRDst.left = psBlitData->rDest.left;
sRDst.right = psBlitData->rDest.right;
sRDst.top = psBlitData->rDest.top;
sRDst.bottom = psBlitData->rDest.bottom;
/* Queue all blits to the Hal queue object */
psQueue = gpsDriverData->psDDQueueInfo;
psDevInfo = gpsDriverData->sDisplayDevData.psDevInfoKM;
/* Flush flips */
do
{
if((psDestData->psMemInfo->psSyncInfo->ui32ReadOpsComplete ==
psDestData->psMemInfo->psSyncInfo->ui32ReadOpsPending) &&
(*psDestData->psMemInfo->psSyncInfo->pui32LastWriteOp ==
psDestData->psMemInfo->psSyncInfo->ui32NextWriteOp -1))
{
bTimeout = IMG_FALSE;
break;
}
if (bStart == IMG_FALSE)
{
bStart = IMG_TRUE;
uiStart = HostClockus();
}
SysKickCmdProc(psDevInfo->pui32KickerAddrKM);
HostWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
i++;
} while ((HostClockus() - uiStart) < MAX_HW_TIME_US);
if(bTimeout)
{
psBlitData->ddRVal = DDERR_WASSTILLDRAWING;
return DDHAL_DRIVER_NOTHANDLED;
}
/*
Punt the blit if either surface is in system memory.
NB: sysmem blits are not capped, so shouldn't get any here.
*/
ASSERT(!(psDestData->dwDDSCaps & DDSCAPS_SYSTEMMEMORY));
if (psSrcData) ASSERT(!(psSrcData->dwDDSCaps & DDSCAPS_SYSTEMMEMORY));
/*
At present, only RGB surfaces are supported. Haven't looked at caps for
this yet.
*/
if (
(GetPixelFormatType(psDestData->dwMBXFormat) != MBXDD_PIXELFORMAT_RGB) ||
(psSrcData && (GetPixelFormatType(psSrcData->dwMBXFormat) != MBXDD_PIXELFORMAT_RGB))
)
{
psBlitData->ddRVal = DDERR_UNSUPPORTED;
return DDHAL_DRIVER_NOTHANDLED;
}
/*
Clipped blits with zero inclusion rectangles MUST be ignored.
*/
if (psBlitData->IsClipped && (psBlitData->dwRectCnt == 0))
{
return DDHAL_DRIVER_HANDLED;
}
/*
Build up hardware control parameters
*/
// Clipping.
if (psBlitData->IsClipped) dwClipEnable = MBX2D_CLIP_ENABLE;
// Attempt to handle all supplied flags. This code should produce DWORDS
// ready to be OR'ed together. There are a few assumptions here about how
// DirectDraw works, where possible I've used ASSERT to check these.
if(psBlitData->dwAFlags & DDABLT_SRCOVERDEST)
{
/* This call originates from AlphaBlt */
/* Flag Alpha blit in 2D Control block */
dw2DDataPresent |= MBX2D_ALPHA_CTRL;
dwAlphaControl |= MBX2D_ALPHA_ENABLE;
if(psBlitData->ddargbScaleFactors.alpha != 0xFF)
{
dwAlphaConst = psBlitData->ddargbScaleFactors.alpha;
}
}
if (dwFlags & DDBLT_ASYNC)
{
// Do this blit asynchronously through the FIFO in the order received.
// If no room exists in the hardware FIFO, fail the call. Drivers
// should ignore this flag and always schedule blits asynchronously
// whenever possible.
// Ignore quietly.
}
if (dwFlags & DDBLT_COLORFILL)
{
// Uses the dwFillColor member in the DDBLTFX structure as the RGB
// color with which to fill the destination rectangle on the
// destination surface.
dwPatternControl = MBX2D_USE_FILL;
dwFillColor = psBlitData->bltFX.dwFillColor;
// Need to set ROP to PATCOPY. Check this will not be overwritten
// by another ROP command.
dwROP = MBX2D_ROP3_PATCOPY;
ASSERT(! (dwFlags & DDBLT_ROP));
}
if (dwFlags & DDBLT_DDFX)
{
// Uses the dwDDFX member in the DDBLTFX structure to specify the
// effects to use for the blit.
DWORD dwDDFX = psBlitData->bltFX.dwDDFX;
// We only support the blt rotation parameters.
if (dwDDFX & DDBLTFX_ROTATE90) dwRotation = MBX2D_TEXTROT_90DEGS;
else if (dwDDFX & DDBLTFX_ROTATE180) dwRotation = MBX2D_TEXTROT_180DEGS;
else if (dwDDFX & DDBLTFX_ROTATE270) dwRotation = MBX2D_TEXTROT_270DEGS;
/* We need to tweak the dest rect in 90 and 270 to get the correct effect */
switch(dwRotation)
{
case MBX2D_TEXTROT_90DEGS:
case MBX2D_TEXTROT_270DEGS:
{
sRDst.top = psBlitData->rDest.left;
sRDst.left = psBlitData->rDest.top;
sRDst.bottom = psBlitData->rDest.right;
sRDst.right = psBlitData->rDest.bottom;
break;
}
}
}
if (dwFlags & DDBLT_DDROPS)
{
// Uses the dwDDROPS member in the DDBLTFX structure to specify the
// raster operations that are not part of the Microsoft Win32
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -