Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1881 lines
56 KiB

  1. /**************************************************************************
  2. ***************************************************************************
  3. *
  4. * Copyright (c) 1996, Cirrus Logic, Inc.
  5. * All Rights Reserved
  6. *
  7. * FILE: blt_dl.c
  8. *
  9. * DESCRIPTION: Display List blts for the 5464
  10. *
  11. * REVISION HISTORY:
  12. *
  13. * $Log: X:\log\laguna\ddraw\src\blt_dl.c $
  14. *
  15. * Rev 1.20 06 Jan 1998 15:20:04 xcong
  16. *
  17. * Rev 1.19 06 Jan 1998 11:56:22 xcong
  18. * Change pDriverData into lpDDHALData for multi-monitor support.
  19. *
  20. * Rev 1.18 03 Oct 1997 14:31:12 RUSSL
  21. * Initial changes for use of hw clipped blts
  22. * All changes wrapped in #if ENABLE_CLIPPEDBLTS/#endif blocks and
  23. * ENABLE_CLIPPEDBLTS defaults to 0 (so the code is disabled)
  24. *
  25. * Rev 1.17 15 Sep 1997 17:25:14 RUSSL
  26. * Fix for PDR 10493 - Minor parenthesis change
  27. *
  28. * Rev 1.16 24 Jul 1997 12:32:40 RUSSL
  29. * Botched the overlap check, changed || to &&
  30. *
  31. * Rev 1.15 24 Jul 1997 11:20:16 RUSSL
  32. * Added DL_DrvStrBlt_OverlapCheck & DL_DrvStrMBlt_OverlapCheck
  33. * inline functions
  34. *
  35. * Rev 1.14 17 Jul 1997 14:31:58 RUSSL
  36. * Fixed my copy & paste errors in the DD_LOG and ASSERTs in DL_DrvStrBlt65
  37. *
  38. * Rev 1.13 15 Jul 1997 16:19:50 eleland
  39. * removed the increment-and-immediate decrement of display list
  40. * pointer at the end of each blt display list
  41. *
  42. * Rev 1.12 14 Jul 1997 14:59:52 RUSSL
  43. * Added DL_DrvStrBlt65
  44. *
  45. * Rev 1.11 02 Jul 1997 19:13:10 eleland
  46. * added wait instruction after each dl blit
  47. *
  48. * Rev 1.10 03 Apr 1997 15:05:30 RUSSL
  49. * Added DL_DrvDstMBlt function
  50. *
  51. * Rev 1.9 26 Mar 1997 13:55:22 RUSSL
  52. * Added DL_DrvSrcMBlt function
  53. *
  54. * Rev 1.8 12 Mar 1997 15:01:20 RUSSL
  55. * replaced a block of includes with include of precomp.h for
  56. * precompiled headers
  57. *
  58. * Rev 1.7 07 Mar 1997 12:50:40 RUSSL
  59. * Modified DDRAW_COMPAT usage
  60. *
  61. * Rev 1.6 11 Feb 1997 11:40:34 bennyn
  62. * Fixed the compiling error for NT
  63. *
  64. * Rev 1.5 07 Feb 1997 16:30:34 KENTL
  65. * Never mind the #ifdefs. The problems are deeper than that. We'd need
  66. * ifdefs around half the code in the file.
  67. *
  68. * Rev 1.4 07 Feb 1997 16:18:58 KENTL
  69. * Addd #ifdef's around include qmgr.h
  70. *
  71. * Rev 1.3 07 Feb 1997 13:22:36 KENTL
  72. * Merged in Evan Leland's modifications to get Display List mode working:
  73. * * include qmgr.h
  74. * * Invoke qmAllocDisplayList to get pDisplayList pointer.
  75. * * Invoke qmExecuteDisplayList on completed DL's
  76. *
  77. * Rev 1.2 23 Jan 1997 17:08:48 bennyn
  78. * Modified naming of registers
  79. *
  80. * Rev 1.1 25 Nov 1996 16:15:48 bennyn
  81. * Fixed misc compiling error for NT
  82. *
  83. * Rev 1.0 25 Nov 1996 15:14:02 RUSSL
  84. * Initial revision.
  85. *
  86. * Rev 1.2 18 Nov 1996 16:18:56 RUSSL
  87. * Added file logging for DDraw entry points and register writes
  88. *
  89. * Rev 1.1 01 Nov 1996 13:08:40 RUSSL
  90. * Merge WIN95 & WINNT code for Blt32
  91. *
  92. * Rev 1.0 01 Nov 1996 09:28:02 BENNYN
  93. * Initial revision.
  94. *
  95. * Rev 1.0 25 Oct 1996 11:08:22 RUSSL
  96. * Initial revision.
  97. *
  98. ***************************************************************************
  99. ***************************************************************************/
  100. /***************************************************************************
  101. * I N C L U D E S
  102. ****************************************************************************/
  103. #include "precomp.h"
  104. // If WinNT 3.5 skip all the source code
  105. #if defined WINNT_VER35 // WINNT_VER35
  106. #else // !WINNT_VER35
  107. #ifdef WINNT_VER40 // WINNT_VER40
  108. #define DBGLVL 1
  109. #define AFPRINTF(n)
  110. #else // !WINNT_VER40
  111. #include "l3system.h"
  112. #include "l2d.h"
  113. #include "bltP.h"
  114. #include "qmgr.h"
  115. #endif // !WINNT_VER40
  116. /***************************************************************************
  117. * S T A T I C V A R I A B L E S
  118. ****************************************************************************/
  119. #ifndef WINNT_VER40
  120. ASSERTFILE("blt_dl.c");
  121. #endif
  122. /***************************************************************************
  123. *
  124. * FUNCTION: DL_Delay9BitBlt
  125. *
  126. * DESCRIPTION:
  127. *
  128. ****************************************************************************/
  129. void DL_Delay9BitBlt
  130. (
  131. #ifdef WINNT_VER40
  132. PDEV *ppdev,
  133. DRIVERDATA *lpDDHALData,
  134. #else
  135. LPGLOBALDATA lpDDHALData,
  136. #endif
  137. BOOL ninebit_on
  138. )
  139. {
  140. #ifdef WINNT_VER40 // WINNT_VER40
  141. #else // !WINNT_VER40
  142. DWORD *pDisplayList;
  143. qm_return rc;
  144. QMDLHandle Handle;
  145. DD_LOG(("DL_Delay9BitBlt\r\n"));
  146. /* This is to ensure that the last packet of any previous blt */
  147. /* does no go out with 9th bit set incorrectly */
  148. /* The boolean paramter is the 9th bit of the PREVIOUS BLT */
  149. rc = qmAllocDisplayList(8*4, QM_DL_UNLOCKED, &Handle, &pDisplayList);
  150. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 4, 0);
  151. // BLTDEF & DRAWDEF
  152. *pDisplayList++ = (C_BLTDEF << 16) | ((BD_RES + BD_OP0 + BD_OP1 + BD_OP2)*IS_VRAM);
  153. if (ninebit_on)
  154. *pDisplayList++ = (C_DRWDEF << 16) | (DD_PTAG | ROP_OP0_copy);
  155. else
  156. *pDisplayList++ = (C_DRWDEF << 16) | ROP_OP0_copy;
  157. // OP0_RDRAM
  158. *pDisplayList++ = (C_RX_0 << 16) | LOWORD(lpDDHALData->PTAGFooPixel);
  159. *pDisplayList++ = (C_RY_0 << 16) | HIWORD(lpDDHALData->PTAGFooPixel);
  160. // BLTEXT_EX
  161. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_BLTEXT_EX, 1, 0);
  162. *pDisplayList++ = MAKELONG(1,1);
  163. *pDisplayList = wait_3d(0x3e0, 0);
  164. rc = qmExecuteDisplayList(Handle, pDisplayList, 0);
  165. #endif // !WINNT_VER40
  166. } /* DL_Delay9BitBlt */
  167. /***************************************************************************
  168. *
  169. * FUNCTION: DL_EdgeFillBlt
  170. *
  171. * DESCRIPTION: Solid Fill BLT to fill in edges ( Pixel Coords / Extents )
  172. *
  173. ****************************************************************************/
  174. void DL_EdgeFillBlt
  175. (
  176. #ifdef WINNT_VER40
  177. PDEV *ppdev,
  178. DRIVERDATA *lpDDHALData,
  179. #else
  180. LPGLOBALDATA lpDDHALData,
  181. #endif
  182. int xFill,
  183. int yFill,
  184. int cxFill,
  185. int cyFill,
  186. DWORD FillValue,
  187. BOOL ninebit_on
  188. )
  189. {
  190. #ifdef WINNT_VER40 // WINNT_VER40
  191. #else // !WINNT_VER40
  192. DWORD *pDisplayList;
  193. qm_return rc;
  194. QMDLHandle Handle;
  195. DD_LOG(("DL_EdgeFillBlt - dst=%08lX ext=%08lX color=%08lX\r\n",
  196. MAKELONG(xFill,yFill),MAKELONG(cxFill,cyFill),FillValue));
  197. rc = qmAllocDisplayList(10*4, QM_DL_UNLOCKED, &Handle, &pDisplayList);
  198. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 6, 0);
  199. // BLTDEF & DRAWDEF
  200. *pDisplayList++ = (C_BLTDEF << 16) | (BD_RES * IS_VRAM + BD_OP1 * IS_SOLID);
  201. if (ninebit_on)
  202. *pDisplayList++ = (C_DRWDEF << 16) | (DD_PTAG | ROP_OP1_copy);
  203. else
  204. *pDisplayList++ = (C_DRWDEF << 16) | ROP_OP1_copy;
  205. // BGCOLOR
  206. *pDisplayList++ = (C_BG_L << 16) | LOWORD(FillValue);
  207. *pDisplayList++ = (C_BG_H << 16) | HIWORD(FillValue);
  208. // OP0_opRDRAM
  209. *pDisplayList++ = (C_RX_0 << 16) | LOWORD(xFill);
  210. *pDisplayList++ = (C_RY_0 << 16) | LOWORD(yFill);
  211. // BLTEXT_EX
  212. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_BLTEXT_EX, 1, 0);
  213. *pDisplayList++ = MAKELONG(LOWORD(cxFill),LOWORD(cyFill));
  214. *pDisplayList = wait_3d(0x3e0, 0);
  215. rc = qmExecuteDisplayList(Handle, pDisplayList, 0);
  216. #endif // !WINNT_VER40
  217. } /* DL_EdgeFillBlt */
  218. /***************************************************************************
  219. *
  220. * FUNCTION: DL_MEdgeFillBlt
  221. *
  222. * DESCRIPTION: Using BYTE BLT coords / Extents perform EdgeFill BLT
  223. *
  224. ****************************************************************************/
  225. void DL_MEdgeFillBlt
  226. (
  227. #ifdef WINNT_VER40
  228. PDEV *ppdev,
  229. DRIVERDATA *lpDDHALData,
  230. #else
  231. LPGLOBALDATA lpDDHALData,
  232. #endif
  233. int xFill,
  234. int yFill,
  235. int cxFill,
  236. int cyFill,
  237. DWORD FillValue,
  238. BOOL ninebit_on
  239. )
  240. {
  241. #ifdef WINNT_VER40 // WINNT_VER40
  242. #else // !WINNT_VER40
  243. DWORD *pDisplayList;
  244. qm_return rc;
  245. QMDLHandle Handle;
  246. DD_LOG(("DL_MEdgeFillBlt - dst=%08lX ext=%08lX color=%08lX\r\n",
  247. MAKELONG(xFill,yFill),MAKELONG(cxFill,cyFill),FillValue));
  248. rc = qmAllocDisplayList(10*4, QM_DL_UNLOCKED, &Handle, &pDisplayList);
  249. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 6, 0);
  250. // BLTDEF & DRAWDEF
  251. *pDisplayList++ = (C_BLTDEF << 16) | (BD_RES * IS_VRAM + BD_OP1 * IS_SOLID);
  252. if (ninebit_on)
  253. *pDisplayList++ = (C_DRWDEF << 16) | (DD_PTAG | ROP_OP1_copy);
  254. else
  255. *pDisplayList++ = (C_DRWDEF << 16) | ROP_OP1_copy;
  256. // BGCOLOR
  257. *pDisplayList++ = (C_BG_L << 16) | LOWORD(FillValue);
  258. *pDisplayList++ = (C_BG_H << 16) | HIWORD(FillValue);
  259. // OP0_opMRDRAM
  260. *pDisplayList++ = (C_MRX_0 << 16) | LOWORD(xFill);
  261. *pDisplayList++ = (C_MRY_0 << 16) | LOWORD(yFill);
  262. // MBLTEXT_EX
  263. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_MBLTEXT_EX, 1, 0);
  264. *pDisplayList++ = MAKELONG(LOWORD(cxFill),LOWORD(cyFill));
  265. *pDisplayList = wait_3d(0x3e0, 0);
  266. rc = qmExecuteDisplayList(Handle, pDisplayList, 0);
  267. #endif // !WINNT_VER40
  268. } /* DL_EdgeFillBlt */
  269. /***************************************************************************
  270. *
  271. * FUNCTION: DL_DrvDstBlt
  272. *
  273. * DESCRIPTION:
  274. *
  275. ****************************************************************************/
  276. void DL_DrvDstBlt
  277. (
  278. #ifdef WINNT_VER40
  279. PDEV *ppdev,
  280. DRIVERDATA *lpDDHALData,
  281. #else
  282. LPGLOBALDATA lpDDHALData,
  283. #endif
  284. DWORD dwDrawBlt,
  285. DWORD dwDstCoord,
  286. DWORD dwBgColor,
  287. DWORD dwExtents
  288. )
  289. {
  290. #ifdef WINNT_VER40 // WINNT_VER40
  291. #else // !WINNT_VER40
  292. DWORD *pDisplayList;
  293. qm_return rc;
  294. QMDLHandle Handle;
  295. DD_LOG(("DL_DrvDstBlt - dst=%08lX ext=%08lX color=%08lX\r\n",
  296. dwDstCoord,dwExtents,dwBgColor));
  297. rc = qmAllocDisplayList(10*4, QM_DL_UNLOCKED, &Handle, &pDisplayList);
  298. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 6, 0);
  299. // BLTDEF & DRAWDEF
  300. *pDisplayList++ = (C_BLTDEF << 16) | HIWORD(dwDrawBlt);
  301. *pDisplayList++ = (C_DRWDEF << 16) | LOWORD(dwDrawBlt);
  302. // BGCOLOR
  303. *pDisplayList++ = (C_BG_L << 16) | LOWORD(dwBgColor);
  304. *pDisplayList++ = (C_BG_H << 16) | HIWORD(dwBgColor);
  305. // OP0_opRDRAM
  306. *pDisplayList++ = (C_RX_0 << 16) | LOWORD(dwDstCoord);
  307. *pDisplayList++ = (C_RY_0 << 16) | HIWORD(dwDstCoord);
  308. // BLTEXT_EX
  309. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_BLTEXT_EX, 1, 0);
  310. *pDisplayList++ = dwExtents;
  311. *pDisplayList = wait_3d(0x3e0, 0);
  312. rc = qmExecuteDisplayList(Handle, pDisplayList, 0);
  313. #endif // !WINNT_VER40
  314. } /* DL_DrvDstBlt */
  315. /***************************************************************************
  316. *
  317. * FUNCTION: DL_DrvDstBlt
  318. *
  319. * DESCRIPTION:
  320. *
  321. ****************************************************************************/
  322. void DL_DrvDstMBlt
  323. (
  324. #ifdef WINNT_VER40
  325. PDEV *ppdev,
  326. DRIVERDATA *lpDDHALData,
  327. #else
  328. LPGLOBALDATA lpDDHALData,
  329. #endif
  330. DWORD dwDrawBlt,
  331. DWORD dwDstCoord,
  332. DWORD dwBgColor,
  333. DWORD dwExtents
  334. )
  335. {
  336. #ifdef WINNT_VER40 // WINNT_VER40
  337. #else // !WINNT_VER40
  338. DWORD *pDisplayList;
  339. qm_return rc;
  340. QMDLHandle Handle;
  341. DD_LOG(("DL_DrvDstMBlt - dst=%08lX ext=%08lX color=%08lX\r\n",
  342. dwDstCoord,dwExtents,dwBgColor));
  343. rc = qmAllocDisplayList(10*4, QM_DL_UNLOCKED, &Handle, &pDisplayList);
  344. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 6, 0);
  345. // BLTDEF & DRAWDEF
  346. *pDisplayList++ = (C_BLTDEF << 16) | HIWORD(dwDrawBlt);
  347. *pDisplayList++ = (C_DRWDEF << 16) | LOWORD(dwDrawBlt);
  348. // BGCOLOR
  349. *pDisplayList++ = (C_BG_L << 16) | LOWORD(dwBgColor);
  350. *pDisplayList++ = (C_BG_H << 16) | HIWORD(dwBgColor);
  351. // OP0_opMRDRAM
  352. *pDisplayList++ = (C_MRX_0 << 16) | LOWORD(dwDstCoord);
  353. *pDisplayList++ = (C_MRY_0 << 16) | HIWORD(dwDstCoord);
  354. // MBLTEXT_EX
  355. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_MBLTEXT_EX, 1, 0);
  356. *pDisplayList++ = dwExtents;
  357. *pDisplayList = wait_3d(0x3e0, 0);
  358. rc = qmExecuteDisplayList(Handle, pDisplayList, 0);
  359. #endif // !WINNT_VER40
  360. } /* DL_DrvDstMBlt */
  361. /***************************************************************************
  362. *
  363. * FUNCTION: DL_DrvSrcBlt
  364. *
  365. * DESCRIPTION:
  366. *
  367. ****************************************************************************/
  368. void DL_DrvSrcBlt
  369. (
  370. #ifdef WINNT_VER40
  371. PDEV *ppdev,
  372. DRIVERDATA *lpDDHALData,
  373. #else
  374. LPGLOBALDATA lpDDHALData,
  375. #endif
  376. DWORD dwDrawBlt,
  377. DWORD dwDstCoord,
  378. DWORD dwSrcCoord,
  379. DWORD dwKeyCoord,
  380. DWORD dwKeyColor,
  381. DWORD dwExtents
  382. )
  383. {
  384. #ifdef WINNT_VER40 // WINNT_VER40
  385. #else // !WINNT_VER40
  386. DWORD *pDisplayList;
  387. qm_return rc;
  388. QMDLHandle Handle;
  389. // Handle overlapped regions.
  390. const int xDelta = (int)LOWORD(dwDstCoord) - (int)LOWORD(dwSrcCoord);
  391. DD_LOG(("DL_DrvSrcBlt - dst=%08lX src=%08lX ext=%08lX color=%08lX\r\n",
  392. dwDstCoord,dwSrcCoord,dwExtents,dwKeyColor));
  393. // Check for x overlap.
  394. if ( abs(xDelta) < (int)LOWORD(dwExtents) )
  395. {
  396. const int yDelta = (int)HIWORD(dwDstCoord) - (int)HIWORD(dwSrcCoord);
  397. if ( (yDelta > 0) && (yDelta < (int)HIWORD(dwExtents)) )
  398. {
  399. const DWORD dwDelta = (dwExtents & MAKELONG(0,-1)) - MAKELONG(0, 1);
  400. // Convert to a bottom-up blt.
  401. dwDrawBlt |= MAKELONG(0, BD_YDIR);
  402. dwDstCoord += dwDelta;
  403. dwSrcCoord += dwDelta;
  404. dwKeyCoord += dwDelta;
  405. }
  406. // are we sliding to the right?
  407. else if ( (xDelta > 0) && (yDelta == 0) )
  408. {
  409. const DWORD dwDelta = MAKELONG(xDelta, 0);
  410. // Blt the overlapped piece first.
  411. DL_DrvSrcBlt(
  412. #ifdef WINNT_VER40
  413. ppdev,
  414. #endif
  415. lpDDHALData,
  416. dwDrawBlt,
  417. dwDstCoord+dwDelta,
  418. dwSrcCoord+dwDelta,
  419. dwKeyCoord+dwDelta,
  420. dwKeyColor,
  421. dwExtents-dwDelta);
  422. // Subtract the overlap from the original extents.
  423. dwExtents = MAKELONG(xDelta, HIWORD(dwExtents));
  424. }
  425. }
  426. rc = qmAllocDisplayList(14*4, QM_DL_UNLOCKED, &Handle, &pDisplayList);
  427. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 10, 0);
  428. // BLTDEF & DRAWDEF
  429. *pDisplayList++ = (C_BLTDEF << 16) | HIWORD(dwDrawBlt);
  430. *pDisplayList++ = (C_DRWDEF << 16) | LOWORD(dwDrawBlt);
  431. // OP0_opRDRAM
  432. *pDisplayList++ = (C_RX_0 << 16) | LOWORD(dwDstCoord);
  433. *pDisplayList++ = (C_RY_0 << 16) | HIWORD(dwDstCoord);
  434. // OP1_opRDRAM
  435. *pDisplayList++ = (C_RX_1 << 16) | LOWORD(dwSrcCoord);
  436. *pDisplayList++ = (C_RY_1 << 16) | HIWORD(dwSrcCoord);
  437. // OP2_opRDRAM
  438. *pDisplayList++ = (C_RX_2 << 16) | LOWORD(dwKeyCoord);
  439. *pDisplayList++ = (C_RY_2 << 16) | HIWORD(dwKeyCoord);
  440. // BGCOLOR
  441. *pDisplayList++ = (C_BG_L << 16) | LOWORD(dwKeyColor);
  442. *pDisplayList++ = (C_BG_H << 16) | HIWORD(dwKeyColor);
  443. // BLTEXT_EX
  444. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_BLTEXT_EX, 1, 0);
  445. *pDisplayList++ = dwExtents;
  446. *pDisplayList = wait_3d(0x3e0, 0);
  447. rc = qmExecuteDisplayList(Handle, pDisplayList, 0);
  448. #endif // !WINNT_VER40
  449. } /* DL_DrvSrcBlt */
  450. /***************************************************************************
  451. *
  452. * FUNCTION: DL_DrvSrcMBlt
  453. *
  454. * DESCRIPTION:
  455. *
  456. ****************************************************************************/
  457. void DL_DrvSrcMBlt
  458. (
  459. #ifdef WINNT_VER40
  460. PDEV *ppdev,
  461. DRIVERDATA *lpDDHALData,
  462. #else
  463. LPGLOBALDATA lpDDHALData,
  464. #endif
  465. DWORD dwDrawBlt,
  466. DWORD dwDstCoord,
  467. DWORD dwSrcCoord,
  468. DWORD dwKeyCoord,
  469. DWORD dwKeyColor,
  470. DWORD dwExtents
  471. )
  472. {
  473. #ifdef WINNT_VER40 // WINNT_VER40
  474. #else // !WINNT_VER40
  475. DWORD *pDisplayList;
  476. qm_return rc;
  477. QMDLHandle Handle;
  478. // Handle overlapped regions.
  479. const int xDelta = (int)LOWORD(dwDstCoord) - (int)LOWORD(dwSrcCoord);
  480. DD_LOG(("DL_DrvSrcMBlt - dst=%08lX src=%08lX ext=%08lX color=%08lX\r\n",
  481. dwDstCoord,dwSrcCoord,dwExtents,dwKeyColor));
  482. // Check for x overlap.
  483. if ( abs(xDelta) < (int)LOWORD(dwExtents) )
  484. {
  485. const int yDelta = (int)HIWORD(dwDstCoord) - (int)HIWORD(dwSrcCoord);
  486. if ( (yDelta > 0) && (yDelta < (int)HIWORD(dwExtents)) )
  487. {
  488. const DWORD dwDelta = (dwExtents & MAKELONG(0,-1)) - MAKELONG(0, 1);
  489. // Convert to a bottom-up blt.
  490. dwDrawBlt |= MAKELONG(0, BD_YDIR);
  491. dwDstCoord += dwDelta;
  492. dwSrcCoord += dwDelta;
  493. dwKeyCoord += dwDelta;
  494. }
  495. // are we sliding to the right?
  496. else if ( (xDelta > 0) && (yDelta == 0) )
  497. {
  498. const DWORD dwDelta = MAKELONG(xDelta, 0);
  499. // Blt the overlapped piece first.
  500. DL_DrvSrcMBlt(
  501. #ifdef WINNT_VER40
  502. ppdev,
  503. #endif
  504. lpDDHALData,
  505. dwDrawBlt,
  506. dwDstCoord+dwDelta,
  507. dwSrcCoord+dwDelta,
  508. dwKeyCoord+dwDelta,
  509. dwKeyColor,
  510. dwExtents-dwDelta);
  511. // Subtract the overlap from the original extents.
  512. dwExtents = MAKELONG(xDelta, HIWORD(dwExtents));
  513. }
  514. }
  515. rc = qmAllocDisplayList(14*4, QM_DL_UNLOCKED, &Handle, &pDisplayList);
  516. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 10, 0);
  517. // BLTDEF & DRAWDEF
  518. *pDisplayList++ = (C_BLTDEF << 16) | HIWORD(dwDrawBlt);
  519. *pDisplayList++ = (C_DRWDEF << 16) | LOWORD(dwDrawBlt);
  520. // OP0_opMRDRAM
  521. *pDisplayList++ = (C_MRX_0 << 16) | LOWORD(dwDstCoord);
  522. *pDisplayList++ = (C_MRY_0 << 16) | HIWORD(dwDstCoord);
  523. // OP1_opMRDRAM
  524. *pDisplayList++ = (C_MRX_1 << 16) | LOWORD(dwSrcCoord);
  525. *pDisplayList++ = (C_MRY_1 << 16) | HIWORD(dwSrcCoord);
  526. // OP2_opMRDRAM
  527. *pDisplayList++ = (C_MRX_2 << 16) | LOWORD(dwKeyCoord);
  528. *pDisplayList++ = (C_MRY_2 << 16) | HIWORD(dwKeyCoord);
  529. // BGCOLOR
  530. *pDisplayList++ = (C_BG_L << 16) | LOWORD(dwKeyColor);
  531. *pDisplayList++ = (C_BG_H << 16) | HIWORD(dwKeyColor);
  532. // MBLTEXT_EX
  533. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_MBLTEXT_EX, 1, 0);
  534. *pDisplayList++ = dwExtents;
  535. *pDisplayList = wait_3d(0x3e0, 0);
  536. rc = qmExecuteDisplayList(Handle, pDisplayList, 0);
  537. #endif // !WINNT_VER40
  538. } /* DL_DrvSrcMBlt */
  539. #if 0
  540. /***************************************************************************
  541. *
  542. * FUNCTION: DL_DrvStrBlt_OverlapCheck
  543. *
  544. * DESCRIPTION:
  545. *
  546. ****************************************************************************/
  547. static void INLINE DL_DrvStrBlt_OverlapCheck
  548. (
  549. #ifdef WINNT_VER40
  550. PDEV *ppdev,
  551. DRIVERDATA *lpDDHALData,
  552. #endif
  553. autoblt_ptr pblt
  554. )
  555. {
  556. int xdelta,ydelta;
  557. xdelta = abs(pblt->OP0_opRDRAM.pt.X - pblt->OP1_opRDRAM.pt.X);
  558. ydelta = abs(pblt->OP0_opRDRAM.pt.Y - pblt->OP1_opRDRAM.pt.Y);
  559. if ((xdelta < pblt->BLTEXT.pt.X) &&
  560. (ydelta < pblt->BLTEXT.pt.Y))
  561. {
  562. // hack, hack, cough, cough
  563. // pblt->MBLTEXT.DW has src exents
  564. // blt the src to the lower right of the dest
  565. DL_DrvSrcBlt(
  566. #ifdef WINNT_VER40
  567. ppdev,
  568. lpDDHALData,
  569. #endif
  570. MAKELONG(ROP_OP1_copy, BD_RES * IS_VRAM | BD_OP1 * IS_VRAM),
  571. pblt->OP0_opRDRAM.DW + pblt->BLTEXT.DW - pblt->MBLTEXT.DW,
  572. pblt->OP1_opRDRAM.DW,
  573. 0UL, // don't care
  574. 0UL,
  575. pblt->MBLTEXT.DW);
  576. // update the src ptr to use this copy of the src
  577. pblt->OP1_opRDRAM.DW = pblt->OP0_opRDRAM.DW + pblt->BLTEXT.DW - pblt->MBLTEXT.DW;
  578. }
  579. }
  580. #endif
  581. /***************************************************************************
  582. *
  583. * FUNCTION: DL_DrvStrMBlt_OverlapCheck
  584. *
  585. * DESCRIPTION:
  586. *
  587. ****************************************************************************/
  588. static void INLINE DL_DrvStrMBlt_OverlapCheck
  589. (
  590. #ifdef WINNT_VER40
  591. PDEV *ppdev,
  592. DRIVERDATA *lpDDHALData,
  593. #else
  594. LPGLOBALDATA lpDDHALData,
  595. #endif
  596. autoblt_ptr pblt
  597. )
  598. {
  599. int xdelta,ydelta;
  600. xdelta = abs(pblt->OP0_opMRDRAM.pt.X - pblt->OP1_opMRDRAM.pt.X);
  601. ydelta = abs(pblt->OP0_opMRDRAM.pt.Y - pblt->OP1_opMRDRAM.pt.Y);
  602. if ((xdelta < pblt->MBLTEXTR_EX.pt.X) &&
  603. (ydelta < pblt->MBLTEXTR_EX.pt.Y))
  604. {
  605. // hack, hack, cough, cough
  606. // pblt->BLTEXT.DW has src exents (see DrvStretch65)
  607. // blt the src to the lower right of the dest
  608. DL_DrvSrcMBlt(
  609. #ifdef WINNT_VER40
  610. ppdev,
  611. #endif
  612. lpDDHALData,
  613. MAKELONG(ROP_OP1_copy, BD_RES * IS_VRAM | BD_OP1 * IS_VRAM),
  614. pblt->OP0_opMRDRAM.DW + pblt->MBLTEXTR_EX.DW - pblt->BLTEXT.DW,
  615. pblt->OP1_opMRDRAM.DW,
  616. 0UL, // don't care
  617. 0UL,
  618. pblt->BLTEXT.DW);
  619. // update the src ptr to use this copy of the src
  620. pblt->OP1_opMRDRAM.DW = pblt->OP0_opMRDRAM.DW + pblt->MBLTEXTR_EX.DW - pblt->BLTEXT.DW;
  621. }
  622. }
  623. /***************************************************************************
  624. *
  625. * FUNCTION: DL_DrvStrBlt
  626. *
  627. * DESCRIPTION: 62/64 version
  628. *
  629. ****************************************************************************/
  630. void DL_DrvStrBlt
  631. (
  632. #ifdef WINNT_VER40
  633. PDEV *ppdev,
  634. DRIVERDATA *lpDDHALData,
  635. #else
  636. LPGLOBALDATA lpDDHALData,
  637. #endif
  638. autoblt_ptr pblt
  639. )
  640. {
  641. #ifdef WINNT_VER40 // WINNT_VER40
  642. #else // !WINNT_VER40
  643. DWORD *pDisplayList;
  644. qm_return rc;
  645. QMDLHandle Handle;
  646. DD_LOG(("DL_DrvStrBlt - dst=%08lX dstext=%08lX src=%08lX\r\n",
  647. pblt->OP0_opRDRAM.DW,pblt->BLTEXT.DW,pblt->OP1_opRDRAM.DW));
  648. ASSERT( pblt->BLTEXT.pt.X != 0 );
  649. ASSERT( pblt->BLTEXT.pt.Y != 0 );
  650. DBG_MESSAGE(("DL_DrvStrBlt: %4d,%4d -> %4d,%4d %4dx%4d %04x %4d %04x",
  651. pblt->OP1_opRDRAM.PT.X, pblt->OP1_opRDRAM.PT.Y,
  652. pblt->OP0_opRDRAM.PT.X, pblt->OP0_opRDRAM.PT.Y,
  653. pblt->BLTEXT.PT.X, pblt->BLTEXT.PT.Y,
  654. pblt->ACCUM_X, pblt->SRCX, pblt->LNCNTL.W));
  655. #if 0
  656. // check for overlap
  657. DL_DrvStrBlt_OverlapCheck(
  658. #ifdef WINNT_VER40
  659. ppdev,lpDDHALData,
  660. #endif
  661. pblt);
  662. #endif
  663. rc = qmAllocDisplayList(19*4, QM_DL_UNLOCKED, &Handle, &pDisplayList);
  664. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 15, 0);
  665. *pDisplayList++ = (C_LNCNTL << 16) | pblt->LNCNTL.W;
  666. *pDisplayList++ = (C_SHINC << 16) | pblt->SHRINKINC.W;
  667. *pDisplayList++ = (C_SRCX << 16) | pblt->SRCX;
  668. *pDisplayList++ = (C_MAJX << 16) | pblt->MAJ_X;
  669. *pDisplayList++ = (C_MINX << 16) | pblt->MIN_X;
  670. *pDisplayList++ = (C_ACCUMX << 16) | pblt->ACCUM_X;
  671. *pDisplayList++ = (C_MAJY << 16) | pblt->MAJ_Y;
  672. *pDisplayList++ = (C_MINY << 16) | pblt->MIN_Y;
  673. *pDisplayList++ = (C_ACCUMY << 16) | pblt->ACCUM_Y;
  674. *pDisplayList++ = (C_RX_0 << 16) | pblt->OP0_opRDRAM.pt.X;
  675. *pDisplayList++ = (C_RY_0 << 16) | pblt->OP0_opRDRAM.pt.Y;
  676. *pDisplayList++ = (C_RX_1 << 16) | pblt->OP1_opRDRAM.pt.X;
  677. *pDisplayList++ = (C_RY_1 << 16) | pblt->OP1_opRDRAM.pt.Y;
  678. *pDisplayList++ = (C_BLTDEF << 16) | pblt->DRAWBLTDEF.lh.HI;
  679. *pDisplayList++ = (C_DRWDEF << 16) | pblt->DRAWBLTDEF.lh.LO;
  680. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_BLTEXTR_EX, 1, 0);
  681. *pDisplayList++ = pblt->BLTEXT.DW;
  682. *pDisplayList = wait_3d(0x3e0, 0);
  683. rc = qmExecuteDisplayList(Handle, pDisplayList, 0);
  684. #endif // !WINNT_VER40
  685. } /* DL_DrvStrBlt */
  686. /***************************************************************************
  687. *
  688. * FUNCTION: DL_DrvStrBlt65
  689. *
  690. * DESCRIPTION: 65+ version
  691. *
  692. ****************************************************************************/
  693. void DL_DrvStrBlt65
  694. (
  695. #ifdef WINNT_VER40
  696. PDEV *ppdev,
  697. DRIVERDATA *lpDDHALData,
  698. #else
  699. LPGLOBALDATA lpDDHALData,
  700. #endif
  701. autoblt_ptr pblt
  702. )
  703. {
  704. #ifdef WINNT_VER40 // WINNT_VER40
  705. #else // !WINNT_VER40
  706. DWORD *pDisplayList;
  707. qm_return rc;
  708. QMDLHandle Handle;
  709. DD_LOG(("DL_DrvStrBlt65 - dst=%08lX dstext=%08lX src=%08lX\r\n",
  710. pblt->OP0_opMRDRAM.DW,pblt->MBLTEXTR_EX.DW,pblt->OP1_opMRDRAM.DW));
  711. ASSERT( pblt->MBLTEXTR_EX.pt.X != 0 );
  712. ASSERT( pblt->MBLTEXTR_EX.pt.Y != 0 );
  713. DBG_MESSAGE(("DL_DrvStrBlt65: %4d,%4d -> %4d,%4d %4dx%4d %04x %4d %04x",
  714. pblt->OP1_opMRDRAM.PT.X, pblt->OP1_opMRDRAM.PT.Y,
  715. pblt->OP0_opMRDRAM.PT.X, pblt->OP0_opMRDRAM.PT.Y,
  716. pblt->MBLTEXTR_EX.PT.X, pblt->MBLTEXTR_EX.PT.Y,
  717. pblt->ACCUM_X, pblt->SRCX, pblt->STRETCH_CNTL.W));
  718. // check for overlap
  719. DL_DrvStrMBlt_OverlapCheck(
  720. #ifdef WINNT_VER40
  721. ppdev,
  722. #endif
  723. lpDDHALData,
  724. pblt);
  725. rc = qmAllocDisplayList(19*4, QM_DL_UNLOCKED, &Handle, &pDisplayList);
  726. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 15, 0);
  727. *pDisplayList++ = (C_STRCTL << 16) | pblt->STRETCH_CNTL.W;
  728. *pDisplayList++ = (C_SHINC << 16) | pblt->SHRINKINC.W;
  729. *pDisplayList++ = (C_SRCX << 16) | pblt->SRCX;
  730. *pDisplayList++ = (C_MAJX << 16) | pblt->MAJ_X;
  731. *pDisplayList++ = (C_MINX << 16) | pblt->MIN_X;
  732. *pDisplayList++ = (C_ACCUMX << 16) | pblt->ACCUM_X;
  733. *pDisplayList++ = (C_MAJY << 16) | pblt->MAJ_Y;
  734. *pDisplayList++ = (C_MINY << 16) | pblt->MIN_Y;
  735. *pDisplayList++ = (C_ACCUMY << 16) | pblt->ACCUM_Y;
  736. *pDisplayList++ = (C_MRX_0 << 16) | pblt->OP0_opMRDRAM.pt.X;
  737. *pDisplayList++ = (C_MRY_0 << 16) | pblt->OP0_opMRDRAM.pt.Y;
  738. *pDisplayList++ = (C_MRX_1 << 16) | pblt->OP1_opMRDRAM.pt.X;
  739. *pDisplayList++ = (C_MRY_1 << 16) | pblt->OP1_opMRDRAM.pt.Y;
  740. *pDisplayList++ = (C_BLTDEF << 16) | pblt->DRAWBLTDEF.lh.HI;
  741. *pDisplayList++ = (C_DRWDEF << 16) | pblt->DRAWBLTDEF.lh.LO;
  742. // MBLTEXTR_EX
  743. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_MBLTEXTR_EX, 1, 0);
  744. *pDisplayList++ = pblt->MBLTEXTR_EX.DW;
  745. *pDisplayList = wait_3d(0x3e0, 0);
  746. rc = qmExecuteDisplayList(Handle, pDisplayList, 0);
  747. #endif // !WINNT_VER40
  748. } /* DIR_DrvStrBlt65 */
  749. /***************************************************************************
  750. *
  751. * FUNCTION: DL_DrvStrMBlt
  752. *
  753. * DESCRIPTION:
  754. *
  755. ****************************************************************************/
  756. void DL_DrvStrMBlt
  757. (
  758. #ifdef WINNT_VER40
  759. PDEV *ppdev,
  760. DRIVERDATA *lpDDHALData,
  761. #else
  762. LPGLOBALDATA lpDDHALData,
  763. #endif
  764. autoblt_ptr pblt
  765. )
  766. {
  767. #ifdef WINNT_VER40 // WINNT_VER40
  768. #else // !WINNT_VER40
  769. DWORD *pDisplayList;
  770. qm_return rc;
  771. QMDLHandle Handle;
  772. DD_LOG(("DL_DrvStrMBlt - dst=%08lX dstext=%08lX src=%08lX\r\n",
  773. pblt->OP0_opRDRAM.DW,pblt->BLTEXT.DW,pblt->OP1_opRDRAM.DW));
  774. ASSERT( pblt->BLTEXT.pt.X != 0 );
  775. ASSERT( pblt->BLTEXT.pt.Y != 0 );
  776. DBG_MESSAGE(("DL_DrvStrMBlt: %4d,%4d -> %4d,%4d %4dx%4d %04x %4d %04x",
  777. pblt->OP1_opRDRAM.PT.X, pblt->OP1_opRDRAM.PT.Y,
  778. pblt->OP0_opRDRAM.PT.X, pblt->OP0_opRDRAM.PT.Y,
  779. pblt->BLTEXT.PT.X, pblt->BLTEXT.PT.Y,
  780. pblt->ACCUM_X, pblt->SRCX, pblt->LNCNTL.W));
  781. // check for overlap
  782. DL_DrvStrMBlt_OverlapCheck(
  783. #ifdef WINNT_VER40
  784. ppdev,
  785. #endif
  786. lpDDHALData,
  787. pblt);
  788. rc = qmAllocDisplayList(19*4, QM_DL_UNLOCKED, &Handle, &pDisplayList);
  789. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 15, 0);
  790. *pDisplayList++ = (C_LNCNTL << 16) | pblt->LNCNTL.W;
  791. *pDisplayList++ = (C_SHINC << 16) | pblt->SHRINKINC.W;
  792. *pDisplayList++ = (C_SRCX << 16) | pblt->SRCX;
  793. *pDisplayList++ = (C_MAJX << 16) | pblt->MAJ_X;
  794. *pDisplayList++ = (C_MINX << 16) | pblt->MIN_X;
  795. *pDisplayList++ = (C_ACCUMX << 16) | pblt->ACCUM_X;
  796. *pDisplayList++ = (C_MAJY << 16) | pblt->MAJ_Y;
  797. *pDisplayList++ = (C_MINY << 16) | pblt->MIN_Y;
  798. *pDisplayList++ = (C_ACCUMY << 16) | pblt->ACCUM_Y;
  799. *pDisplayList++ = (C_MRX_0 << 16) | pblt->OP0_opRDRAM.pt.X;
  800. *pDisplayList++ = (C_MRY_0 << 16) | pblt->OP0_opRDRAM.pt.Y;
  801. *pDisplayList++ = (C_MRX_1 << 16) | pblt->OP1_opRDRAM.pt.X;
  802. *pDisplayList++ = (C_MRY_1 << 16) | pblt->OP1_opRDRAM.pt.Y;
  803. *pDisplayList++ = (C_BLTDEF << 16) | pblt->DRAWBLTDEF.lh.HI;
  804. *pDisplayList++ = (C_DRWDEF << 16) | pblt->DRAWBLTDEF.lh.LO;
  805. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_MBLTEXTR_EX, 1, 0);
  806. *pDisplayList++ = pblt->BLTEXT.DW;
  807. *pDisplayList = wait_3d(0x3e0, 0);
  808. rc = qmExecuteDisplayList(Handle, pDisplayList, 0);
  809. #endif // !WINNT_VER40
  810. } /* DL_DrvStrMBlt */
  811. /***************************************************************************
  812. *
  813. * FUNCTION: DL_DrvStrMBltY
  814. *
  815. * DESCRIPTION: Write regs that don't vary over the stripes
  816. * Used in conjunction with DL_DrvStrMBltX
  817. *
  818. ****************************************************************************/
  819. void DL_DrvStrMBltY
  820. (
  821. #ifdef WINNT_VER40
  822. PDEV *ppdev,
  823. DRIVERDATA *lpDDHALData,
  824. #else
  825. LPGLOBALDATA lpDDHALData,
  826. #endif
  827. autoblt_ptr pblt
  828. )
  829. {
  830. #ifdef WINNT_VER40 // WINNT_VER40
  831. #else // !WINNT_VER40
  832. DWORD *pDisplayList;
  833. qm_return rc;
  834. QMDLHandle Handle;
  835. DD_LOG(("DL_DrvStrMBltY - dst.Y=%04X dstext.Y=%04X src=%04X\r\n",
  836. pblt->OP0_opRDRAM.pt.Y,pblt->BLTEXT.pt.Y,pblt->OP1_opRDRAM.pt.Y));
  837. ASSERT( pblt->BLTEXT.pt.Y != 0 );
  838. DBG_MESSAGE(("DrvStrMBltY: %4d,%4d -> %4d,%4d %4dx%4d %04x %4d %04x",
  839. pblt->OP1_opRDRAM.PT.X, pblt->OP1_opRDRAM.PT.Y,
  840. pblt->OP0_opRDRAM.PT.X, pblt->OP0_opRDRAM.PT.Y,
  841. pblt->BLTEXT.PT.X, pblt->BLTEXT.PT.Y,
  842. pblt->ACCUM_X, pblt->SRCX, pblt->LNCNTL.W));
  843. rc = qmAllocDisplayList(13*4, QM_DL_UNLOCKED, &Handle, &pDisplayList);
  844. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 11, 0);
  845. *pDisplayList++ = (C_LNCNTL << 16) | pblt->LNCNTL.W;
  846. *pDisplayList++ = (C_SHINC << 16) | pblt->SHRINKINC.W;
  847. *pDisplayList++ = (C_MAJX << 16) | pblt->MAJ_X;
  848. *pDisplayList++ = (C_MINX << 16) | pblt->MIN_X;
  849. *pDisplayList++ = (C_MAJY << 16) | pblt->MAJ_Y;
  850. *pDisplayList++ = (C_MINY << 16) | pblt->MIN_Y;
  851. *pDisplayList++ = (C_ACCUMY << 16) | pblt->ACCUM_Y;
  852. *pDisplayList++ = (C_MRY_0 << 16) | pblt->OP0_opRDRAM.pt.Y;
  853. *pDisplayList++ = (C_MRY_1 << 16) | pblt->OP1_opRDRAM.pt.Y;
  854. *pDisplayList++ = (C_BLTDEF << 16) | pblt->DRAWBLTDEF.lh.HI;
  855. *pDisplayList++ = (C_DRWDEF << 16) | pblt->DRAWBLTDEF.lh.LO;
  856. *pDisplayList = wait_3d(0x3e0, 0);
  857. rc = qmExecuteDisplayList(Handle, pDisplayList, 0);
  858. #endif // !WINNT_VER40
  859. } /* DL_DrvStrMBltY */
  860. /***************************************************************************
  861. *
  862. * FUNCTION: DL_DrvStrMBltX
  863. *
  864. * DESCRIPTION: Write stripe specific regs
  865. * Used in conjunction with DL_DrvStrMBltY
  866. *
  867. ****************************************************************************/
  868. void DL_DrvStrMBltX
  869. (
  870. #ifdef WINNT_VER40
  871. PDEV *ppdev,
  872. DRIVERDATA *lpDDHALData,
  873. #else
  874. LPGLOBALDATA lpDDHALData,
  875. #endif
  876. autoblt_ptr pblt
  877. )
  878. {
  879. #ifdef WINNT_VER40 // WINNT_VER40
  880. #else // !WINNT_VER40
  881. DWORD *pDisplayList;
  882. qm_return rc;
  883. QMDLHandle Handle;
  884. DD_LOG(("DL_DrvStrMBltX - dst.X=%04X dstext.X=%04X src.X=%04X\r\n",
  885. pblt->OP0_opRDRAM.pt.X,pblt->BLTEXT.pt.X,pblt->OP1_opRDRAM.pt.X));
  886. ASSERT( pblt->BLTEXT.pt.X != 0 );
  887. DBG_MESSAGE(("DrvStrMBltX: %4d,%4d -> %4d,%4d %4dx%4d %04x %4d %04x",
  888. pblt->OP1_opRDRAM.PT.X, pblt->OP1_opRDRAM.PT.Y,
  889. pblt->OP0_opRDRAM.PT.X, pblt->OP0_opRDRAM.PT.Y,
  890. pblt->BLTEXT.PT.X, pblt->BLTEXT.PT.Y,
  891. pblt->ACCUM_X, pblt->SRCX, pblt->LNCNTL.W));
  892. rc = qmAllocDisplayList(8*4, QM_DL_UNLOCKED, &Handle, &pDisplayList);
  893. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 4, 0);
  894. *pDisplayList++ = (C_SRCX << 16) | pblt->SRCX;
  895. *pDisplayList++ = (C_ACCUMX << 16) | pblt->ACCUM_X;
  896. *pDisplayList++ = (C_MRX_0 << 16) | pblt->OP0_opRDRAM.pt.X;
  897. *pDisplayList++ = (C_MRX_1 << 16) | pblt->OP1_opRDRAM.pt.X;
  898. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_MBLTEXTR_EX, 1, 0);
  899. *pDisplayList++ = pblt->BLTEXT.DW;
  900. *pDisplayList = wait_3d(0x3e0, 0);
  901. rc = qmExecuteDisplayList(Handle, pDisplayList, 0);
  902. #endif // !WINNT_VER40
  903. } /* DL_DrvStrMBltX */
  904. /***************************************************************************
  905. *
  906. * FUNCTION: DL_DrvStrBltY
  907. *
  908. * DESCRIPTION: Write regs that don't vary over the stripes
  909. * Used in conjunction with DL_DrvStrBltX
  910. *
  911. ****************************************************************************/
  912. void DL_DrvStrBltY
  913. (
  914. #ifdef WINNT_VER40
  915. PDEV *ppdev,
  916. DRIVERDATA *lpDDHALData,
  917. #else
  918. LPGLOBALDATA lpDDHALData,
  919. #endif
  920. autoblt_ptr pblt
  921. )
  922. {
  923. #ifdef WINNT_VER40 // WINNT_VER40
  924. #else // !WINNT_VER40
  925. DWORD *pDisplayList;
  926. qm_return rc;
  927. QMDLHandle Handle;
  928. DD_LOG(("DL_DrvStrBltY\r\n"));
  929. DBG_MESSAGE(("DL_DrvStrBltY: %4d,%4d -> %4d,%4d %4dx%4d %04x %4d %04x",
  930. pblt->OP1_opRDRAM.PT.X, pblt->OP1_opRDRAM.PT.Y,
  931. pblt->OP0_opRDRAM.PT.X, pblt->OP0_opRDRAM.PT.Y,
  932. pblt->BLTEXT.PT.X, pblt->BLTEXT.PT.Y,
  933. pblt->ACCUM_X, pblt->SRCX, pblt->LNCNTL.W));
  934. rc = qmAllocDisplayList(12*4, QM_DL_UNLOCKED, &Handle, &pDisplayList);
  935. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 10, 0);
  936. *pDisplayList++ = (C_LNCNTL << 16) | pblt->LNCNTL.W;
  937. *pDisplayList++ = (C_SHINC << 16) | pblt->SHRINKINC.W;
  938. *pDisplayList++ = (C_SRCX << 16) | pblt->SRCX;
  939. *pDisplayList++ = (C_MAJX << 16) | pblt->MAJ_X;
  940. *pDisplayList++ = (C_MINX << 16) | pblt->MIN_X;
  941. *pDisplayList++ = (C_MAJY << 16) | pblt->MAJ_Y;
  942. *pDisplayList++ = (C_MINY << 16) | pblt->MIN_Y;
  943. *pDisplayList++ = (C_ACCUMY << 16) | pblt->ACCUM_Y;
  944. *pDisplayList++ = (C_BLTDEF << 16) | pblt->DRAWBLTDEF.lh.HI;
  945. *pDisplayList++ = (C_DRWDEF << 16) | pblt->DRAWBLTDEF.lh.LO;
  946. *pDisplayList = wait_3d(0x3e0, 0);
  947. rc = qmExecuteDisplayList(Handle, pDisplayList, 0);
  948. #endif // !WINNT_VER40
  949. } /* DL_DrvStrBltY */
  950. /***************************************************************************
  951. *
  952. * FUNCTION: DL_DrvStrBltX
  953. *
  954. * DESCRIPTION: Write stripe specific regs
  955. * Used in conjunction with DL_DrvStrMBltY
  956. *
  957. ****************************************************************************/
  958. void DL_DrvStrBltX
  959. (
  960. #ifdef WINNT_VER40
  961. PDEV *ppdev,
  962. DRIVERDATA *lpDDHALData,
  963. #else
  964. LPGLOBALDATA lpDDHALData,
  965. #endif
  966. autoblt_ptr pblt
  967. )
  968. {
  969. #ifdef WINNT_VER40 // WINNT_VER40
  970. #else // !WINNT_VER40
  971. DWORD *pDisplayList;
  972. qm_return rc;
  973. QMDLHandle Handle;
  974. DD_LOG(("DL_DrvStrBltX - dst=%08lX dstext=%08lX src=%08lX\r\n",
  975. pblt->OP0_opRDRAM.DW,pblt->BLTEXT.DW,pblt->OP1_opRDRAM.DW));
  976. ASSERT( pblt->BLTEXT.pt.X != 0 );
  977. ASSERT( pblt->BLTEXT.pt.Y != 0 );
  978. DBG_MESSAGE(("DL_DrvStrBltX: %4d,%4d -> %4d,%4d %4dx%4d %04x %4d %04x",
  979. pblt->OP1_opRDRAM.PT.X, pblt->OP1_opRDRAM.PT.Y,
  980. pblt->OP0_opRDRAM.PT.X, pblt->OP0_opRDRAM.PT.Y,
  981. pblt->BLTEXT.PT.X, pblt->BLTEXT.PT.Y,
  982. pblt->ACCUM_X, pblt->SRCX, pblt->LNCNTL.W));
  983. rc = qmAllocDisplayList(9*4, QM_DL_UNLOCKED, &Handle, &pDisplayList);
  984. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 5, 0);
  985. *pDisplayList++ = (C_ACCUMX << 16) | pblt->ACCUM_X;
  986. *pDisplayList++ = (C_RX_0 << 16) | pblt->OP0_opRDRAM.pt.X;
  987. *pDisplayList++ = (C_RY_0 << 16) | pblt->OP0_opRDRAM.pt.Y;
  988. *pDisplayList++ = (C_RX_1 << 16) | pblt->OP1_opRDRAM.pt.X;
  989. *pDisplayList++ = (C_RY_1 << 16) | pblt->OP1_opRDRAM.pt.Y;
  990. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_BLTEXTR_EX, 1, 0);
  991. *pDisplayList++ = pblt->BLTEXT.DW;
  992. *pDisplayList = wait_3d(0x3e0, 0);
  993. rc = qmExecuteDisplayList(Handle, pDisplayList, 0);
  994. #endif // !WINNT_VER40
  995. } /* DL_DrvStrBltX */
  996. #if ENABLE_CLIPPEDBLTS
  997. /***************************************************************************
  998. *
  999. * FUNCTION: DL_HWClippedDrvDstBlt
  1000. *
  1001. * DESCRIPTION:
  1002. *
  1003. ****************************************************************************/
  1004. void DL_HWClippedDrvDstBlt
  1005. (
  1006. #ifdef WINNT_VER40
  1007. PDEV *ppdev,
  1008. DRIVERDATA *lpDDHALData,
  1009. #endif
  1010. DWORD dwDrawBlt,
  1011. DWORD dwDstCoord,
  1012. DWORD dwBgColor,
  1013. DWORD dwExtents,
  1014. DWORD dwDstBaseXY,
  1015. DWORD dwRectCnt,
  1016. LPRECT pDestRects
  1017. )
  1018. {
  1019. #ifdef WINNT_VER40 // WINNT_VER40
  1020. #else // !WINNT_VER40
  1021. DWORD *pDisplayList;
  1022. qm_return rc;
  1023. QMDLHandle Handle;
  1024. DD_LOG(("DL_HWClippedDrvDstBlt - dst=%08lX ext=%08lX color=%08lX\r\n",
  1025. dwDstCoord,dwExtents,dwBgColor));
  1026. // check for negative dst coordinates, hw can't deal with negative OP0 values
  1027. if (0 > (short)((REG32 *)&dwDstCoord)->pt.X)
  1028. {
  1029. (short)((REG32 *)&dwExtents)->pt.X += (short)((REG32 *)&dwDstCoord)->pt.X;
  1030. ((REG32 *)&dwDstCoord)->pt.X = 0;
  1031. }
  1032. if (0 > (short)((REG32 *)&dwDstCoord)->pt.Y)
  1033. {
  1034. (short)((REG32 *)&dwExtents)->pt.Y += (short)((REG32 *)&dwDstCoord)->pt.Y;
  1035. ((REG32 *)&dwDstCoord)->pt.Y = 0;
  1036. }
  1037. rc = qmAllocDisplayList((10+dwRectCnt*4)*4, QM_DL_UNLOCKED, &Handle, &pDisplayList);
  1038. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 8, 0);
  1039. // setup blt, write BLTEXT reg with extent which doesn't fire off blt
  1040. // BLTDEF & DRAWDEF
  1041. *pDisplayList++ = (C_BLTDEF << 16) | HIWORD(dwDrawBlt);
  1042. *pDisplayList++ = (C_DRWDEF << 16) | LOWORD(dwDrawBlt);
  1043. // BGCOLOR
  1044. *pDisplayList++ = (C_BG_L << 16) | LOWORD(dwBgColor);
  1045. *pDisplayList++ = (C_BG_H << 16) | HIWORD(dwBgColor);
  1046. // OP0_opRDRAM
  1047. *pDisplayList++ = (C_RX_0 << 16) | LOWORD(dwDstCoord);
  1048. *pDisplayList++ = (C_RY_0 << 16) | HIWORD(dwDstCoord);
  1049. // BLTEXT
  1050. *pDisplayList++ = (C_BLTEXT_X << 16) | LOWORD(dwExtents);
  1051. *pDisplayList++ = (C_BLTEXT_Y << 16) | HIWORD(dwExtents);
  1052. // loop over clip list
  1053. do
  1054. {
  1055. REG32 UpperLeft;
  1056. REG32 LowerRight;
  1057. // compute cliprect coords
  1058. UpperLeft.DW = dwDstBaseXY + MAKELONG(pDestRects->left, pDestRects->top);
  1059. LowerRight.DW = dwDstBaseXY + MAKELONG(pDestRects->right, pDestRects->bottom);
  1060. // write clipping regs
  1061. // CLIPULE
  1062. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_CLIPULE, 1, 0);
  1063. *pDisplayList++ = UpperLeft.DW;
  1064. // CLIPLOR_EX
  1065. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_CLIPLOR_EX, 1, 0);
  1066. *pDisplayList++ = LowerRight.DW;
  1067. pDestRects++;
  1068. } while (0 < --dwRectCnt);
  1069. *pDisplayList = wait_3d(0x3e0, 0);
  1070. rc = qmExecuteDisplayList(Handle, pDisplayList, 0);
  1071. #endif // !WINNT_VER40
  1072. } /* DL_HWClippedDrvDstBlt */
  1073. /***************************************************************************
  1074. *
  1075. * FUNCTION: DL_HWClippedDrvDstMBlt
  1076. *
  1077. * DESCRIPTION:
  1078. *
  1079. ****************************************************************************/
  1080. void DL_HWClippedDrvDstMBlt
  1081. (
  1082. #ifdef WINNT_VER40
  1083. PDEV *ppdev,
  1084. DRIVERDATA *lpDDHALData,
  1085. #endif
  1086. DWORD dwDrawBlt,
  1087. DWORD dwDstCoord,
  1088. DWORD dwBgColor,
  1089. DWORD dwExtents,
  1090. DWORD dwDstBaseXY,
  1091. DWORD dwRectCnt,
  1092. LPRECT pDestRects
  1093. )
  1094. {
  1095. #ifdef WINNT_VER40 // WINNT_VER40
  1096. #else // !WINNT_VER40
  1097. const int nBytesPixel = BYTESPERPIXEL;
  1098. DWORD *pDisplayList;
  1099. qm_return rc;
  1100. QMDLHandle Handle;
  1101. DD_LOG(("DL_HWClippedDrvDstMBlt - dst=%08lX ext=%08lX color=%08lX\r\n",
  1102. dwDstCoord,dwExtents,dwBgColor));
  1103. // check for negative dst coordinates, hw can't deal with negative OP0 values
  1104. if (0 > (short)((REG32 *)&dwDstCoord)->pt.X)
  1105. {
  1106. (short)((REG32 *)&dwExtents)->pt.X += (short)((REG32 *)&dwDstCoord)->pt.X;
  1107. ((REG32 *)&dwDstCoord)->pt.X = 0;
  1108. }
  1109. if (0 > (short)((REG32 *)&dwDstCoord)->pt.Y)
  1110. {
  1111. (short)((REG32 *)&dwExtents)->pt.Y += (short)((REG32 *)&dwDstCoord)->pt.Y;
  1112. ((REG32 *)&dwDstCoord)->pt.Y = 0;
  1113. }
  1114. rc = qmAllocDisplayList((10+dwRectCnt*4)*4, QM_DL_UNLOCKED, &Handle, &pDisplayList);
  1115. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 8, 0);
  1116. // setup blt, write BLTEXT reg with extent which doesn't fire off blt
  1117. // BLTDEF & DRAWDEF
  1118. *pDisplayList++ = (C_BLTDEF << 16) | HIWORD(dwDrawBlt);
  1119. *pDisplayList++ = (C_DRWDEF << 16) | LOWORD(dwDrawBlt);
  1120. // BGCOLOR
  1121. *pDisplayList++ = (C_BG_L << 16) | LOWORD(dwBgColor);
  1122. *pDisplayList++ = (C_BG_H << 16) | HIWORD(dwBgColor);
  1123. // OP0_opMRDRAM
  1124. *pDisplayList++ = (C_MRX_0 << 16) | LOWORD(dwDstCoord);
  1125. *pDisplayList++ = (C_MRY_0 << 16) | HIWORD(dwDstCoord);
  1126. // MBLTEXT
  1127. *pDisplayList++ = (C_MBLTEXT_X << 16) | LOWORD(dwExtents);
  1128. *pDisplayList++ = (C_MBLTEXT_Y << 16) | HIWORD(dwExtents);
  1129. // loop over clip list
  1130. do
  1131. {
  1132. REG32 UpperLeft;
  1133. REG32 LowerRight;
  1134. // compute cliprect coords
  1135. UpperLeft.DW = dwDstBaseXY + MAKELONG(pDestRects->left, pDestRects->top);
  1136. LowerRight.DW = dwDstBaseXY + MAKELONG(pDestRects->right, pDestRects->bottom);
  1137. UpperLeft.pt.X *= nBytesPixel;
  1138. LowerRight.pt.X *= nBytesPixel;
  1139. // write clipping regs
  1140. // MCLIPULE
  1141. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_MCLIPULE, 1, 0);
  1142. *pDisplayList++ = UpperLeft.DW;
  1143. // MCLIPLOR_EX
  1144. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_MCLIPLOR_EX, 1, 0);
  1145. *pDisplayList++ = LowerRight.DW;
  1146. pDestRects++;
  1147. } while (0 < --dwRectCnt);
  1148. *pDisplayList = wait_3d(0x3e0, 0);
  1149. rc = qmExecuteDisplayList(Handle, pDisplayList, 0);
  1150. #endif // !WINNT_VER40
  1151. } /* DL_HWClippedDrvDstMBlt */
  1152. /***************************************************************************
  1153. *
  1154. * FUNCTION: DL_HWClippedDrvSrcBlt
  1155. *
  1156. * DESCRIPTION:
  1157. *
  1158. ****************************************************************************/
  1159. void DL_HWClippedDrvSrcBlt
  1160. (
  1161. #ifdef WINNT_VER40
  1162. PDEV *ppdev,
  1163. DRIVERDATA *lpDDHALData,
  1164. #endif
  1165. DWORD dwDrawBlt,
  1166. DWORD dwDstCoord,
  1167. DWORD dwSrcCoord,
  1168. DWORD dwKeyCoord,
  1169. DWORD dwKeyColor,
  1170. DWORD dwExtents,
  1171. DWORD dwDstBaseXY,
  1172. DWORD dwSrcBaseXY,
  1173. DWORD dwRectCnt,
  1174. LPRECT pDestRects
  1175. )
  1176. {
  1177. #ifdef WINNT_VER40 // WINNT_VER40
  1178. #else // !WINNT_VER40
  1179. DWORD *pDisplayList;
  1180. qm_return rc;
  1181. QMDLHandle Handle;
  1182. // Handle overlapped regions
  1183. const int xDelta = (int)LOWORD(dwDstCoord) - (int)LOWORD(dwSrcCoord);
  1184. DD_LOG(("DL_HWClippedDrvSrcBlt - dst=%08lX src=%08lX ext=%08lX color=%08lX\r\n",
  1185. dwDstCoord,dwSrcCoord,dwExtents,dwKeyColor));
  1186. // check for negative dst coordinates, hw can't deal with negative OP0 values
  1187. if (0 > (short)((REG32 *)&dwDstCoord)->pt.X)
  1188. {
  1189. // reduce extent.X
  1190. (short)((REG32 *)&dwExtents)->pt.X += (short)((REG32 *)&dwDstCoord)->pt.X;
  1191. // bump src.X to right
  1192. (short)((REG32 *)&dwSrcCoord)->pt.X -= (short)((REG32 *)&dwDstCoord)->pt.X;
  1193. if ((DD_TRANS | DD_TRANSOP) & dwDrawBlt)
  1194. // bump key.X to right
  1195. (short)((REG32 *)&dwKeyCoord)->pt.X -= (short)((REG32 *)&dwKeyCoord)->pt.X;
  1196. // clear dst.X
  1197. ((REG32 *)&dwDstCoord)->pt.X = 0;
  1198. }
  1199. if (0 > (short)((REG32 *)&dwDstCoord)->pt.Y)
  1200. {
  1201. // reduce extent.Y
  1202. (short)((REG32 *)&dwExtents)->pt.Y += (short)((REG32 *)&dwDstCoord)->pt.Y;
  1203. // bump src.Y down
  1204. (short)((REG32 *)&dwSrcCoord)->pt.Y -= (short)((REG32 *)&dwDstCoord)->pt.Y;
  1205. if ((DD_TRANS | DD_TRANSOP) & dwDrawBlt)
  1206. // bump key.Y down
  1207. (short)((REG32 *)&dwKeyCoord)->pt.Y -= (short)((REG32 *)&dwKeyCoord)->pt.Y;
  1208. // clean dst.Y
  1209. ((REG32 *)&dwDstCoord)->pt.Y = 0;
  1210. }
  1211. // Check for x overlap
  1212. if ( abs(xDelta) < (int)LOWORD(dwExtents) )
  1213. {
  1214. const int yDelta = (int)HIWORD(dwDstCoord) - (int)HIWORD(dwSrcCoord);
  1215. if ( (yDelta > 0) && (yDelta < (int)HIWORD(dwExtents)) )
  1216. {
  1217. const DWORD dwDelta = (dwExtents & MAKELONG(0, -1)) - MAKELONG(0, 1);
  1218. // Convert to a bottom-up blt.
  1219. dwDrawBlt |= MAKELONG(0, BD_YDIR);
  1220. dwDstCoord += dwDelta;
  1221. dwSrcCoord += dwDelta;
  1222. dwKeyCoord += dwDelta;
  1223. }
  1224. // are we sliding to the right?
  1225. else if ( (xDelta > 0) && (yDelta == 0) )
  1226. {
  1227. const DWORD dwDelta = MAKELONG(xDelta, 0);
  1228. // Blt the overlapped piece first
  1229. DL_HWClippedDrvSrcBlt(
  1230. #ifdef WINNT_VER40
  1231. ppdev,
  1232. lpDDHALData,
  1233. #endif
  1234. dwDrawBlt,
  1235. dwDstCoord+dwDelta,
  1236. dwSrcCoord+dwDelta,
  1237. dwKeyCoord+dwDelta,
  1238. dwKeyColor,
  1239. dwExtents-dwDelta,
  1240. dwDstBaseXY,
  1241. dwSrcBaseXY,
  1242. dwRectCnt,
  1243. pDestRects);
  1244. // Subtract the overlap from the original extents.
  1245. dwExtents = MAKELONG(xDelta, HIWORD(dwExtents));
  1246. }
  1247. }
  1248. rc = qmAllocDisplayList((14+dwRectCnt*4)*4, QM_DL_UNLOCKED, &Handle, &pDisplayList);
  1249. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 12, 0);
  1250. // setup blt, write BLTEXT reg with extent which doesn't fire off blt
  1251. // BLTDEF & DRAWDEF
  1252. *pDisplayList++ = (C_BLTDEF << 16) | HIWORD(dwDrawBlt);
  1253. *pDisplayList++ = (C_DRWDEF << 16) | LOWORD(dwDrawBlt);
  1254. // OP0_opRDRAM
  1255. *pDisplayList++ = (C_RX_0 << 16) | LOWORD(dwDstCoord);
  1256. *pDisplayList++ = (C_RY_0 << 16) | HIWORD(dwDstCoord);
  1257. // OP1_opRDRAM
  1258. *pDisplayList++ = (C_RX_1 << 16) | LOWORD(dwSrcCoord);
  1259. *pDisplayList++ = (C_RY_1 << 16) | HIWORD(dwSrcCoord);
  1260. // OP2_opRDRAM
  1261. *pDisplayList++ = (C_RX_2 << 16) | LOWORD(dwKeyCoord);
  1262. *pDisplayList++ = (C_RY_2 << 16) | HIWORD(dwKeyCoord);
  1263. // BGCOLOR
  1264. *pDisplayList++ = (C_BG_L << 16) | LOWORD(dwKeyColor);
  1265. *pDisplayList++ = (C_BG_H << 16) | HIWORD(dwKeyColor);
  1266. // BLTEXT
  1267. *pDisplayList++ = (C_BLTEXT_X << 16) | LOWORD(dwExtents);
  1268. *pDisplayList++ = (C_BLTEXT_Y << 16) | HIWORD(dwExtents);
  1269. // loop over clip list
  1270. do
  1271. {
  1272. REG32 UpperLeft;
  1273. REG32 LowerRight;
  1274. // compute cliprect coords
  1275. UpperLeft.DW = dwDstBaseXY + MAKELONG(pDestRects->left, pDestRects->top);
  1276. LowerRight.DW = dwDstBaseXY + MAKELONG(pDestRects->right, pDestRects->bottom);
  1277. // write clipping regs
  1278. // CLIPULE
  1279. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_CLIPULE, 1, 0);
  1280. *pDisplayList++ = UpperLeft.DW;
  1281. // CLIPLOR_EX
  1282. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_CLIPLOR_EX, 1, 0);
  1283. *pDisplayList++ = LowerRight.DW;
  1284. pDestRects++;
  1285. } while (0 < --dwRectCnt);
  1286. *pDisplayList = wait_3d(0x3e0, 0);
  1287. rc = qmExecuteDisplayList(Handle, pDisplayList, 0);
  1288. #endif // !WINNT_VER40
  1289. } /* DL_HWClippedDrvSrcBlt */
  1290. /***************************************************************************
  1291. *
  1292. * FUNCTION: DL_SWClippedDrvDstBlt
  1293. *
  1294. * DESCRIPTION:
  1295. *
  1296. ****************************************************************************/
  1297. void DL_SWClippedDrvDstBlt
  1298. (
  1299. #ifdef WINNT_VER40
  1300. PDEV *ppdev,
  1301. DRIVERDATA *lpDDHALData,
  1302. #endif
  1303. DWORD dwDrawBlt,
  1304. DWORD dwDstCoord,
  1305. DWORD dwBgColor,
  1306. DWORD dwExtents,
  1307. DWORD dwDstBaseXY,
  1308. DWORD dwRectCnt,
  1309. LPRECT pDestRects
  1310. )
  1311. {
  1312. #ifdef WINNT_VER40 // WINNT_VER40
  1313. #else // !WINNT_VER40
  1314. DWORD *pDisplayList;
  1315. qm_return rc;
  1316. QMDLHandle Handle;
  1317. DD_LOG(("DL_SWClippedDrvDstBlt - dst=%08lX ext=%08lX color=%08lX\r\n",
  1318. dwDstCoord,dwExtents,dwBgColor));
  1319. // make sure DD_CLIP isn't set in drawdef
  1320. dwDrawBlt &= ~DD_CLIP;
  1321. rc = qmAllocDisplayList((6+dwRectCnt*4)*4, QM_DL_UNLOCKED, &Handle, &pDisplayList);
  1322. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 4, 0);
  1323. // write regs that don't vary over rectangles
  1324. // BLTDEF & DRAWDEF
  1325. *pDisplayList++ = (C_BLTDEF << 16) | HIWORD(dwDrawBlt);
  1326. *pDisplayList++ = (C_DRWDEF << 16) | LOWORD(dwDrawBlt);
  1327. // BGCOLOR
  1328. *pDisplayList++ = (C_BG_L << 16) | LOWORD(dwBgColor);
  1329. *pDisplayList++ = (C_BG_H << 16) | HIWORD(dwBgColor);
  1330. // loop over clip list
  1331. do
  1332. {
  1333. DDRECTL DstDDRect;
  1334. // compute cliprect coords
  1335. DstDDRect.loc.DW = dwDstBaseXY + MAKELONG(pDestRects->left, pDestRects->top);
  1336. DstDDRect.ext.pt.X = (WORD)(pDestRects->right - pDestRects->left);
  1337. DstDDRect.ext.pt.Y = (WORD)(pDestRects->bottom - pDestRects->top);
  1338. // write OP0 and bltext regs
  1339. // OP0_opRDRAM
  1340. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_OP0_OPRDRAM, 1, 0);
  1341. *pDisplayList++ = DstDDRect.loc.DW;
  1342. // BLTEXT_EX
  1343. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_BLTEXT_EX, 1, 0);
  1344. *pDisplayList++ = DstDDRect.ext.DW;
  1345. pDestRects++;
  1346. } while (0 < --dwRectCnt);
  1347. *pDisplayList = wait_3d(0x3e0, 0);
  1348. rc = qmExecuteDisplayList(Handle, pDisplayList, 0);
  1349. #endif // !WINNT_VER40
  1350. } /* DL_SWClippedDrvDstBlt */
  1351. /***************************************************************************
  1352. *
  1353. * FUNCTION: DL_SWClippedDrvDstMBlt
  1354. *
  1355. * DESCRIPTION:
  1356. *
  1357. ****************************************************************************/
  1358. void DL_SWClippedDrvDstMBlt
  1359. (
  1360. #ifdef WINNT_VER40
  1361. PDEV *ppdev,
  1362. DRIVERDATA *lpDDHALData,
  1363. #endif
  1364. DWORD dwDrawBlt,
  1365. DWORD dwDstCoord,
  1366. DWORD dwBgColor,
  1367. DWORD dwExtents,
  1368. DWORD dwDstBaseXY,
  1369. DWORD dwRectCnt,
  1370. LPRECT pDestRects
  1371. )
  1372. {
  1373. #ifdef WINNT_VER40 // WINNT_VER40
  1374. #else // !WINNT_VER40
  1375. const int nBytesPixel = BYTESPERPIXEL;
  1376. DWORD *pDisplayList;
  1377. qm_return rc;
  1378. QMDLHandle Handle;
  1379. DD_LOG(("DL_SWClippedDrvDstMBlt - dst=%08lX ext=%08lX color=%08lX\r\n",
  1380. dwDstCoord,dwExtents,dwBgColor));
  1381. // make sure DD_CLIP isn't set in drawdef
  1382. dwDrawBlt &= ~DD_CLIP;
  1383. rc = qmAllocDisplayList((6+dwRectCnt*4)*4, QM_DL_UNLOCKED, &Handle, &pDisplayList);
  1384. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 4, 0);
  1385. // write regs that don't vary over rectangles
  1386. // BLTDEF & DRAWDEF
  1387. *pDisplayList++ = (C_BLTDEF << 16) | HIWORD(dwDrawBlt);
  1388. *pDisplayList++ = (C_DRWDEF << 16) | LOWORD(dwDrawBlt);
  1389. // BGCOLOR
  1390. *pDisplayList++ = (C_BG_L << 16) | LOWORD(dwBgColor);
  1391. *pDisplayList++ = (C_BG_H << 16) | HIWORD(dwBgColor);
  1392. // loop over clip list
  1393. do
  1394. {
  1395. DDRECTL DstDDRect;
  1396. // compute cliprect coords
  1397. DstDDRect.loc.DW = dwDstBaseXY + MAKELONG(pDestRects->left, pDestRects->top);
  1398. DstDDRect.loc.pt.X *= nBytesPixel;
  1399. DstDDRect.ext.pt.X = (WORD)(pDestRects->right - pDestRects->left) * nBytesPixel;
  1400. DstDDRect.ext.pt.Y = (WORD)(pDestRects->bottom - pDestRects->top);
  1401. // write OP0 and bltext regs
  1402. // OP0_opMRDRAM
  1403. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_OP0_OPMRDRAM, 1, 0);
  1404. *pDisplayList++ = DstDDRect.loc.DW;
  1405. // MBLTEXT_EX
  1406. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_MBLTEXT_EX, 1, 0);
  1407. *pDisplayList++ = DstDDRect.ext.DW;
  1408. pDestRects++;
  1409. } while (0 < --dwRectCnt);
  1410. *pDisplayList = wait_3d(0x3e0, 0);
  1411. rc = qmExecuteDisplayList(Handle, pDisplayList, 0);
  1412. #endif // !WINNT_VER40
  1413. } /* DL_SWClippedDrvDstMBlt */
  1414. /***************************************************************************
  1415. *
  1416. * FUNCTION: DL_SWClippedDrvSrcBlt
  1417. *
  1418. * DESCRIPTION:
  1419. *
  1420. ****************************************************************************/
  1421. void DL_SWClippedDrvSrcBlt
  1422. (
  1423. #ifdef WINNT_VER40
  1424. PDEV *ppdev,
  1425. DRIVERDATA *lpDDHALData,
  1426. #endif
  1427. DWORD dwDrawBlt,
  1428. DWORD dwDstCoord,
  1429. DWORD dwSrcCoord,
  1430. DWORD dwKeyCoord,
  1431. DWORD dwKeyColor,
  1432. DWORD dwExtents,
  1433. DWORD dwDstBaseXY,
  1434. DWORD dwSrcBaseXY,
  1435. DWORD dwRectCnt,
  1436. LPRECT pDestRects
  1437. )
  1438. {
  1439. #ifdef WINNT_VER40 // WINNT_VER40
  1440. #else // !WINNT_VER40
  1441. DWORD *pDisplayList;
  1442. qm_return rc;
  1443. QMDLHandle Handle;
  1444. // Handle overlapped regions
  1445. const int xDelta = (int)LOWORD(dwDstCoord) - (int)LOWORD(dwSrcCoord);
  1446. DD_LOG(("DL_SWClippedDrvSrcBlt - dst=%08lX src=%08lX ext=%08lX color=%08lX\r\n",
  1447. dwDstCoord,dwSrcCoord,dwExtents,dwKeyColor));
  1448. // make sure DD_CLIP isn't set in drawdef
  1449. dwDrawBlt &= ~DD_CLIP;
  1450. // Check for x overlap
  1451. if ( abs(xDelta) < (int)LOWORD(dwExtents) )
  1452. {
  1453. const int yDelta = (int)HIWORD(dwDstCoord) - (int)HIWORD(dwSrcCoord);
  1454. if ( (yDelta > 0) && (yDelta < (int)HIWORD(dwExtents)) )
  1455. {
  1456. const DWORD dwDelta = (dwExtents & MAKELONG(0, -1)) - MAKELONG(0, 1);
  1457. // Convert to a bottom-up blt.
  1458. dwDrawBlt |= MAKELONG(0, BD_YDIR);
  1459. dwDstCoord += dwDelta;
  1460. dwSrcCoord += dwDelta;
  1461. dwKeyCoord += dwDelta;
  1462. }
  1463. // are we sliding to the right?
  1464. else if ( (xDelta > 0) && (yDelta == 0) )
  1465. {
  1466. const DWORD dwDelta = MAKELONG(xDelta, 0);
  1467. // Blt the overlapped piece first
  1468. DL_SWClippedDrvSrcBlt(
  1469. #ifdef WINNT_VER40
  1470. ppdev,
  1471. lpDDHALData,
  1472. #endif
  1473. dwDrawBlt,
  1474. dwDstCoord+dwDelta,
  1475. dwSrcCoord+dwDelta,
  1476. dwKeyCoord+dwDelta,
  1477. dwKeyColor,
  1478. dwExtents-dwDelta,
  1479. dwDstBaseXY,
  1480. dwSrcBaseXY,
  1481. dwRectCnt,
  1482. pDestRects);
  1483. // Subtract the overlap from the original extents.
  1484. dwExtents = MAKELONG(xDelta, HIWORD(dwExtents));
  1485. }
  1486. }
  1487. rc = qmAllocDisplayList((6+dwRectCnt*9)*4, QM_DL_UNLOCKED, &Handle, &pDisplayList);
  1488. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 4, 0);
  1489. // write regs that don't vary over rectangles
  1490. // BLTDEF & DRAWDEF
  1491. *pDisplayList++ = (C_BLTDEF << 16) | HIWORD(dwDrawBlt);
  1492. *pDisplayList++ = (C_DRWDEF << 16) | LOWORD(dwDrawBlt);
  1493. // BGCOLOR
  1494. *pDisplayList++ = (C_BG_L << 16) | LOWORD(dwKeyColor);
  1495. *pDisplayList++ = (C_BG_H << 16) | HIWORD(dwKeyColor);
  1496. // loop over clip list
  1497. do
  1498. {
  1499. DDRECTL DstDDRect;
  1500. DDRECTL SrcDDRect;
  1501. // compute dst cliprect coords
  1502. DstDDRect.loc.DW = dwDstBaseXY + MAKELONG(pDestRects->left, pDestRects->top);
  1503. DstDDRect.ext.pt.X = (WORD)(pDestRects->right - pDestRects->left);
  1504. DstDDRect.ext.pt.Y = (WORD)(pDestRects->bottom - pDestRects->top);
  1505. // compute src cliprect coords
  1506. SrcDDRect.loc.DW = dwSrcBaseXY + MAKELONG(pDestRects->left, pDestRects->top);
  1507. // don't care about src extent, it's the same as dst extent
  1508. //SrcDDRect.ext.pt.X = (WORD)(pDestRects->right - pDestRects->left);
  1509. //SrcDDRect.ext.pt.Y = (WORD)(pDestRects->bottom - pDestRects->top);
  1510. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, COMMAND_2D, 6, 0);
  1511. // write OP0, OP1, OP2 and bltext regs
  1512. if ((DD_TRANS | DD_TRANSOP) == ((DD_TRANS | DD_TRANSOP) & dwDrawBlt))
  1513. {
  1514. // dst color key
  1515. // OP2_opRDRAM
  1516. *pDisplayList++ = (C_RX_2 << 16) | DstDDRect.loc.pt.X;
  1517. *pDisplayList++ = (C_RY_2 << 16) | DstDDRect.loc.pt.Y;
  1518. }
  1519. else if (DD_TRANS == ((DD_TRANS | DD_TRANSOP) & dwDrawBlt))
  1520. {
  1521. // src color key
  1522. // OP2_opRDRAM
  1523. *pDisplayList++ = (C_RX_2 << 16) | SrcDDRect.loc.pt.X;
  1524. *pDisplayList++ = (C_RY_2 << 16) | SrcDDRect.loc.pt.Y;
  1525. }
  1526. else
  1527. {
  1528. // OP2_opRDRAM
  1529. *pDisplayList++ = (C_RX_2 << 16) | 0;
  1530. *pDisplayList++ = (C_RY_2 << 16) | 0;
  1531. }
  1532. // OP0_opRDRAM
  1533. *pDisplayList++ = (C_RX_0 << 16) | DstDDRect.loc.pt.X;
  1534. *pDisplayList++ = (C_RY_0 << 16) | DstDDRect.loc.pt.Y;
  1535. // OP1_opRDRAM
  1536. *pDisplayList++ = (C_RX_1 << 16) | SrcDDRect.loc.pt.X;
  1537. *pDisplayList++ = (C_RY_1 << 16) | SrcDDRect.loc.pt.Y;
  1538. // BLTEXT_EX
  1539. *pDisplayList++ = write_dev_regs(DEV_ENG2D, 0, L2D_BLTEXT_EX, 1, 0);
  1540. *pDisplayList++ = DstDDRect.ext.DW;
  1541. pDestRects++;
  1542. } while (0 < --dwRectCnt);
  1543. *pDisplayList = wait_3d(0x3e0, 0);
  1544. rc = qmExecuteDisplayList(Handle, pDisplayList, 0);
  1545. #endif // !WINNT_VER40
  1546. } /* DL_SWClippedDrvSrcBlt */
  1547. #endif // ENABLE_CLIPPEDBLTS
  1548. #endif // WINNT_VER35