/************************************************************************** *************************************************************************** * * Copyright (c) 1996, Cirrus Logic, Inc. * All Rights Reserved * * FILE: blt_dl.c * * DESCRIPTION: Display List blts for the 5464 * * REVISION HISTORY: * * $Log: X:\log\laguna\ddraw\src\blt_dl.c $ * * Rev 1.20 06 Jan 1998 15:20:04 xcong * * Rev 1.19 06 Jan 1998 11:56:22 xcong * Change pDriverData into lpDDHALData for multi-monitor support. * * Rev 1.18 03 Oct 1997 14:31:12 RUSSL * Initial changes for use of hw clipped blts * All changes wrapped in #if ENABLE_CLIPPEDBLTS/#endif blocks and * ENABLE_CLIPPEDBLTS defaults to 0 (so the code is disabled) * * Rev 1.17 15 Sep 1997 17:25:14 RUSSL * Fix for PDR 10493 - Minor parenthesis change * * Rev 1.16 24 Jul 1997 12:32:40 RUSSL * Botched the overlap check, changed || to && * * Rev 1.15 24 Jul 1997 11:20:16 RUSSL * Added DL_DrvStrBlt_OverlapCheck & DL_DrvStrMBlt_OverlapCheck * inline functions * * Rev 1.14 17 Jul 1997 14:31:58 RUSSL * Fixed my copy & paste errors in the DD_LOG and ASSERTs in DL_DrvStrBlt65 * * Rev 1.13 15 Jul 1997 16:19:50 eleland * removed the increment-and-immediate decrement of display list * pointer at the end of each blt display list * * Rev 1.12 14 Jul 1997 14:59:52 RUSSL * Added DL_DrvStrBlt65 * * Rev 1.11 02 Jul 1997 19:13:10 eleland * added wait instruction after each dl blit * * Rev 1.10 03 Apr 1997 15:05:30 RUSSL * Added DL_DrvDstMBlt function * * Rev 1.9 26 Mar 1997 13:55:22 RUSSL * Added DL_DrvSrcMBlt function * * Rev 1.8 12 Mar 1997 15:01:20 RUSSL * replaced a block of includes with include of precomp.h for * precompiled headers * * Rev 1.7 07 Mar 1997 12:50:40 RUSSL * Modified DDRAW_COMPAT usage * * Rev 1.6 11 Feb 1997 11:40:34 bennyn * Fixed the compiling error for NT * * Rev 1.5 07 Feb 1997 16:30:34 KENTL * Never mind the #ifdefs. The problems are deeper than that. We'd need * ifdefs around half the code in the file. * * Rev 1.4 07 Feb 1997 16:18:58 KENTL * Addd #ifdef's around include qmgr.h * * Rev 1.3 07 Feb 1997 13:22:36 KENTL * Merged in Evan Leland's modifications to get Display List mode working: * * include qmgr.h * * Invoke qmAllocDisplayList to get pDisplayList pointer. * * Invoke qmExecuteDisplayList on completed DL's * * Rev 1.2 23 Jan 1997 17:08:48 bennyn * Modified naming of registers * * Rev 1.1 25 Nov 1996 16:15:48 bennyn * Fixed misc compiling error for NT * * Rev 1.0 25 Nov 1996 15:14:02 RUSSL * Initial revision. * * Rev 1.2 18 Nov 1996 16:18:56 RUSSL * Added file logging for DDraw entry points and register writes * * Rev 1.1 01 Nov 1996 13:08:40 RUSSL * Merge WIN95 & WINNT code for Blt32 * * Rev 1.0 01 Nov 1996 09:28:02 BENNYN * Initial revision. * * Rev 1.0 25 Oct 1996 11:08:22 RUSSL * Initial revision. * *************************************************************************** ***************************************************************************/ /*************************************************************************** * I N C L U D E S ****************************************************************************/ #include "precomp.h" // If WinNT 3.5 skip all the source code #if defined WINNT_VER35 // WINNT_VER35 #else // !WINNT_VER35 #ifdef WINNT_VER40 // WINNT_VER40 #define DBGLVL 1 #define AFPRINTF(n) #else // !WINNT_VER40 #include "l3system.h" #include "l2d.h" #include "bltP.h" #include "qmgr.h" #endif // !WINNT_VER40 /*************************************************************************** * S T A T I C V A R I A B L E S ****************************************************************************/ #ifndef WINNT_VER40 ASSERTFILE("blt_dl.c"); #endif /*************************************************************************** * * FUNCTION: DL_Delay9BitBlt * * DESCRIPTION: * ****************************************************************************/ void DL_Delay9BitBlt ( #ifdef WINNT_VER40 PDEV *ppdev, DRIVERDATA *lpDDHALData, #else LPGLOBALDATA lpDDHALData, #endif BOOL ninebit_on ) { #ifdef WINNT_VER40 // WINNT_VER40 #else // !WINNT_VER40 DWORD *pDisplayList; qm_return rc; QMDLHandle Handle; DD_LOG(("DL_Delay9BitBlt\r\n")); /* This is to ensure that the last packet of any previous blt */ /* does no go out with 9th bit set incorrectly */ /* The boolean paramter is the 9th bit of the PREVIOUS BLT */ rc = qmAllocDisplayList(8*4, QM_DL_UNLOCKED, &Handle, &pDisplayList); *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 4, 0); // BLTDEF & DRAWDEF *pDisplayList++ = (C_BLTDEF << 16) | ((BD_RES + BD_OP0 + BD_OP1 + BD_OP2)*IS_VRAM); if (ninebit_on) *pDisplayList++ = (C_DRWDEF << 16) | (DD_PTAG | ROP_OP0_copy); else *pDisplayList++ = (C_DRWDEF << 16) | ROP_OP0_copy; // OP0_RDRAM *pDisplayList++ = (C_RX_0 << 16) | LOWORD(lpDDHALData->PTAGFooPixel); *pDisplayList++ = (C_RY_0 << 16) | HIWORD(lpDDHALData->PTAGFooPixel); // BLTEXT_EX *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_BLTEXT_EX, 1, 0); *pDisplayList++ = MAKELONG(1,1); *pDisplayList = wait_3d(0x3e0, 0); rc = qmExecuteDisplayList(Handle, pDisplayList, 0); #endif // !WINNT_VER40 } /* DL_Delay9BitBlt */ /*************************************************************************** * * FUNCTION: DL_EdgeFillBlt * * DESCRIPTION: Solid Fill BLT to fill in edges ( Pixel Coords / Extents ) * ****************************************************************************/ void DL_EdgeFillBlt ( #ifdef WINNT_VER40 PDEV *ppdev, DRIVERDATA *lpDDHALData, #else LPGLOBALDATA lpDDHALData, #endif int xFill, int yFill, int cxFill, int cyFill, DWORD FillValue, BOOL ninebit_on ) { #ifdef WINNT_VER40 // WINNT_VER40 #else // !WINNT_VER40 DWORD *pDisplayList; qm_return rc; QMDLHandle Handle; DD_LOG(("DL_EdgeFillBlt - dst=%08lX ext=%08lX color=%08lX\r\n", MAKELONG(xFill,yFill),MAKELONG(cxFill,cyFill),FillValue)); rc = qmAllocDisplayList(10*4, QM_DL_UNLOCKED, &Handle, &pDisplayList); *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 6, 0); // BLTDEF & DRAWDEF *pDisplayList++ = (C_BLTDEF << 16) | (BD_RES * IS_VRAM + BD_OP1 * IS_SOLID); if (ninebit_on) *pDisplayList++ = (C_DRWDEF << 16) | (DD_PTAG | ROP_OP1_copy); else *pDisplayList++ = (C_DRWDEF << 16) | ROP_OP1_copy; // BGCOLOR *pDisplayList++ = (C_BG_L << 16) | LOWORD(FillValue); *pDisplayList++ = (C_BG_H << 16) | HIWORD(FillValue); // OP0_opRDRAM *pDisplayList++ = (C_RX_0 << 16) | LOWORD(xFill); *pDisplayList++ = (C_RY_0 << 16) | LOWORD(yFill); // BLTEXT_EX *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_BLTEXT_EX, 1, 0); *pDisplayList++ = MAKELONG(LOWORD(cxFill),LOWORD(cyFill)); *pDisplayList = wait_3d(0x3e0, 0); rc = qmExecuteDisplayList(Handle, pDisplayList, 0); #endif // !WINNT_VER40 } /* DL_EdgeFillBlt */ /*************************************************************************** * * FUNCTION: DL_MEdgeFillBlt * * DESCRIPTION: Using BYTE BLT coords / Extents perform EdgeFill BLT * ****************************************************************************/ void DL_MEdgeFillBlt ( #ifdef WINNT_VER40 PDEV *ppdev, DRIVERDATA *lpDDHALData, #else LPGLOBALDATA lpDDHALData, #endif int xFill, int yFill, int cxFill, int cyFill, DWORD FillValue, BOOL ninebit_on ) { #ifdef WINNT_VER40 // WINNT_VER40 #else // !WINNT_VER40 DWORD *pDisplayList; qm_return rc; QMDLHandle Handle; DD_LOG(("DL_MEdgeFillBlt - dst=%08lX ext=%08lX color=%08lX\r\n", MAKELONG(xFill,yFill),MAKELONG(cxFill,cyFill),FillValue)); rc = qmAllocDisplayList(10*4, QM_DL_UNLOCKED, &Handle, &pDisplayList); *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 6, 0); // BLTDEF & DRAWDEF *pDisplayList++ = (C_BLTDEF << 16) | (BD_RES * IS_VRAM + BD_OP1 * IS_SOLID); if (ninebit_on) *pDisplayList++ = (C_DRWDEF << 16) | (DD_PTAG | ROP_OP1_copy); else *pDisplayList++ = (C_DRWDEF << 16) | ROP_OP1_copy; // BGCOLOR *pDisplayList++ = (C_BG_L << 16) | LOWORD(FillValue); *pDisplayList++ = (C_BG_H << 16) | HIWORD(FillValue); // OP0_opMRDRAM *pDisplayList++ = (C_MRX_0 << 16) | LOWORD(xFill); *pDisplayList++ = (C_MRY_0 << 16) | LOWORD(yFill); // MBLTEXT_EX *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_MBLTEXT_EX, 1, 0); *pDisplayList++ = MAKELONG(LOWORD(cxFill),LOWORD(cyFill)); *pDisplayList = wait_3d(0x3e0, 0); rc = qmExecuteDisplayList(Handle, pDisplayList, 0); #endif // !WINNT_VER40 } /* DL_EdgeFillBlt */ /*************************************************************************** * * FUNCTION: DL_DrvDstBlt * * DESCRIPTION: * ****************************************************************************/ void DL_DrvDstBlt ( #ifdef WINNT_VER40 PDEV *ppdev, DRIVERDATA *lpDDHALData, #else LPGLOBALDATA lpDDHALData, #endif DWORD dwDrawBlt, DWORD dwDstCoord, DWORD dwBgColor, DWORD dwExtents ) { #ifdef WINNT_VER40 // WINNT_VER40 #else // !WINNT_VER40 DWORD *pDisplayList; qm_return rc; QMDLHandle Handle; DD_LOG(("DL_DrvDstBlt - dst=%08lX ext=%08lX color=%08lX\r\n", dwDstCoord,dwExtents,dwBgColor)); rc = qmAllocDisplayList(10*4, QM_DL_UNLOCKED, &Handle, &pDisplayList); *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 6, 0); // BLTDEF & DRAWDEF *pDisplayList++ = (C_BLTDEF << 16) | HIWORD(dwDrawBlt); *pDisplayList++ = (C_DRWDEF << 16) | LOWORD(dwDrawBlt); // BGCOLOR *pDisplayList++ = (C_BG_L << 16) | LOWORD(dwBgColor); *pDisplayList++ = (C_BG_H << 16) | HIWORD(dwBgColor); // OP0_opRDRAM *pDisplayList++ = (C_RX_0 << 16) | LOWORD(dwDstCoord); *pDisplayList++ = (C_RY_0 << 16) | HIWORD(dwDstCoord); // BLTEXT_EX *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_BLTEXT_EX, 1, 0); *pDisplayList++ = dwExtents; *pDisplayList = wait_3d(0x3e0, 0); rc = qmExecuteDisplayList(Handle, pDisplayList, 0); #endif // !WINNT_VER40 } /* DL_DrvDstBlt */ /*************************************************************************** * * FUNCTION: DL_DrvDstBlt * * DESCRIPTION: * ****************************************************************************/ void DL_DrvDstMBlt ( #ifdef WINNT_VER40 PDEV *ppdev, DRIVERDATA *lpDDHALData, #else LPGLOBALDATA lpDDHALData, #endif DWORD dwDrawBlt, DWORD dwDstCoord, DWORD dwBgColor, DWORD dwExtents ) { #ifdef WINNT_VER40 // WINNT_VER40 #else // !WINNT_VER40 DWORD *pDisplayList; qm_return rc; QMDLHandle Handle; DD_LOG(("DL_DrvDstMBlt - dst=%08lX ext=%08lX color=%08lX\r\n", dwDstCoord,dwExtents,dwBgColor)); rc = qmAllocDisplayList(10*4, QM_DL_UNLOCKED, &Handle, &pDisplayList); *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 6, 0); // BLTDEF & DRAWDEF *pDisplayList++ = (C_BLTDEF << 16) | HIWORD(dwDrawBlt); *pDisplayList++ = (C_DRWDEF << 16) | LOWORD(dwDrawBlt); // BGCOLOR *pDisplayList++ = (C_BG_L << 16) | LOWORD(dwBgColor); *pDisplayList++ = (C_BG_H << 16) | HIWORD(dwBgColor); // OP0_opMRDRAM *pDisplayList++ = (C_MRX_0 << 16) | LOWORD(dwDstCoord); *pDisplayList++ = (C_MRY_0 << 16) | HIWORD(dwDstCoord); // MBLTEXT_EX *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_MBLTEXT_EX, 1, 0); *pDisplayList++ = dwExtents; *pDisplayList = wait_3d(0x3e0, 0); rc = qmExecuteDisplayList(Handle, pDisplayList, 0); #endif // !WINNT_VER40 } /* DL_DrvDstMBlt */ /*************************************************************************** * * FUNCTION: DL_DrvSrcBlt * * DESCRIPTION: * ****************************************************************************/ void DL_DrvSrcBlt ( #ifdef WINNT_VER40 PDEV *ppdev, DRIVERDATA *lpDDHALData, #else LPGLOBALDATA lpDDHALData, #endif DWORD dwDrawBlt, DWORD dwDstCoord, DWORD dwSrcCoord, DWORD dwKeyCoord, DWORD dwKeyColor, DWORD dwExtents ) { #ifdef WINNT_VER40 // WINNT_VER40 #else // !WINNT_VER40 DWORD *pDisplayList; qm_return rc; QMDLHandle Handle; // Handle overlapped regions. const int xDelta = (int)LOWORD(dwDstCoord) - (int)LOWORD(dwSrcCoord); DD_LOG(("DL_DrvSrcBlt - dst=%08lX src=%08lX ext=%08lX color=%08lX\r\n", dwDstCoord,dwSrcCoord,dwExtents,dwKeyColor)); // Check for x overlap. if ( abs(xDelta) < (int)LOWORD(dwExtents) ) { const int yDelta = (int)HIWORD(dwDstCoord) - (int)HIWORD(dwSrcCoord); if ( (yDelta > 0) && (yDelta < (int)HIWORD(dwExtents)) ) { const DWORD dwDelta = (dwExtents & MAKELONG(0,-1)) - MAKELONG(0, 1); // Convert to a bottom-up blt. dwDrawBlt |= MAKELONG(0, BD_YDIR); dwDstCoord += dwDelta; dwSrcCoord += dwDelta; dwKeyCoord += dwDelta; } // are we sliding to the right? else if ( (xDelta > 0) && (yDelta == 0) ) { const DWORD dwDelta = MAKELONG(xDelta, 0); // Blt the overlapped piece first. DL_DrvSrcBlt( #ifdef WINNT_VER40 ppdev, #endif lpDDHALData, dwDrawBlt, dwDstCoord+dwDelta, dwSrcCoord+dwDelta, dwKeyCoord+dwDelta, dwKeyColor, dwExtents-dwDelta); // Subtract the overlap from the original extents. dwExtents = MAKELONG(xDelta, HIWORD(dwExtents)); } } rc = qmAllocDisplayList(14*4, QM_DL_UNLOCKED, &Handle, &pDisplayList); *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 10, 0); // BLTDEF & DRAWDEF *pDisplayList++ = (C_BLTDEF << 16) | HIWORD(dwDrawBlt); *pDisplayList++ = (C_DRWDEF << 16) | LOWORD(dwDrawBlt); // OP0_opRDRAM *pDisplayList++ = (C_RX_0 << 16) | LOWORD(dwDstCoord); *pDisplayList++ = (C_RY_0 << 16) | HIWORD(dwDstCoord); // OP1_opRDRAM *pDisplayList++ = (C_RX_1 << 16) | LOWORD(dwSrcCoord); *pDisplayList++ = (C_RY_1 << 16) | HIWORD(dwSrcCoord); // OP2_opRDRAM *pDisplayList++ = (C_RX_2 << 16) | LOWORD(dwKeyCoord); *pDisplayList++ = (C_RY_2 << 16) | HIWORD(dwKeyCoord); // BGCOLOR *pDisplayList++ = (C_BG_L << 16) | LOWORD(dwKeyColor); *pDisplayList++ = (C_BG_H << 16) | HIWORD(dwKeyColor); // BLTEXT_EX *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_BLTEXT_EX, 1, 0); *pDisplayList++ = dwExtents; *pDisplayList = wait_3d(0x3e0, 0); rc = qmExecuteDisplayList(Handle, pDisplayList, 0); #endif // !WINNT_VER40 } /* DL_DrvSrcBlt */ /*************************************************************************** * * FUNCTION: DL_DrvSrcMBlt * * DESCRIPTION: * ****************************************************************************/ void DL_DrvSrcMBlt ( #ifdef WINNT_VER40 PDEV *ppdev, DRIVERDATA *lpDDHALData, #else LPGLOBALDATA lpDDHALData, #endif DWORD dwDrawBlt, DWORD dwDstCoord, DWORD dwSrcCoord, DWORD dwKeyCoord, DWORD dwKeyColor, DWORD dwExtents ) { #ifdef WINNT_VER40 // WINNT_VER40 #else // !WINNT_VER40 DWORD *pDisplayList; qm_return rc; QMDLHandle Handle; // Handle overlapped regions. const int xDelta = (int)LOWORD(dwDstCoord) - (int)LOWORD(dwSrcCoord); DD_LOG(("DL_DrvSrcMBlt - dst=%08lX src=%08lX ext=%08lX color=%08lX\r\n", dwDstCoord,dwSrcCoord,dwExtents,dwKeyColor)); // Check for x overlap. if ( abs(xDelta) < (int)LOWORD(dwExtents) ) { const int yDelta = (int)HIWORD(dwDstCoord) - (int)HIWORD(dwSrcCoord); if ( (yDelta > 0) && (yDelta < (int)HIWORD(dwExtents)) ) { const DWORD dwDelta = (dwExtents & MAKELONG(0,-1)) - MAKELONG(0, 1); // Convert to a bottom-up blt. dwDrawBlt |= MAKELONG(0, BD_YDIR); dwDstCoord += dwDelta; dwSrcCoord += dwDelta; dwKeyCoord += dwDelta; } // are we sliding to the right? else if ( (xDelta > 0) && (yDelta == 0) ) { const DWORD dwDelta = MAKELONG(xDelta, 0); // Blt the overlapped piece first. DL_DrvSrcMBlt( #ifdef WINNT_VER40 ppdev, #endif lpDDHALData, dwDrawBlt, dwDstCoord+dwDelta, dwSrcCoord+dwDelta, dwKeyCoord+dwDelta, dwKeyColor, dwExtents-dwDelta); // Subtract the overlap from the original extents. dwExtents = MAKELONG(xDelta, HIWORD(dwExtents)); } } rc = qmAllocDisplayList(14*4, QM_DL_UNLOCKED, &Handle, &pDisplayList); *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 10, 0); // BLTDEF & DRAWDEF *pDisplayList++ = (C_BLTDEF << 16) | HIWORD(dwDrawBlt); *pDisplayList++ = (C_DRWDEF << 16) | LOWORD(dwDrawBlt); // OP0_opMRDRAM *pDisplayList++ = (C_MRX_0 << 16) | LOWORD(dwDstCoord); *pDisplayList++ = (C_MRY_0 << 16) | HIWORD(dwDstCoord); // OP1_opMRDRAM *pDisplayList++ = (C_MRX_1 << 16) | LOWORD(dwSrcCoord); *pDisplayList++ = (C_MRY_1 << 16) | HIWORD(dwSrcCoord); // OP2_opMRDRAM *pDisplayList++ = (C_MRX_2 << 16) | LOWORD(dwKeyCoord); *pDisplayList++ = (C_MRY_2 << 16) | HIWORD(dwKeyCoord); // BGCOLOR *pDisplayList++ = (C_BG_L << 16) | LOWORD(dwKeyColor); *pDisplayList++ = (C_BG_H << 16) | HIWORD(dwKeyColor); // MBLTEXT_EX *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_MBLTEXT_EX, 1, 0); *pDisplayList++ = dwExtents; *pDisplayList = wait_3d(0x3e0, 0); rc = qmExecuteDisplayList(Handle, pDisplayList, 0); #endif // !WINNT_VER40 } /* DL_DrvSrcMBlt */ #if 0 /*************************************************************************** * * FUNCTION: DL_DrvStrBlt_OverlapCheck * * DESCRIPTION: * ****************************************************************************/ static void INLINE DL_DrvStrBlt_OverlapCheck ( #ifdef WINNT_VER40 PDEV *ppdev, DRIVERDATA *lpDDHALData, #endif autoblt_ptr pblt ) { int xdelta,ydelta; xdelta = abs(pblt->OP0_opRDRAM.pt.X - pblt->OP1_opRDRAM.pt.X); ydelta = abs(pblt->OP0_opRDRAM.pt.Y - pblt->OP1_opRDRAM.pt.Y); if ((xdelta < pblt->BLTEXT.pt.X) && (ydelta < pblt->BLTEXT.pt.Y)) { // hack, hack, cough, cough // pblt->MBLTEXT.DW has src exents // blt the src to the lower right of the dest DL_DrvSrcBlt( #ifdef WINNT_VER40 ppdev, lpDDHALData, #endif MAKELONG(ROP_OP1_copy, BD_RES * IS_VRAM | BD_OP1 * IS_VRAM), pblt->OP0_opRDRAM.DW + pblt->BLTEXT.DW - pblt->MBLTEXT.DW, pblt->OP1_opRDRAM.DW, 0UL, // don't care 0UL, pblt->MBLTEXT.DW); // update the src ptr to use this copy of the src pblt->OP1_opRDRAM.DW = pblt->OP0_opRDRAM.DW + pblt->BLTEXT.DW - pblt->MBLTEXT.DW; } } #endif /*************************************************************************** * * FUNCTION: DL_DrvStrMBlt_OverlapCheck * * DESCRIPTION: * ****************************************************************************/ static void INLINE DL_DrvStrMBlt_OverlapCheck ( #ifdef WINNT_VER40 PDEV *ppdev, DRIVERDATA *lpDDHALData, #else LPGLOBALDATA lpDDHALData, #endif autoblt_ptr pblt ) { int xdelta,ydelta; xdelta = abs(pblt->OP0_opMRDRAM.pt.X - pblt->OP1_opMRDRAM.pt.X); ydelta = abs(pblt->OP0_opMRDRAM.pt.Y - pblt->OP1_opMRDRAM.pt.Y); if ((xdelta < pblt->MBLTEXTR_EX.pt.X) && (ydelta < pblt->MBLTEXTR_EX.pt.Y)) { // hack, hack, cough, cough // pblt->BLTEXT.DW has src exents (see DrvStretch65) // blt the src to the lower right of the dest DL_DrvSrcMBlt( #ifdef WINNT_VER40 ppdev, #endif lpDDHALData, MAKELONG(ROP_OP1_copy, BD_RES * IS_VRAM | BD_OP1 * IS_VRAM), pblt->OP0_opMRDRAM.DW + pblt->MBLTEXTR_EX.DW - pblt->BLTEXT.DW, pblt->OP1_opMRDRAM.DW, 0UL, // don't care 0UL, pblt->BLTEXT.DW); // update the src ptr to use this copy of the src pblt->OP1_opMRDRAM.DW = pblt->OP0_opMRDRAM.DW + pblt->MBLTEXTR_EX.DW - pblt->BLTEXT.DW; } } /*************************************************************************** * * FUNCTION: DL_DrvStrBlt * * DESCRIPTION: 62/64 version * ****************************************************************************/ void DL_DrvStrBlt ( #ifdef WINNT_VER40 PDEV *ppdev, DRIVERDATA *lpDDHALData, #else LPGLOBALDATA lpDDHALData, #endif autoblt_ptr pblt ) { #ifdef WINNT_VER40 // WINNT_VER40 #else // !WINNT_VER40 DWORD *pDisplayList; qm_return rc; QMDLHandle Handle; DD_LOG(("DL_DrvStrBlt - dst=%08lX dstext=%08lX src=%08lX\r\n", pblt->OP0_opRDRAM.DW,pblt->BLTEXT.DW,pblt->OP1_opRDRAM.DW)); ASSERT( pblt->BLTEXT.pt.X != 0 ); ASSERT( pblt->BLTEXT.pt.Y != 0 ); DBG_MESSAGE(("DL_DrvStrBlt: %4d,%4d -> %4d,%4d %4dx%4d %04x %4d %04x", pblt->OP1_opRDRAM.PT.X, pblt->OP1_opRDRAM.PT.Y, pblt->OP0_opRDRAM.PT.X, pblt->OP0_opRDRAM.PT.Y, pblt->BLTEXT.PT.X, pblt->BLTEXT.PT.Y, pblt->ACCUM_X, pblt->SRCX, pblt->LNCNTL.W)); #if 0 // check for overlap DL_DrvStrBlt_OverlapCheck( #ifdef WINNT_VER40 ppdev,lpDDHALData, #endif pblt); #endif rc = qmAllocDisplayList(19*4, QM_DL_UNLOCKED, &Handle, &pDisplayList); *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 15, 0); *pDisplayList++ = (C_LNCNTL << 16) | pblt->LNCNTL.W; *pDisplayList++ = (C_SHINC << 16) | pblt->SHRINKINC.W; *pDisplayList++ = (C_SRCX << 16) | pblt->SRCX; *pDisplayList++ = (C_MAJX << 16) | pblt->MAJ_X; *pDisplayList++ = (C_MINX << 16) | pblt->MIN_X; *pDisplayList++ = (C_ACCUMX << 16) | pblt->ACCUM_X; *pDisplayList++ = (C_MAJY << 16) | pblt->MAJ_Y; *pDisplayList++ = (C_MINY << 16) | pblt->MIN_Y; *pDisplayList++ = (C_ACCUMY << 16) | pblt->ACCUM_Y; *pDisplayList++ = (C_RX_0 << 16) | pblt->OP0_opRDRAM.pt.X; *pDisplayList++ = (C_RY_0 << 16) | pblt->OP0_opRDRAM.pt.Y; *pDisplayList++ = (C_RX_1 << 16) | pblt->OP1_opRDRAM.pt.X; *pDisplayList++ = (C_RY_1 << 16) | pblt->OP1_opRDRAM.pt.Y; *pDisplayList++ = (C_BLTDEF << 16) | pblt->DRAWBLTDEF.lh.HI; *pDisplayList++ = (C_DRWDEF << 16) | pblt->DRAWBLTDEF.lh.LO; *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_BLTEXTR_EX, 1, 0); *pDisplayList++ = pblt->BLTEXT.DW; *pDisplayList = wait_3d(0x3e0, 0); rc = qmExecuteDisplayList(Handle, pDisplayList, 0); #endif // !WINNT_VER40 } /* DL_DrvStrBlt */ /*************************************************************************** * * FUNCTION: DL_DrvStrBlt65 * * DESCRIPTION: 65+ version * ****************************************************************************/ void DL_DrvStrBlt65 ( #ifdef WINNT_VER40 PDEV *ppdev, DRIVERDATA *lpDDHALData, #else LPGLOBALDATA lpDDHALData, #endif autoblt_ptr pblt ) { #ifdef WINNT_VER40 // WINNT_VER40 #else // !WINNT_VER40 DWORD *pDisplayList; qm_return rc; QMDLHandle Handle; DD_LOG(("DL_DrvStrBlt65 - dst=%08lX dstext=%08lX src=%08lX\r\n", pblt->OP0_opMRDRAM.DW,pblt->MBLTEXTR_EX.DW,pblt->OP1_opMRDRAM.DW)); ASSERT( pblt->MBLTEXTR_EX.pt.X != 0 ); ASSERT( pblt->MBLTEXTR_EX.pt.Y != 0 ); DBG_MESSAGE(("DL_DrvStrBlt65: %4d,%4d -> %4d,%4d %4dx%4d %04x %4d %04x", pblt->OP1_opMRDRAM.PT.X, pblt->OP1_opMRDRAM.PT.Y, pblt->OP0_opMRDRAM.PT.X, pblt->OP0_opMRDRAM.PT.Y, pblt->MBLTEXTR_EX.PT.X, pblt->MBLTEXTR_EX.PT.Y, pblt->ACCUM_X, pblt->SRCX, pblt->STRETCH_CNTL.W)); // check for overlap DL_DrvStrMBlt_OverlapCheck( #ifdef WINNT_VER40 ppdev, #endif lpDDHALData, pblt); rc = qmAllocDisplayList(19*4, QM_DL_UNLOCKED, &Handle, &pDisplayList); *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 15, 0); *pDisplayList++ = (C_STRCTL << 16) | pblt->STRETCH_CNTL.W; *pDisplayList++ = (C_SHINC << 16) | pblt->SHRINKINC.W; *pDisplayList++ = (C_SRCX << 16) | pblt->SRCX; *pDisplayList++ = (C_MAJX << 16) | pblt->MAJ_X; *pDisplayList++ = (C_MINX << 16) | pblt->MIN_X; *pDisplayList++ = (C_ACCUMX << 16) | pblt->ACCUM_X; *pDisplayList++ = (C_MAJY << 16) | pblt->MAJ_Y; *pDisplayList++ = (C_MINY << 16) | pblt->MIN_Y; *pDisplayList++ = (C_ACCUMY << 16) | pblt->ACCUM_Y; *pDisplayList++ = (C_MRX_0 << 16) | pblt->OP0_opMRDRAM.pt.X; *pDisplayList++ = (C_MRY_0 << 16) | pblt->OP0_opMRDRAM.pt.Y; *pDisplayList++ = (C_MRX_1 << 16) | pblt->OP1_opMRDRAM.pt.X; *pDisplayList++ = (C_MRY_1 << 16) | pblt->OP1_opMRDRAM.pt.Y; *pDisplayList++ = (C_BLTDEF << 16) | pblt->DRAWBLTDEF.lh.HI; *pDisplayList++ = (C_DRWDEF << 16) | pblt->DRAWBLTDEF.lh.LO; // MBLTEXTR_EX *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_MBLTEXTR_EX, 1, 0); *pDisplayList++ = pblt->MBLTEXTR_EX.DW; *pDisplayList = wait_3d(0x3e0, 0); rc = qmExecuteDisplayList(Handle, pDisplayList, 0); #endif // !WINNT_VER40 } /* DIR_DrvStrBlt65 */ /*************************************************************************** * * FUNCTION: DL_DrvStrMBlt * * DESCRIPTION: * ****************************************************************************/ void DL_DrvStrMBlt ( #ifdef WINNT_VER40 PDEV *ppdev, DRIVERDATA *lpDDHALData, #else LPGLOBALDATA lpDDHALData, #endif autoblt_ptr pblt ) { #ifdef WINNT_VER40 // WINNT_VER40 #else // !WINNT_VER40 DWORD *pDisplayList; qm_return rc; QMDLHandle Handle; DD_LOG(("DL_DrvStrMBlt - dst=%08lX dstext=%08lX src=%08lX\r\n", pblt->OP0_opRDRAM.DW,pblt->BLTEXT.DW,pblt->OP1_opRDRAM.DW)); ASSERT( pblt->BLTEXT.pt.X != 0 ); ASSERT( pblt->BLTEXT.pt.Y != 0 ); DBG_MESSAGE(("DL_DrvStrMBlt: %4d,%4d -> %4d,%4d %4dx%4d %04x %4d %04x", pblt->OP1_opRDRAM.PT.X, pblt->OP1_opRDRAM.PT.Y, pblt->OP0_opRDRAM.PT.X, pblt->OP0_opRDRAM.PT.Y, pblt->BLTEXT.PT.X, pblt->BLTEXT.PT.Y, pblt->ACCUM_X, pblt->SRCX, pblt->LNCNTL.W)); // check for overlap DL_DrvStrMBlt_OverlapCheck( #ifdef WINNT_VER40 ppdev, #endif lpDDHALData, pblt); rc = qmAllocDisplayList(19*4, QM_DL_UNLOCKED, &Handle, &pDisplayList); *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 15, 0); *pDisplayList++ = (C_LNCNTL << 16) | pblt->LNCNTL.W; *pDisplayList++ = (C_SHINC << 16) | pblt->SHRINKINC.W; *pDisplayList++ = (C_SRCX << 16) | pblt->SRCX; *pDisplayList++ = (C_MAJX << 16) | pblt->MAJ_X; *pDisplayList++ = (C_MINX << 16) | pblt->MIN_X; *pDisplayList++ = (C_ACCUMX << 16) | pblt->ACCUM_X; *pDisplayList++ = (C_MAJY << 16) | pblt->MAJ_Y; *pDisplayList++ = (C_MINY << 16) | pblt->MIN_Y; *pDisplayList++ = (C_ACCUMY << 16) | pblt->ACCUM_Y; *pDisplayList++ = (C_MRX_0 << 16) | pblt->OP0_opRDRAM.pt.X; *pDisplayList++ = (C_MRY_0 << 16) | pblt->OP0_opRDRAM.pt.Y; *pDisplayList++ = (C_MRX_1 << 16) | pblt->OP1_opRDRAM.pt.X; *pDisplayList++ = (C_MRY_1 << 16) | pblt->OP1_opRDRAM.pt.Y; *pDisplayList++ = (C_BLTDEF << 16) | pblt->DRAWBLTDEF.lh.HI; *pDisplayList++ = (C_DRWDEF << 16) | pblt->DRAWBLTDEF.lh.LO; *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_MBLTEXTR_EX, 1, 0); *pDisplayList++ = pblt->BLTEXT.DW; *pDisplayList = wait_3d(0x3e0, 0); rc = qmExecuteDisplayList(Handle, pDisplayList, 0); #endif // !WINNT_VER40 } /* DL_DrvStrMBlt */ /*************************************************************************** * * FUNCTION: DL_DrvStrMBltY * * DESCRIPTION: Write regs that don't vary over the stripes * Used in conjunction with DL_DrvStrMBltX * ****************************************************************************/ void DL_DrvStrMBltY ( #ifdef WINNT_VER40 PDEV *ppdev, DRIVERDATA *lpDDHALData, #else LPGLOBALDATA lpDDHALData, #endif autoblt_ptr pblt ) { #ifdef WINNT_VER40 // WINNT_VER40 #else // !WINNT_VER40 DWORD *pDisplayList; qm_return rc; QMDLHandle Handle; DD_LOG(("DL_DrvStrMBltY - dst.Y=%04X dstext.Y=%04X src=%04X\r\n", pblt->OP0_opRDRAM.pt.Y,pblt->BLTEXT.pt.Y,pblt->OP1_opRDRAM.pt.Y)); ASSERT( pblt->BLTEXT.pt.Y != 0 ); DBG_MESSAGE(("DrvStrMBltY: %4d,%4d -> %4d,%4d %4dx%4d %04x %4d %04x", pblt->OP1_opRDRAM.PT.X, pblt->OP1_opRDRAM.PT.Y, pblt->OP0_opRDRAM.PT.X, pblt->OP0_opRDRAM.PT.Y, pblt->BLTEXT.PT.X, pblt->BLTEXT.PT.Y, pblt->ACCUM_X, pblt->SRCX, pblt->LNCNTL.W)); rc = qmAllocDisplayList(13*4, QM_DL_UNLOCKED, &Handle, &pDisplayList); *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 11, 0); *pDisplayList++ = (C_LNCNTL << 16) | pblt->LNCNTL.W; *pDisplayList++ = (C_SHINC << 16) | pblt->SHRINKINC.W; *pDisplayList++ = (C_MAJX << 16) | pblt->MAJ_X; *pDisplayList++ = (C_MINX << 16) | pblt->MIN_X; *pDisplayList++ = (C_MAJY << 16) | pblt->MAJ_Y; *pDisplayList++ = (C_MINY << 16) | pblt->MIN_Y; *pDisplayList++ = (C_ACCUMY << 16) | pblt->ACCUM_Y; *pDisplayList++ = (C_MRY_0 << 16) | pblt->OP0_opRDRAM.pt.Y; *pDisplayList++ = (C_MRY_1 << 16) | pblt->OP1_opRDRAM.pt.Y; *pDisplayList++ = (C_BLTDEF << 16) | pblt->DRAWBLTDEF.lh.HI; *pDisplayList++ = (C_DRWDEF << 16) | pblt->DRAWBLTDEF.lh.LO; *pDisplayList = wait_3d(0x3e0, 0); rc = qmExecuteDisplayList(Handle, pDisplayList, 0); #endif // !WINNT_VER40 } /* DL_DrvStrMBltY */ /*************************************************************************** * * FUNCTION: DL_DrvStrMBltX * * DESCRIPTION: Write stripe specific regs * Used in conjunction with DL_DrvStrMBltY * ****************************************************************************/ void DL_DrvStrMBltX ( #ifdef WINNT_VER40 PDEV *ppdev, DRIVERDATA *lpDDHALData, #else LPGLOBALDATA lpDDHALData, #endif autoblt_ptr pblt ) { #ifdef WINNT_VER40 // WINNT_VER40 #else // !WINNT_VER40 DWORD *pDisplayList; qm_return rc; QMDLHandle Handle; DD_LOG(("DL_DrvStrMBltX - dst.X=%04X dstext.X=%04X src.X=%04X\r\n", pblt->OP0_opRDRAM.pt.X,pblt->BLTEXT.pt.X,pblt->OP1_opRDRAM.pt.X)); ASSERT( pblt->BLTEXT.pt.X != 0 ); DBG_MESSAGE(("DrvStrMBltX: %4d,%4d -> %4d,%4d %4dx%4d %04x %4d %04x", pblt->OP1_opRDRAM.PT.X, pblt->OP1_opRDRAM.PT.Y, pblt->OP0_opRDRAM.PT.X, pblt->OP0_opRDRAM.PT.Y, pblt->BLTEXT.PT.X, pblt->BLTEXT.PT.Y, pblt->ACCUM_X, pblt->SRCX, pblt->LNCNTL.W)); rc = qmAllocDisplayList(8*4, QM_DL_UNLOCKED, &Handle, &pDisplayList); *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 4, 0); *pDisplayList++ = (C_SRCX << 16) | pblt->SRCX; *pDisplayList++ = (C_ACCUMX << 16) | pblt->ACCUM_X; *pDisplayList++ = (C_MRX_0 << 16) | pblt->OP0_opRDRAM.pt.X; *pDisplayList++ = (C_MRX_1 << 16) | pblt->OP1_opRDRAM.pt.X; *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_MBLTEXTR_EX, 1, 0); *pDisplayList++ = pblt->BLTEXT.DW; *pDisplayList = wait_3d(0x3e0, 0); rc = qmExecuteDisplayList(Handle, pDisplayList, 0); #endif // !WINNT_VER40 } /* DL_DrvStrMBltX */ /*************************************************************************** * * FUNCTION: DL_DrvStrBltY * * DESCRIPTION: Write regs that don't vary over the stripes * Used in conjunction with DL_DrvStrBltX * ****************************************************************************/ void DL_DrvStrBltY ( #ifdef WINNT_VER40 PDEV *ppdev, DRIVERDATA *lpDDHALData, #else LPGLOBALDATA lpDDHALData, #endif autoblt_ptr pblt ) { #ifdef WINNT_VER40 // WINNT_VER40 #else // !WINNT_VER40 DWORD *pDisplayList; qm_return rc; QMDLHandle Handle; DD_LOG(("DL_DrvStrBltY\r\n")); DBG_MESSAGE(("DL_DrvStrBltY: %4d,%4d -> %4d,%4d %4dx%4d %04x %4d %04x", pblt->OP1_opRDRAM.PT.X, pblt->OP1_opRDRAM.PT.Y, pblt->OP0_opRDRAM.PT.X, pblt->OP0_opRDRAM.PT.Y, pblt->BLTEXT.PT.X, pblt->BLTEXT.PT.Y, pblt->ACCUM_X, pblt->SRCX, pblt->LNCNTL.W)); rc = qmAllocDisplayList(12*4, QM_DL_UNLOCKED, &Handle, &pDisplayList); *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 10, 0); *pDisplayList++ = (C_LNCNTL << 16) | pblt->LNCNTL.W; *pDisplayList++ = (C_SHINC << 16) | pblt->SHRINKINC.W; *pDisplayList++ = (C_SRCX << 16) | pblt->SRCX; *pDisplayList++ = (C_MAJX << 16) | pblt->MAJ_X; *pDisplayList++ = (C_MINX << 16) | pblt->MIN_X; *pDisplayList++ = (C_MAJY << 16) | pblt->MAJ_Y; *pDisplayList++ = (C_MINY << 16) | pblt->MIN_Y; *pDisplayList++ = (C_ACCUMY << 16) | pblt->ACCUM_Y; *pDisplayList++ = (C_BLTDEF << 16) | pblt->DRAWBLTDEF.lh.HI; *pDisplayList++ = (C_DRWDEF << 16) | pblt->DRAWBLTDEF.lh.LO; *pDisplayList = wait_3d(0x3e0, 0); rc = qmExecuteDisplayList(Handle, pDisplayList, 0); #endif // !WINNT_VER40 } /* DL_DrvStrBltY */ /*************************************************************************** * * FUNCTION: DL_DrvStrBltX * * DESCRIPTION: Write stripe specific regs * Used in conjunction with DL_DrvStrMBltY * ****************************************************************************/ void DL_DrvStrBltX ( #ifdef WINNT_VER40 PDEV *ppdev, DRIVERDATA *lpDDHALData, #else LPGLOBALDATA lpDDHALData, #endif autoblt_ptr pblt ) { #ifdef WINNT_VER40 // WINNT_VER40 #else // !WINNT_VER40 DWORD *pDisplayList; qm_return rc; QMDLHandle Handle; DD_LOG(("DL_DrvStrBltX - dst=%08lX dstext=%08lX src=%08lX\r\n", pblt->OP0_opRDRAM.DW,pblt->BLTEXT.DW,pblt->OP1_opRDRAM.DW)); ASSERT( pblt->BLTEXT.pt.X != 0 ); ASSERT( pblt->BLTEXT.pt.Y != 0 ); DBG_MESSAGE(("DL_DrvStrBltX: %4d,%4d -> %4d,%4d %4dx%4d %04x %4d %04x", pblt->OP1_opRDRAM.PT.X, pblt->OP1_opRDRAM.PT.Y, pblt->OP0_opRDRAM.PT.X, pblt->OP0_opRDRAM.PT.Y, pblt->BLTEXT.PT.X, pblt->BLTEXT.PT.Y, pblt->ACCUM_X, pblt->SRCX, pblt->LNCNTL.W)); rc = qmAllocDisplayList(9*4, QM_DL_UNLOCKED, &Handle, &pDisplayList); *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 5, 0); *pDisplayList++ = (C_ACCUMX << 16) | pblt->ACCUM_X; *pDisplayList++ = (C_RX_0 << 16) | pblt->OP0_opRDRAM.pt.X; *pDisplayList++ = (C_RY_0 << 16) | pblt->OP0_opRDRAM.pt.Y; *pDisplayList++ = (C_RX_1 << 16) | pblt->OP1_opRDRAM.pt.X; *pDisplayList++ = (C_RY_1 << 16) | pblt->OP1_opRDRAM.pt.Y; *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_BLTEXTR_EX, 1, 0); *pDisplayList++ = pblt->BLTEXT.DW; *pDisplayList = wait_3d(0x3e0, 0); rc = qmExecuteDisplayList(Handle, pDisplayList, 0); #endif // !WINNT_VER40 } /* DL_DrvStrBltX */ #if ENABLE_CLIPPEDBLTS /*************************************************************************** * * FUNCTION: DL_HWClippedDrvDstBlt * * DESCRIPTION: * ****************************************************************************/ void DL_HWClippedDrvDstBlt ( #ifdef WINNT_VER40 PDEV *ppdev, DRIVERDATA *lpDDHALData, #endif DWORD dwDrawBlt, DWORD dwDstCoord, DWORD dwBgColor, DWORD dwExtents, DWORD dwDstBaseXY, DWORD dwRectCnt, LPRECT pDestRects ) { #ifdef WINNT_VER40 // WINNT_VER40 #else // !WINNT_VER40 DWORD *pDisplayList; qm_return rc; QMDLHandle Handle; DD_LOG(("DL_HWClippedDrvDstBlt - dst=%08lX ext=%08lX color=%08lX\r\n", dwDstCoord,dwExtents,dwBgColor)); // check for negative dst coordinates, hw can't deal with negative OP0 values if (0 > (short)((REG32 *)&dwDstCoord)->pt.X) { (short)((REG32 *)&dwExtents)->pt.X += (short)((REG32 *)&dwDstCoord)->pt.X; ((REG32 *)&dwDstCoord)->pt.X = 0; } if (0 > (short)((REG32 *)&dwDstCoord)->pt.Y) { (short)((REG32 *)&dwExtents)->pt.Y += (short)((REG32 *)&dwDstCoord)->pt.Y; ((REG32 *)&dwDstCoord)->pt.Y = 0; } rc = qmAllocDisplayList((10+dwRectCnt*4)*4, QM_DL_UNLOCKED, &Handle, &pDisplayList); *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 8, 0); // setup blt, write BLTEXT reg with extent which doesn't fire off blt // BLTDEF & DRAWDEF *pDisplayList++ = (C_BLTDEF << 16) | HIWORD(dwDrawBlt); *pDisplayList++ = (C_DRWDEF << 16) | LOWORD(dwDrawBlt); // BGCOLOR *pDisplayList++ = (C_BG_L << 16) | LOWORD(dwBgColor); *pDisplayList++ = (C_BG_H << 16) | HIWORD(dwBgColor); // OP0_opRDRAM *pDisplayList++ = (C_RX_0 << 16) | LOWORD(dwDstCoord); *pDisplayList++ = (C_RY_0 << 16) | HIWORD(dwDstCoord); // BLTEXT *pDisplayList++ = (C_BLTEXT_X << 16) | LOWORD(dwExtents); *pDisplayList++ = (C_BLTEXT_Y << 16) | HIWORD(dwExtents); // loop over clip list do { REG32 UpperLeft; REG32 LowerRight; // compute cliprect coords UpperLeft.DW = dwDstBaseXY + MAKELONG(pDestRects->left, pDestRects->top); LowerRight.DW = dwDstBaseXY + MAKELONG(pDestRects->right, pDestRects->bottom); // write clipping regs // CLIPULE *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_CLIPULE, 1, 0); *pDisplayList++ = UpperLeft.DW; // CLIPLOR_EX *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_CLIPLOR_EX, 1, 0); *pDisplayList++ = LowerRight.DW; pDestRects++; } while (0 < --dwRectCnt); *pDisplayList = wait_3d(0x3e0, 0); rc = qmExecuteDisplayList(Handle, pDisplayList, 0); #endif // !WINNT_VER40 } /* DL_HWClippedDrvDstBlt */ /*************************************************************************** * * FUNCTION: DL_HWClippedDrvDstMBlt * * DESCRIPTION: * ****************************************************************************/ void DL_HWClippedDrvDstMBlt ( #ifdef WINNT_VER40 PDEV *ppdev, DRIVERDATA *lpDDHALData, #endif DWORD dwDrawBlt, DWORD dwDstCoord, DWORD dwBgColor, DWORD dwExtents, DWORD dwDstBaseXY, DWORD dwRectCnt, LPRECT pDestRects ) { #ifdef WINNT_VER40 // WINNT_VER40 #else // !WINNT_VER40 const int nBytesPixel = BYTESPERPIXEL; DWORD *pDisplayList; qm_return rc; QMDLHandle Handle; DD_LOG(("DL_HWClippedDrvDstMBlt - dst=%08lX ext=%08lX color=%08lX\r\n", dwDstCoord,dwExtents,dwBgColor)); // check for negative dst coordinates, hw can't deal with negative OP0 values if (0 > (short)((REG32 *)&dwDstCoord)->pt.X) { (short)((REG32 *)&dwExtents)->pt.X += (short)((REG32 *)&dwDstCoord)->pt.X; ((REG32 *)&dwDstCoord)->pt.X = 0; } if (0 > (short)((REG32 *)&dwDstCoord)->pt.Y) { (short)((REG32 *)&dwExtents)->pt.Y += (short)((REG32 *)&dwDstCoord)->pt.Y; ((REG32 *)&dwDstCoord)->pt.Y = 0; } rc = qmAllocDisplayList((10+dwRectCnt*4)*4, QM_DL_UNLOCKED, &Handle, &pDisplayList); *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 8, 0); // setup blt, write BLTEXT reg with extent which doesn't fire off blt // BLTDEF & DRAWDEF *pDisplayList++ = (C_BLTDEF << 16) | HIWORD(dwDrawBlt); *pDisplayList++ = (C_DRWDEF << 16) | LOWORD(dwDrawBlt); // BGCOLOR *pDisplayList++ = (C_BG_L << 16) | LOWORD(dwBgColor); *pDisplayList++ = (C_BG_H << 16) | HIWORD(dwBgColor); // OP0_opMRDRAM *pDisplayList++ = (C_MRX_0 << 16) | LOWORD(dwDstCoord); *pDisplayList++ = (C_MRY_0 << 16) | HIWORD(dwDstCoord); // MBLTEXT *pDisplayList++ = (C_MBLTEXT_X << 16) | LOWORD(dwExtents); *pDisplayList++ = (C_MBLTEXT_Y << 16) | HIWORD(dwExtents); // loop over clip list do { REG32 UpperLeft; REG32 LowerRight; // compute cliprect coords UpperLeft.DW = dwDstBaseXY + MAKELONG(pDestRects->left, pDestRects->top); LowerRight.DW = dwDstBaseXY + MAKELONG(pDestRects->right, pDestRects->bottom); UpperLeft.pt.X *= nBytesPixel; LowerRight.pt.X *= nBytesPixel; // write clipping regs // MCLIPULE *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_MCLIPULE, 1, 0); *pDisplayList++ = UpperLeft.DW; // MCLIPLOR_EX *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_MCLIPLOR_EX, 1, 0); *pDisplayList++ = LowerRight.DW; pDestRects++; } while (0 < --dwRectCnt); *pDisplayList = wait_3d(0x3e0, 0); rc = qmExecuteDisplayList(Handle, pDisplayList, 0); #endif // !WINNT_VER40 } /* DL_HWClippedDrvDstMBlt */ /*************************************************************************** * * FUNCTION: DL_HWClippedDrvSrcBlt * * DESCRIPTION: * ****************************************************************************/ void DL_HWClippedDrvSrcBlt ( #ifdef WINNT_VER40 PDEV *ppdev, DRIVERDATA *lpDDHALData, #endif DWORD dwDrawBlt, DWORD dwDstCoord, DWORD dwSrcCoord, DWORD dwKeyCoord, DWORD dwKeyColor, DWORD dwExtents, DWORD dwDstBaseXY, DWORD dwSrcBaseXY, DWORD dwRectCnt, LPRECT pDestRects ) { #ifdef WINNT_VER40 // WINNT_VER40 #else // !WINNT_VER40 DWORD *pDisplayList; qm_return rc; QMDLHandle Handle; // Handle overlapped regions const int xDelta = (int)LOWORD(dwDstCoord) - (int)LOWORD(dwSrcCoord); DD_LOG(("DL_HWClippedDrvSrcBlt - dst=%08lX src=%08lX ext=%08lX color=%08lX\r\n", dwDstCoord,dwSrcCoord,dwExtents,dwKeyColor)); // check for negative dst coordinates, hw can't deal with negative OP0 values if (0 > (short)((REG32 *)&dwDstCoord)->pt.X) { // reduce extent.X (short)((REG32 *)&dwExtents)->pt.X += (short)((REG32 *)&dwDstCoord)->pt.X; // bump src.X to right (short)((REG32 *)&dwSrcCoord)->pt.X -= (short)((REG32 *)&dwDstCoord)->pt.X; if ((DD_TRANS | DD_TRANSOP) & dwDrawBlt) // bump key.X to right (short)((REG32 *)&dwKeyCoord)->pt.X -= (short)((REG32 *)&dwKeyCoord)->pt.X; // clear dst.X ((REG32 *)&dwDstCoord)->pt.X = 0; } if (0 > (short)((REG32 *)&dwDstCoord)->pt.Y) { // reduce extent.Y (short)((REG32 *)&dwExtents)->pt.Y += (short)((REG32 *)&dwDstCoord)->pt.Y; // bump src.Y down (short)((REG32 *)&dwSrcCoord)->pt.Y -= (short)((REG32 *)&dwDstCoord)->pt.Y; if ((DD_TRANS | DD_TRANSOP) & dwDrawBlt) // bump key.Y down (short)((REG32 *)&dwKeyCoord)->pt.Y -= (short)((REG32 *)&dwKeyCoord)->pt.Y; // clean dst.Y ((REG32 *)&dwDstCoord)->pt.Y = 0; } // Check for x overlap if ( abs(xDelta) < (int)LOWORD(dwExtents) ) { const int yDelta = (int)HIWORD(dwDstCoord) - (int)HIWORD(dwSrcCoord); if ( (yDelta > 0) && (yDelta < (int)HIWORD(dwExtents)) ) { const DWORD dwDelta = (dwExtents & MAKELONG(0, -1)) - MAKELONG(0, 1); // Convert to a bottom-up blt. dwDrawBlt |= MAKELONG(0, BD_YDIR); dwDstCoord += dwDelta; dwSrcCoord += dwDelta; dwKeyCoord += dwDelta; } // are we sliding to the right? else if ( (xDelta > 0) && (yDelta == 0) ) { const DWORD dwDelta = MAKELONG(xDelta, 0); // Blt the overlapped piece first DL_HWClippedDrvSrcBlt( #ifdef WINNT_VER40 ppdev, lpDDHALData, #endif dwDrawBlt, dwDstCoord+dwDelta, dwSrcCoord+dwDelta, dwKeyCoord+dwDelta, dwKeyColor, dwExtents-dwDelta, dwDstBaseXY, dwSrcBaseXY, dwRectCnt, pDestRects); // Subtract the overlap from the original extents. dwExtents = MAKELONG(xDelta, HIWORD(dwExtents)); } } rc = qmAllocDisplayList((14+dwRectCnt*4)*4, QM_DL_UNLOCKED, &Handle, &pDisplayList); *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 12, 0); // setup blt, write BLTEXT reg with extent which doesn't fire off blt // BLTDEF & DRAWDEF *pDisplayList++ = (C_BLTDEF << 16) | HIWORD(dwDrawBlt); *pDisplayList++ = (C_DRWDEF << 16) | LOWORD(dwDrawBlt); // OP0_opRDRAM *pDisplayList++ = (C_RX_0 << 16) | LOWORD(dwDstCoord); *pDisplayList++ = (C_RY_0 << 16) | HIWORD(dwDstCoord); // OP1_opRDRAM *pDisplayList++ = (C_RX_1 << 16) | LOWORD(dwSrcCoord); *pDisplayList++ = (C_RY_1 << 16) | HIWORD(dwSrcCoord); // OP2_opRDRAM *pDisplayList++ = (C_RX_2 << 16) | LOWORD(dwKeyCoord); *pDisplayList++ = (C_RY_2 << 16) | HIWORD(dwKeyCoord); // BGCOLOR *pDisplayList++ = (C_BG_L << 16) | LOWORD(dwKeyColor); *pDisplayList++ = (C_BG_H << 16) | HIWORD(dwKeyColor); // BLTEXT *pDisplayList++ = (C_BLTEXT_X << 16) | LOWORD(dwExtents); *pDisplayList++ = (C_BLTEXT_Y << 16) | HIWORD(dwExtents); // loop over clip list do { REG32 UpperLeft; REG32 LowerRight; // compute cliprect coords UpperLeft.DW = dwDstBaseXY + MAKELONG(pDestRects->left, pDestRects->top); LowerRight.DW = dwDstBaseXY + MAKELONG(pDestRects->right, pDestRects->bottom); // write clipping regs // CLIPULE *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_CLIPULE, 1, 0); *pDisplayList++ = UpperLeft.DW; // CLIPLOR_EX *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_CLIPLOR_EX, 1, 0); *pDisplayList++ = LowerRight.DW; pDestRects++; } while (0 < --dwRectCnt); *pDisplayList = wait_3d(0x3e0, 0); rc = qmExecuteDisplayList(Handle, pDisplayList, 0); #endif // !WINNT_VER40 } /* DL_HWClippedDrvSrcBlt */ /*************************************************************************** * * FUNCTION: DL_SWClippedDrvDstBlt * * DESCRIPTION: * ****************************************************************************/ void DL_SWClippedDrvDstBlt ( #ifdef WINNT_VER40 PDEV *ppdev, DRIVERDATA *lpDDHALData, #endif DWORD dwDrawBlt, DWORD dwDstCoord, DWORD dwBgColor, DWORD dwExtents, DWORD dwDstBaseXY, DWORD dwRectCnt, LPRECT pDestRects ) { #ifdef WINNT_VER40 // WINNT_VER40 #else // !WINNT_VER40 DWORD *pDisplayList; qm_return rc; QMDLHandle Handle; DD_LOG(("DL_SWClippedDrvDstBlt - dst=%08lX ext=%08lX color=%08lX\r\n", dwDstCoord,dwExtents,dwBgColor)); // make sure DD_CLIP isn't set in drawdef dwDrawBlt &= ~DD_CLIP; rc = qmAllocDisplayList((6+dwRectCnt*4)*4, QM_DL_UNLOCKED, &Handle, &pDisplayList); *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 4, 0); // write regs that don't vary over rectangles // BLTDEF & DRAWDEF *pDisplayList++ = (C_BLTDEF << 16) | HIWORD(dwDrawBlt); *pDisplayList++ = (C_DRWDEF << 16) | LOWORD(dwDrawBlt); // BGCOLOR *pDisplayList++ = (C_BG_L << 16) | LOWORD(dwBgColor); *pDisplayList++ = (C_BG_H << 16) | HIWORD(dwBgColor); // loop over clip list do { DDRECTL DstDDRect; // compute cliprect coords DstDDRect.loc.DW = dwDstBaseXY + MAKELONG(pDestRects->left, pDestRects->top); DstDDRect.ext.pt.X = (WORD)(pDestRects->right - pDestRects->left); DstDDRect.ext.pt.Y = (WORD)(pDestRects->bottom - pDestRects->top); // write OP0 and bltext regs // OP0_opRDRAM *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_OP0_OPRDRAM, 1, 0); *pDisplayList++ = DstDDRect.loc.DW; // BLTEXT_EX *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_BLTEXT_EX, 1, 0); *pDisplayList++ = DstDDRect.ext.DW; pDestRects++; } while (0 < --dwRectCnt); *pDisplayList = wait_3d(0x3e0, 0); rc = qmExecuteDisplayList(Handle, pDisplayList, 0); #endif // !WINNT_VER40 } /* DL_SWClippedDrvDstBlt */ /*************************************************************************** * * FUNCTION: DL_SWClippedDrvDstMBlt * * DESCRIPTION: * ****************************************************************************/ void DL_SWClippedDrvDstMBlt ( #ifdef WINNT_VER40 PDEV *ppdev, DRIVERDATA *lpDDHALData, #endif DWORD dwDrawBlt, DWORD dwDstCoord, DWORD dwBgColor, DWORD dwExtents, DWORD dwDstBaseXY, DWORD dwRectCnt, LPRECT pDestRects ) { #ifdef WINNT_VER40 // WINNT_VER40 #else // !WINNT_VER40 const int nBytesPixel = BYTESPERPIXEL; DWORD *pDisplayList; qm_return rc; QMDLHandle Handle; DD_LOG(("DL_SWClippedDrvDstMBlt - dst=%08lX ext=%08lX color=%08lX\r\n", dwDstCoord,dwExtents,dwBgColor)); // make sure DD_CLIP isn't set in drawdef dwDrawBlt &= ~DD_CLIP; rc = qmAllocDisplayList((6+dwRectCnt*4)*4, QM_DL_UNLOCKED, &Handle, &pDisplayList); *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 4, 0); // write regs that don't vary over rectangles // BLTDEF & DRAWDEF *pDisplayList++ = (C_BLTDEF << 16) | HIWORD(dwDrawBlt); *pDisplayList++ = (C_DRWDEF << 16) | LOWORD(dwDrawBlt); // BGCOLOR *pDisplayList++ = (C_BG_L << 16) | LOWORD(dwBgColor); *pDisplayList++ = (C_BG_H << 16) | HIWORD(dwBgColor); // loop over clip list do { DDRECTL DstDDRect; // compute cliprect coords DstDDRect.loc.DW = dwDstBaseXY + MAKELONG(pDestRects->left, pDestRects->top); DstDDRect.loc.pt.X *= nBytesPixel; DstDDRect.ext.pt.X = (WORD)(pDestRects->right - pDestRects->left) * nBytesPixel; DstDDRect.ext.pt.Y = (WORD)(pDestRects->bottom - pDestRects->top); // write OP0 and bltext regs // OP0_opMRDRAM *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_OP0_OPMRDRAM, 1, 0); *pDisplayList++ = DstDDRect.loc.DW; // MBLTEXT_EX *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_MBLTEXT_EX, 1, 0); *pDisplayList++ = DstDDRect.ext.DW; pDestRects++; } while (0 < --dwRectCnt); *pDisplayList = wait_3d(0x3e0, 0); rc = qmExecuteDisplayList(Handle, pDisplayList, 0); #endif // !WINNT_VER40 } /* DL_SWClippedDrvDstMBlt */ /*************************************************************************** * * FUNCTION: DL_SWClippedDrvSrcBlt * * DESCRIPTION: * ****************************************************************************/ void DL_SWClippedDrvSrcBlt ( #ifdef WINNT_VER40 PDEV *ppdev, DRIVERDATA *lpDDHALData, #endif DWORD dwDrawBlt, DWORD dwDstCoord, DWORD dwSrcCoord, DWORD dwKeyCoord, DWORD dwKeyColor, DWORD dwExtents, DWORD dwDstBaseXY, DWORD dwSrcBaseXY, DWORD dwRectCnt, LPRECT pDestRects ) { #ifdef WINNT_VER40 // WINNT_VER40 #else // !WINNT_VER40 DWORD *pDisplayList; qm_return rc; QMDLHandle Handle; // Handle overlapped regions const int xDelta = (int)LOWORD(dwDstCoord) - (int)LOWORD(dwSrcCoord); DD_LOG(("DL_SWClippedDrvSrcBlt - dst=%08lX src=%08lX ext=%08lX color=%08lX\r\n", dwDstCoord,dwSrcCoord,dwExtents,dwKeyColor)); // make sure DD_CLIP isn't set in drawdef dwDrawBlt &= ~DD_CLIP; // Check for x overlap if ( abs(xDelta) < (int)LOWORD(dwExtents) ) { const int yDelta = (int)HIWORD(dwDstCoord) - (int)HIWORD(dwSrcCoord); if ( (yDelta > 0) && (yDelta < (int)HIWORD(dwExtents)) ) { const DWORD dwDelta = (dwExtents & MAKELONG(0, -1)) - MAKELONG(0, 1); // Convert to a bottom-up blt. dwDrawBlt |= MAKELONG(0, BD_YDIR); dwDstCoord += dwDelta; dwSrcCoord += dwDelta; dwKeyCoord += dwDelta; } // are we sliding to the right? else if ( (xDelta > 0) && (yDelta == 0) ) { const DWORD dwDelta = MAKELONG(xDelta, 0); // Blt the overlapped piece first DL_SWClippedDrvSrcBlt( #ifdef WINNT_VER40 ppdev, lpDDHALData, #endif dwDrawBlt, dwDstCoord+dwDelta, dwSrcCoord+dwDelta, dwKeyCoord+dwDelta, dwKeyColor, dwExtents-dwDelta, dwDstBaseXY, dwSrcBaseXY, dwRectCnt, pDestRects); // Subtract the overlap from the original extents. dwExtents = MAKELONG(xDelta, HIWORD(dwExtents)); } } rc = qmAllocDisplayList((6+dwRectCnt*9)*4, QM_DL_UNLOCKED, &Handle, &pDisplayList); *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 4, 0); // write regs that don't vary over rectangles // BLTDEF & DRAWDEF *pDisplayList++ = (C_BLTDEF << 16) | HIWORD(dwDrawBlt); *pDisplayList++ = (C_DRWDEF << 16) | LOWORD(dwDrawBlt); // BGCOLOR *pDisplayList++ = (C_BG_L << 16) | LOWORD(dwKeyColor); *pDisplayList++ = (C_BG_H << 16) | HIWORD(dwKeyColor); // loop over clip list do { DDRECTL DstDDRect; DDRECTL SrcDDRect; // compute dst cliprect coords DstDDRect.loc.DW = dwDstBaseXY + MAKELONG(pDestRects->left, pDestRects->top); DstDDRect.ext.pt.X = (WORD)(pDestRects->right - pDestRects->left); DstDDRect.ext.pt.Y = (WORD)(pDestRects->bottom - pDestRects->top); // compute src cliprect coords SrcDDRect.loc.DW = dwSrcBaseXY + MAKELONG(pDestRects->left, pDestRects->top); // don't care about src extent, it's the same as dst extent //SrcDDRect.ext.pt.X = (WORD)(pDestRects->right - pDestRects->left); //SrcDDRect.ext.pt.Y = (WORD)(pDestRects->bottom - pDestRects->top); *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 6, 0); // write OP0, OP1, OP2 and bltext regs if ((DD_TRANS | DD_TRANSOP) == ((DD_TRANS | DD_TRANSOP) & dwDrawBlt)) { // dst color key // OP2_opRDRAM *pDisplayList++ = (C_RX_2 << 16) | DstDDRect.loc.pt.X; *pDisplayList++ = (C_RY_2 << 16) | DstDDRect.loc.pt.Y; } else if (DD_TRANS == ((DD_TRANS | DD_TRANSOP) & dwDrawBlt)) { // src color key // OP2_opRDRAM *pDisplayList++ = (C_RX_2 << 16) | SrcDDRect.loc.pt.X; *pDisplayList++ = (C_RY_2 << 16) | SrcDDRect.loc.pt.Y; } else { // OP2_opRDRAM *pDisplayList++ = (C_RX_2 << 16) | 0; *pDisplayList++ = (C_RY_2 << 16) | 0; } // OP0_opRDRAM *pDisplayList++ = (C_RX_0 << 16) | DstDDRect.loc.pt.X; *pDisplayList++ = (C_RY_0 << 16) | DstDDRect.loc.pt.Y; // OP1_opRDRAM *pDisplayList++ = (C_RX_1 << 16) | SrcDDRect.loc.pt.X; *pDisplayList++ = (C_RY_1 << 16) | SrcDDRect.loc.pt.Y; // BLTEXT_EX *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_BLTEXT_EX, 1, 0); *pDisplayList++ = DstDDRect.ext.DW; pDestRects++; } while (0 < --dwRectCnt); *pDisplayList = wait_3d(0x3e0, 0); rc = qmExecuteDisplayList(Handle, pDisplayList, 0); #endif // !WINNT_VER40 } /* DL_SWClippedDrvSrcBlt */ #endif // ENABLE_CLIPPEDBLTS #endif // WINNT_VER35