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

📄 blit.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
		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 + -