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.

2005 lines
65 KiB

  1. /**************************************************************************
  2. ***************************************************************************
  3. *
  4. * Copyright (c) 1997, Cirrus Logic, Inc.
  5. * All Rights Reserved
  6. *
  7. * FILE: blt65.c
  8. *
  9. * DESCRIPTION:
  10. *
  11. * REVISION HISTORY:
  12. *
  13. * $Log: //uinac/log/log/laguna/ddraw/src/Blt65.c $
  14. *
  15. * Rev 1.47 Jun 21 1998 12:16:46 clang
  16. * Fixed PDR#11507 CK with ConCurrent RAM has the same transparent
  17. * blt problem with AC
  18. *
  19. * Rev 1.46 May 01 1998 15:47:06 frido
  20. * Fixed the checks for the programmable blitter stride.
  21. *
  22. * Rev 1.45 May 01 1998 13:37:06 frido
  23. * Copied programmable blitter stride to Windows 95 code as well.
  24. *
  25. * Rev 1.44 May 01 1998 11:12:38 frido
  26. * Added test for programmable blitter stride.
  27. *
  28. * Rev 1.43 Feb 24 1998 11:36:56 frido
  29. * The overlay data has been changed in Windows NT 5.0.
  30. *
  31. * Rev 1.42 Feb 16 1998 16:23:06 frido
  32. * Moved the PFN_UPDATEFLIPSTATUS into Windows 95 specific region.
  33. *
  34. * Rev 1.41 14 Jan 1998 06:14:02 eleland
  35. *
  36. * added support for display list flipping: calls to UpdateFlipStatus are
  37. * thru function pointer pfnUpdateFlipStatus
  38. *
  39. * Rev 1.40 06 Jan 1998 15:01:58 xcong
  40. * Pass lpDDHALData into some functions and macros for multi-monitor support.
  41. *
  42. * Rev 1.39 06 Jan 1998 11:52:16 xcong
  43. * change pDriverData into local lpDDHALData for multi-monitor support.
  44. *
  45. * Rev 1.38 28 Oct 1997 15:33:24 RUSSL
  46. * src colorkey blts are faster and less work for the hw if just OP2 is used
  47. * with a rop of F0 rather than using both OP1 & OP2 with a rop of CC
  48. * To get back the old way, set the OP2_ONLY_SRC_COLORKEY define to 0
  49. *
  50. * Rev 1.37 16 Oct 1997 17:01:34 RUSSL
  51. * In Blt65, if REMOVE_GLOBAL_VARS is nonzero, get pdevice pointer from
  52. * DDRAWI_DIRECTDRAW_GBL struct. It's a 16:16 ptr so call an asm function
  53. * to convert it to a 32 bit linear address and then store this in
  54. * DDRAWI_DIRECTDRAW_GBL dwReserved1 element.
  55. *
  56. * Rev 1.36 03 Oct 1997 15:45:12 RUSSL
  57. * Initial changes for use of hw clipped blts
  58. * All changes wrapped in #if ENABLE_CLIPPEDBLTS/#endif blocks and
  59. * ENABLE_CLIPPEDBLTS defaults to 0 (so the code is disabled)
  60. *
  61. * Rev 1.35 01 Oct 1997 12:57:20 eleland
  62. * added check in blt65() to detect blts to host texture surfaces and
  63. * punt those blts back to the ddraw hel
  64. *
  65. * Rev 1.34 20 Aug 1997 15:36:30 RUSSL
  66. * Added ColorKeyBlt24 function.
  67. * With 256 byte fetch disabled, SrcColorKey blts seem to be working
  68. * correctly at 24bpp and DstColorKey blts appear to be working correctly
  69. * for the tddraw BLT, single DESTKEY, VMem to Primary case but running
  70. * foxbear in 24bpp modes with only DDCKEYCAPS_DESTBLT set doesn't look
  71. * correct. The best I've been able to do is run the tddraw DESTKEY case
  72. * and force ColorKeyBlt24 to go though each path and verify that they
  73. * each work correctly. This leads me to expect that foxbear using
  74. * DstColorKeying wasn't debugged very thoroughly (now that's probably a big
  75. * surprise to everyone). We need more dest color key blt tests.
  76. * For Win95, this was basically a wasted effort since 256 byte fetch appears
  77. * to break 24bpp colorkey blts in some other way, which would require yet
  78. * another workaround.
  79. *
  80. * Rev 1.33 18 Aug 1997 15:00:42 bennyn
  81. * For NT, if DDBLTFX dwSize not equal to sizeof(DDBLTFX), set dwColor to 0.
  82. *
  83. * Rev 1.32 13 Aug 1997 12:20:48 bennyn
  84. * For NT, punt if no scratch buffer and DDBLTFX dwSize is not sizeof(DDBLTFX)
  85. *
  86. * Rev 1.31 29 Jul 1997 17:18:18 bennyn
  87. * Fixed the Foxbear F8 bug
  88. *
  89. * Rev 1.30 29 Jul 1997 10:51:40 bennyn
  90. * NT only, punt if it is a host to screen BLT
  91. *
  92. * Rev 1.29 24 Jul 1997 12:30:36 RUSSL
  93. * Added check for NULL src surface ptr in Blt65 before nonlocal vidmem test
  94. *
  95. * Rev 1.28 24 Jul 1997 11:17:14 RUSSL
  96. * cover up various wickle crimes against humanity
  97. * which means disabling interpolated stretch blts among other things
  98. *
  99. * Rev 1.27 18 Jul 1997 10:21:50 RUSSL
  100. * Added check for zero extent blts in TransparentStretch65
  101. *
  102. * Rev 1.26 14 Jul 1997 13:15:14 RUSSL
  103. * Fix for PDR 9947 - include support for all surface formats for blts
  104. * between overlay surfaces
  105. *
  106. * Rev 1.25 08 Jul 1997 11:50:48 RUSSL
  107. * Rewrite of TransparentStretch65, similar to TransparentStretch in ddblt.c
  108. * but can blt each scanline's full x extent without striping.
  109. * Modified calls to do stretch blt with source colorkeying in Blt65.
  110. *
  111. * Rev 1.24 07 Jul 1997 13:43:52 dzenz
  112. * Added check of DRVSEM_DISPLAY_LIST semaphore to ascertain if
  113. * qmRequestDirectAccess needs to be called.
  114. *
  115. * Rev 1.23 20 Jun 1997 09:45:32 RUSSL
  116. * Added FBToFBCopy to handle blts to/from a linear surface
  117. * (currently these can be overlay or videoport surfaces only)
  118. * Fixed one of our seemingly inevitable NT/Win95 collisions
  119. *
  120. * Rev 1.22 12 Jun 1997 17:30:46 bennyn
  121. * For 24 & 32 BPP use StretchColor() instead of TransparentStretch()
  122. *
  123. * Rev 1.21 23 May 1997 15:41:28 noelv
  124. * Added nt method for chip revision test.
  125. *
  126. * Rev 1.20 22 May 1997 16:46:38 RUSSL
  127. * Fix for PDRs 9710 & 9706, remove xext <= 8 check on striping of src
  128. * colorkey blts on 65AC (this is a workaround for a hw bug)
  129. * Add check for 65AC or earlier and do striping of src colorkey blts
  130. * on 65AD striping isn't needed so just do single blt
  131. *
  132. * Rev 1.19 19 May 1997 13:08:10 noelv
  133. * Put NT4.0 wrapper around DrvSrcMBlt call.
  134. *
  135. * Rev 1.18 16 May 1997 15:32:02 RUSSL
  136. * Added blt case to handle blts from a UYVY surface to another UYVY surface
  137. * This fixes the VFW bugs, WinBench 97 video bugs and Encarta 97 video bugs
  138. * PDRs 9557, 9604, 9692, 9268 & 9270
  139. * Thanks to Peter Hou
  140. *
  141. * Rev 1.17 16 Apr 1997 18:40:48 RUSSL
  142. * Fix for PDR #9340, for color conversion and resize blts calculate surface
  143. * offset based on frame buffer pixel format then calculate offset into surface
  144. * based on surface pixel format. Pass DrvStretch65 byte based coordinates
  145. * rather than pixel based coordinates.
  146. *
  147. * Rev 1.16 16 Apr 1997 10:50:54 bennyn
  148. * Eliminated the warning due to Win95 DBG_MESSAGE call.
  149. *
  150. * Rev 1.15 08 Apr 1997 11:50:46 einkauf
  151. * WINNT_VER40 affected only:add SYNC_W_3D to coordinate MCD and 2D hw access
  152. *
  153. * Rev 1.14 03 Apr 1997 15:25:34 RUSSL
  154. * Modified DDBLT_DEPTHFILL case in Blt65 to blt based on surface colordepth
  155. * it was clearing 16bit zbuffers in 32bit modes with pixel blts so would
  156. * wipe out everything to the right of the actual zbuffer
  157. * Fixes at least PDRs #9152, 9150 & 8789 (maybe others as well)
  158. *
  159. * Rev 1.13 02 Apr 1997 15:44:54 RUSSL
  160. * Stripe src color key blts at 24bpp, fixes PDR #9113
  161. * Added TransparentStretch65 but hw doesn't work so it's #if'd out
  162. *
  163. * Rev 1.12 27 Mar 1997 16:12:36 RUSSL
  164. * Tossed the whole bloody mess in the bit bucket. Reverted to rev 1.1
  165. * Changed name of DrvStretch to DrvStretch65
  166. * Modified DrvStretch65 to do 65-style resize blts using stretch_cntl
  167. * rather than lncntl
  168. * Added use of original src & dst rectangle (if available) to compute
  169. * error terms. Walk DDA's in DrvStretch65 for clipped rect's.
  170. * Changed Blt65 locals dwDstCoord, dwDstWidth, dwDstHeight and dwSrcCoord,
  171. * dwSrcWidth, dwSrcHeight to DstDDRect and SrcDDRect DDRECTL structures
  172. * Moved sync with queue manager in front of call to updateFlipStatus since
  173. * updateFlipStatus might access the hardware
  174. * Added workaround for hw bug for src colorkey blts less than one qword
  175. * wide that require fetching from two src qwords but writing to only
  176. * one dst qword. Fixes white lines on foxbear that used to appear in
  177. * some modes
  178. *
  179. * Rev 1.11 21 Mar 1997 18:08:38 RUSSL
  180. * Fixups in StretchRect so Foxbear now runs correctly in a window at
  181. * all 4 colordepths
  182. *
  183. * Rev 1.10 18 Mar 1997 07:51:44 bennyn
  184. * Resolved NT comiling error by #ifdef queue manager sync call
  185. *
  186. * Rev 1.9 12 Mar 1997 14:59:50 RUSSL
  187. * replaced a block of includes with include of precomp.h for
  188. * precompiled headers
  189. *
  190. * Rev 1.8 07 Mar 1997 12:47:10 RUSSL
  191. * Modified DDRAW_COMPAT usage
  192. *
  193. * Rev 1.7 03 Mar 1997 10:31:40 eleland
  194. * inserted queue manager sync call to blt65(), removed #ifdef
  195. * USE_QUEUE_MANAGER
  196. *
  197. * Rev 1.6 21 Feb 1997 15:40:38 RUSSL
  198. * Anybody know why we were doing every 1:1 blt through the
  199. * resize engine rather than just a normal blt ???????
  200. *
  201. * Rev 1.5 06 Feb 1997 13:09:36 BENNYN
  202. * Fixed DWORD alignment for DD resizing code
  203. *
  204. * Rev 1.4 31 Jan 1997 13:44:06 BENNYN
  205. * Added clipping support and no interpolation set for 24BPP & YUV src shrink
  206. *
  207. * Rev 1.3 27 Jan 1997 17:29:14 BENNYN
  208. * Added Win95 support
  209. *
  210. * Rev 1.2 23 Jan 1997 17:10:10 bennyn
  211. * Modified to support 5465 DD
  212. *
  213. * Rev 1.1 21 Jan 1997 15:09:28 RUSSL
  214. * Added include of ddinline.h
  215. *
  216. * Rev 1.0 15 Jan 1997 10:35:20 RUSSL
  217. * Initial revision.
  218. *
  219. ***************************************************************************
  220. ***************************************************************************/
  221. /*----------------------------- INCLUDES ----------------------------------*/
  222. #include "precomp.h"
  223. // If WinNT 3.5 skip all the source code
  224. #if defined WINNT_VER35 // WINNT_VER35
  225. #else // !WinNT 3.51
  226. #ifdef WINNT_VER40 // WINNT_VER40
  227. #define DBGLVL 1
  228. #else // Win95
  229. #include "flip.h"
  230. #include "surface.h"
  231. #include "blt.h"
  232. #include "palette.h"
  233. #include "bltP.h"
  234. #include "ddinline.h"
  235. #include "qmgr.h"
  236. #include "ddshared.h"
  237. #include "overlay.h"
  238. #endif // WINNT_VER40
  239. /*----------------------------- DEFINES -----------------------------------*/
  240. #define OP2_ONLY_SRC_COLORKEY 1
  241. #ifdef WINNT_VER40
  242. #define UPDATE_FLIP_STATUS(arg) vUpdateFlipStatus(&ppdev->flipRecord,(arg))
  243. #else // Win95
  244. #define UPDATE_FLIP_STATUS(arg) updateFlipStatus((arg),lpDDHALData)
  245. #endif // WINNT_VER40
  246. #define LOCK_HW_SEMAPHORE() (lpDDHALData->DrvSemaphore |= DRVSEM_IN_USE)
  247. #define UNLOCK_HW_SEMAPHORE() (lpDDHALData->DrvSemaphore &= ~ DRVSEM_IN_USE)
  248. // defines for STRETCH_CNTL register
  249. #define RGB_8_FMT 0
  250. #define RGB_555_FMT 1
  251. #define RGB_565_FMT 2
  252. #define RGB_24_FMT 3
  253. #define RGB_32_FMT 4
  254. #define YUV_422_FMT 9
  255. #define SRC_FMT_SHIFT 12
  256. #define DST_FMT_SHIFT 8
  257. #define SRC_FMT_MASK 0xF000
  258. #define DST_FMT_MASK 0x0F00
  259. #define YSHRINK_ENABLE 0x8
  260. #define XSHRINK_ENABLE 0x4
  261. #define YINTERP_ENABLE 0x2
  262. #define XINTERP_ENABLE 0x1
  263. // bltdef defines
  264. #define BD_TYPE_RESIZE (1 << 9)
  265. #define BD_TYPE_NORMAL 0
  266. /*----------------------------- TYPEDEFS ----------------------------------*/
  267. typedef short DDAX;
  268. typedef struct tagAxis
  269. {
  270. DDAX accum;
  271. DDAX maj;
  272. DDAX min;
  273. } AXIS;
  274. #if !ENABLE_CLIPPEDBLTS
  275. typedef struct _DDRECTL
  276. {
  277. REG32 loc;
  278. REG32 ext;
  279. } DDRECTL;
  280. #endif
  281. /*------------------------- FUNCTION PROTOTYPES ---------------------------*/
  282. #ifdef DEBUG
  283. extern VOID SaveSurfaceToBmp ( DDRAWI_DDRAWSURFACE_LCL *pSurface );
  284. #endif
  285. /*-------------------------- STATIC VARIABLES -----------------------------*/
  286. #ifndef WINNT_VER40
  287. ASSERTFILE("blt65.c");
  288. extern PFN_UPDATEFLIPSTATUS pfnUpdateFlipStatus;
  289. #endif
  290. /*-------------------------- GLOBAL FUNCTIONS -----------------------------*/
  291. /***************************************************************************
  292. *
  293. * FUNCTION: DrvStretch65()
  294. *
  295. * DESCRIPTION:
  296. *
  297. ****************************************************************************/
  298. void DrvStretch65
  299. (
  300. #ifdef WINNT_VER40
  301. PDEV *ppdev,
  302. DRIVERDATA *lpDDHALData,
  303. #else
  304. LPGLOBALDATA lpDDHALData,
  305. #endif
  306. DDRECTL SrcDDRect,
  307. DDRECTL DstDDRect,
  308. DWORD Stretch_Cntl,
  309. DDRECTL OrigSrcDDRect,
  310. DDRECTL OrigDstDDRect
  311. )
  312. {
  313. const int nBytesPixel = BYTESPERPIXEL;
  314. autoblt_regs bltr;
  315. AXIS axis[2];
  316. int nDst[2];
  317. int nSrc[2];
  318. int i;
  319. int ext;
  320. #ifndef WINNT_VER40
  321. DBG_MESSAGE(("DrvStretch65: %4d,%4d %4dx%4d -> %4d,%4d %4dx%4d",
  322. SrcDDRect.loc.pt.X, SrcDDRect.loc.pt.Y,
  323. SrcDDRect.ext.pt.X, SrcDDRect.ext.pt.Y,
  324. DstDDRect.loc.pt.X, DstDDRect.loc.pt.Y,
  325. DstDDRect.ext.pt.X, DstDDRect.ext.pt.Y));
  326. #endif // WINNT_VER40
  327. if ((0 == DstDDRect.ext.pt.X) || (0 == DstDDRect.ext.pt.Y) ||
  328. (0 == SrcDDRect.ext.pt.X) || (0 == SrcDDRect.ext.pt.Y))
  329. {
  330. // nothing to do, so get outta here!
  331. return;
  332. }
  333. #ifdef WINNT_VER40
  334. SYNC_W_3D(ppdev);
  335. #endif
  336. bltr.DRAWBLTDEF.DW = MAKELONG(ROP_OP1_copy, BD_RES * IS_VRAM |
  337. BD_OP1 * IS_VRAM |
  338. BD_TYPE_RESIZE);
  339. // dst coords
  340. bltr.OP0_opMRDRAM.DW = DstDDRect.loc.DW;
  341. // src coords
  342. bltr.OP1_opMRDRAM.DW = SrcDDRect.loc.DW;
  343. // blt extent
  344. bltr.MBLTEXTR_EX.DW = DstDDRect.ext.DW;
  345. #if 1
  346. // tddraw agp Case 47 puts the goofy happy face with arms image in the middle
  347. // of the screen and then expects us to stretch it over the top of itself
  348. // if we don't handle the overlap somehow, the result is trash at the bottom
  349. // we blt the original src to the lower right of the dest and then stretch
  350. // that copy of the src to the dest
  351. // hack, hack, cough, cough
  352. bltr.BLTEXT.DW = SrcDDRect.ext.DW; // stuff this here for overlap check
  353. #endif
  354. bltr.STRETCH_CNTL.W = (WORD)Stretch_Cntl;
  355. bltr.SHRINKINC.W = 0x0000;
  356. bltr.SRCX = SrcDDRect.ext.pt.X;
  357. // convert back to pixels for error term computations
  358. DstDDRect.ext.pt.X /= (USHORT)nBytesPixel;
  359. OrigDstDDRect.ext.pt.X /= (USHORT)nBytesPixel;
  360. if ((YUV_422_FMT << SRC_FMT_SHIFT) == (SRC_FMT_MASK & Stretch_Cntl))
  361. {
  362. bltr.OP1_opMRDRAM.pt.X &= 0xFFFC;
  363. SrcDDRect.ext.pt.X /= 2;
  364. OrigSrcDDRect.ext.pt.X /= 2;
  365. }
  366. else
  367. {
  368. SrcDDRect.ext.pt.X /= (USHORT)nBytesPixel;
  369. OrigSrcDDRect.ext.pt.X /= (USHORT)nBytesPixel;
  370. }
  371. if (DstDDRect.ext.pt.X < SrcDDRect.ext.pt.X)
  372. {
  373. bltr.STRETCH_CNTL.W |= XSHRINK_ENABLE;
  374. bltr.STRETCH_CNTL.W &= ~XINTERP_ENABLE;
  375. bltr.SHRINKINC.pt.X = SrcDDRect.ext.pt.X / DstDDRect.ext.pt.X;
  376. }
  377. if (DstDDRect.ext.pt.Y < SrcDDRect.ext.pt.Y)
  378. {
  379. bltr.STRETCH_CNTL.W |= YSHRINK_ENABLE;
  380. bltr.STRETCH_CNTL.W &= ~YINTERP_ENABLE;
  381. bltr.SHRINKINC.pt.Y = SrcDDRect.ext.pt.Y / DstDDRect.ext.pt.Y;
  382. }
  383. // Compute DDA terms.
  384. nDst[0] = OrigDstDDRect.ext.pt.X;
  385. nDst[1] = OrigDstDDRect.ext.pt.Y;
  386. nSrc[0] = OrigSrcDDRect.ext.pt.X;
  387. nSrc[1] = OrigSrcDDRect.ext.pt.Y;
  388. for (i = 0; i < 2; i++)
  389. {
  390. int kDst = 1;
  391. if (bltr.STRETCH_CNTL.W & ((i==0) ? XINTERP_ENABLE : YINTERP_ENABLE))
  392. {
  393. nDst[i] *= 4;
  394. nSrc[i] *= 4;
  395. nSrc[i] -= 3;
  396. kDst = 0x8000 / nDst[i];
  397. }
  398. if (bltr.STRETCH_CNTL.W & ((i==0) ? XSHRINK_ENABLE : YSHRINK_ENABLE))
  399. { /* Shrink Terms */
  400. axis[i].maj = (short)nDst[i];
  401. axis[i].min = - (nSrc[i] % nDst[i]);
  402. axis[i].accum = axis[i].maj - 1
  403. - ((nSrc[i] % nDst[i]) / (nSrc[i]/nDst[i] + 1));
  404. }
  405. else
  406. { /* Stretch Terms */
  407. axis[i].maj = kDst * nDst[i];
  408. axis[i].min = -kDst * nSrc[i];
  409. axis[i].accum = axis[i].maj - 1
  410. - ((axis[i].maj % -axis[i].min) / (nDst[i]/nSrc[i] + 1));
  411. }
  412. }
  413. bltr.MAJ_X = axis[0].maj;
  414. bltr.MIN_X = axis[0].min;
  415. bltr.ACCUM_X = axis[0].accum;
  416. bltr.MAJ_Y = axis[1].maj;
  417. bltr.MIN_Y = axis[1].min;
  418. bltr.ACCUM_Y = axis[1].accum;
  419. #define DO_SW_CLIPPING
  420. #ifdef DO_SW_CLIPPING
  421. // walk DDA's to get correct initial ACCUM terms
  422. ext = DstDDRect.loc.pt.X - OrigDstDDRect.loc.pt.X;
  423. while (0 < ext--)
  424. {
  425. bltr.ACCUM_X += bltr.MIN_X;
  426. if (0 > (short)bltr.ACCUM_X)
  427. {
  428. bltr.ACCUM_X += bltr.MAJ_X;
  429. }
  430. }
  431. ext = DstDDRect.loc.pt.Y - OrigDstDDRect.loc.pt.Y;
  432. while (0 < ext--)
  433. {
  434. bltr.ACCUM_Y += bltr.MIN_Y;
  435. if (0 > (short)bltr.ACCUM_Y)
  436. {
  437. bltr.ACCUM_Y += bltr.MAJ_Y;
  438. }
  439. }
  440. #else
  441. #pragma message("Add hw clipping")
  442. #endif
  443. #ifdef WINNT_VER40
  444. ppdev->pfnDrvStrBlt(ppdev, lpDDHALData,
  445. #else
  446. pfnDrvStrBlt(
  447. lpDDHALData,
  448. #endif
  449. &bltr);
  450. }
  451. /***************************************************************************
  452. *
  453. * FUNCTION: TransparentStretch65()
  454. *
  455. * DESCRIPTION:
  456. *
  457. ****************************************************************************/
  458. void TransparentStretch65
  459. (
  460. #ifdef WINNT_VER40
  461. PDEV *ppdev,
  462. DRIVERDATA *lpDDHALData,
  463. #else
  464. LPGLOBALDATA lpDDHALData,
  465. #endif
  466. DDRECTL SrcDDRect,
  467. DDRECTL DstDDRect,
  468. DWORD Stretch_Cntl,
  469. DWORD ColorKey
  470. )
  471. {
  472. const int nBytesPixel = BYTESPERPIXEL;
  473. autoblt_regs SrcToScratch;
  474. AXIS axis[2];
  475. int nDst[2];
  476. int nSrc[2];
  477. int i;
  478. // currently this only supports same src & dst formats
  479. #ifndef WINNT_VER40
  480. ASSERT(((SRC_FMT_MASK & Stretch_Cntl) >> SRC_FMT_SHIFT) ==
  481. ((DST_FMT_MASK & Stretch_Cntl) >> DST_FMT_SHIFT));
  482. DBG_MESSAGE(("TransparentStretch65: %4X,%4X %4Xx%4X -> %4X,%4X %4Xx%4X",
  483. SrcDDRect.loc.pt.X, SrcDDRect.loc.pt.Y,
  484. SrcDDRect.ext.pt.X, SrcDDRect.ext.pt.Y,
  485. DstDDRect.loc.pt.X, DstDDRect.loc.pt.Y,
  486. DstDDRect.ext.pt.X, DstDDRect.ext.pt.Y));
  487. #endif
  488. if ((0 == DstDDRect.ext.pt.X) || (0 == DstDDRect.ext.pt.Y) ||
  489. (0 == SrcDDRect.ext.pt.X) || (0 == SrcDDRect.ext.pt.Y))
  490. {
  491. // nothing to do, so get outta here!
  492. return;
  493. }
  494. // initialize auto blt struct for src to scratch buffer
  495. SrcToScratch.DRAWBLTDEF.DW = MAKELONG(ROP_OP1_copy, BD_RES * IS_VRAM |
  496. BD_OP1 * IS_VRAM |
  497. BD_TYPE_RESIZE);
  498. // dst coords in bytes (scratch buffer)
  499. SrcToScratch.OP0_opMRDRAM.DW = lpDDHALData->ScratchBufferOrg;
  500. SrcToScratch.OP0_opMRDRAM.pt.X *= (USHORT)nBytesPixel;
  501. // src coords in bytes
  502. SrcToScratch.OP1_opMRDRAM.DW = SrcDDRect.loc.DW;
  503. SrcToScratch.OP1_opMRDRAM.pt.X *= (USHORT)nBytesPixel;
  504. // blt extent in bytes (1 scanline at a time)
  505. SrcToScratch.MBLTEXTR_EX.DW = MAKELONG(DstDDRect.ext.pt.X * nBytesPixel,1);
  506. SrcToScratch.STRETCH_CNTL.W = (WORD)Stretch_Cntl;
  507. SrcToScratch.SHRINKINC.W = 0x0000;
  508. SrcToScratch.SRCX = SrcDDRect.ext.pt.X * nBytesPixel;
  509. if (DstDDRect.ext.pt.X < SrcDDRect.ext.pt.X)
  510. {
  511. SrcToScratch.STRETCH_CNTL.W |= XSHRINK_ENABLE;
  512. SrcToScratch.STRETCH_CNTL.W &= ~XINTERP_ENABLE;
  513. SrcToScratch.SHRINKINC.pt.X = SrcDDRect.ext.pt.X / DstDDRect.ext.pt.X;
  514. }
  515. if (DstDDRect.ext.pt.Y < SrcDDRect.ext.pt.Y)
  516. {
  517. SrcToScratch.STRETCH_CNTL.W |= YSHRINK_ENABLE;
  518. SrcToScratch.STRETCH_CNTL.W &= ~YINTERP_ENABLE;
  519. SrcToScratch.SHRINKINC.pt.Y = SrcDDRect.ext.pt.Y / DstDDRect.ext.pt.Y;
  520. }
  521. // Compute DDA terms
  522. nDst[0] = DstDDRect.ext.pt.X;
  523. nDst[1] = DstDDRect.ext.pt.Y;
  524. nSrc[0] = SrcDDRect.ext.pt.X;
  525. nSrc[1] = SrcDDRect.ext.pt.Y;
  526. for (i = 0; i < 2; i++)
  527. {
  528. int kDst = 1;
  529. if (SrcToScratch.STRETCH_CNTL.W & ((i==0) ? XINTERP_ENABLE : YINTERP_ENABLE))
  530. {
  531. nDst[i] *= 4;
  532. nSrc[i] *= 4;
  533. nSrc[i] -= 3;
  534. kDst = 0x8000 / nDst[i];
  535. }
  536. if (SrcToScratch.STRETCH_CNTL.W & ((i==0) ? XSHRINK_ENABLE : YSHRINK_ENABLE))
  537. { /* Shrink Terms */
  538. axis[i].maj = (short)nDst[i];
  539. axis[i].min = - (nSrc[i] % nDst[i]);
  540. axis[i].accum = axis[i].maj - 1
  541. - ((nSrc[i] % nDst[i]) / (nSrc[i]/nDst[i] + 1));
  542. }
  543. else
  544. { /* Stretch Terms */
  545. axis[i].maj = kDst * nDst[i];
  546. axis[i].min = -kDst * nSrc[i];
  547. axis[i].accum = axis[i].maj - 1
  548. - ((axis[i].maj % -axis[i].min) / (nDst[i]/nSrc[i] + 1));
  549. }
  550. }
  551. SrcToScratch.MAJ_X = axis[0].maj;
  552. SrcToScratch.MIN_X = axis[0].min;
  553. SrcToScratch.ACCUM_X = axis[0].accum;
  554. SrcToScratch.MAJ_Y = axis[1].maj;
  555. SrcToScratch.MIN_Y = axis[1].min;
  556. SrcToScratch.ACCUM_Y = axis[1].accum;
  557. // loop over scanlines in dst
  558. // do two blts for each, one from src to scratch buffer
  559. // then one from scratch buffer to dst
  560. while (0 < DstDDRect.ext.pt.Y)
  561. {
  562. // blt one scanline high from src to scratch buffer
  563. #ifdef WINNT_VER40
  564. ppdev->pfnDrvStrBlt(ppdev, lpDDHALData,
  565. #else
  566. pfnDrvStrBlt(
  567. lpDDHALData,
  568. #endif
  569. &SrcToScratch);
  570. // walk Y DDA for src to scratch buffer blt
  571. SrcToScratch.ACCUM_Y += SrcToScratch.MIN_Y;
  572. SrcToScratch.OP1_opMRDRAM.pt.Y += SrcToScratch.SHRINKINC.pt.Y;
  573. if (0 > (short)SrcToScratch.ACCUM_Y)
  574. {
  575. SrcToScratch.ACCUM_Y += SrcToScratch.MAJ_Y;
  576. SrcToScratch.OP1_opMRDRAM.pt.Y++;
  577. }
  578. // blt from scratch buffer to dst
  579. // 1:1 in X, 1:1 in Y, uses colorkey
  580. #ifdef WINNT_VER40
  581. ppdev->pfnDrvSrcBlt(ppdev, lpDDHALData,
  582. #else
  583. pfnDrvSrcBlt(
  584. lpDDHALData,
  585. #endif
  586. #if OP2_ONLY_SRC_COLORKEY
  587. MAKELONG((DD_TRANS | ROP_OP2_copy),
  588. ((BD_RES+BD_OP2)*IS_VRAM)),
  589. #else
  590. MAKELONG((DD_TRANS | ROP_OP1_copy),
  591. ((BD_RES+BD_OP1+BD_OP2)*IS_VRAM)),
  592. #endif
  593. DstDDRect.loc.DW,
  594. lpDDHALData->ScratchBufferOrg,
  595. lpDDHALData->ScratchBufferOrg,
  596. ColorKey,
  597. MAKELONG(DstDDRect.ext.pt.X,1));
  598. DstDDRect.loc.pt.Y++;
  599. DstDDRect.ext.pt.Y--;
  600. }
  601. }
  602. #ifndef WINNT_VER40
  603. /***************************************************************************
  604. *
  605. * FUNCTION: FBToFBCopy()
  606. *
  607. * DESCRIPTION:
  608. *
  609. ****************************************************************************/
  610. VOID
  611. FBToFBCopy ( BYTE *dst, LONG dstPitch, BYTE *src, LONG srcPitch, REG32 ext, LONG bpp )
  612. {
  613. int yext = ext.pt.Y;
  614. int xext = ext.pt.X * bpp;
  615. while (0 < yext--)
  616. {
  617. memcpy(dst,src,xext);
  618. dst += dstPitch;
  619. src += srcPitch;
  620. }
  621. }
  622. #endif
  623. /***************************************************************************
  624. *
  625. * FUNCTION: ColorKeyBlt24()
  626. *
  627. * DESCRIPTION:
  628. *
  629. ****************************************************************************/
  630. #define MIN_WIDTH 21 // empirically determined that most widths less than this don't work
  631. #define STRIPE_WIDTH 40 // max is 128 / 3 = 42 pixels, but use 40 to account for phase
  632. STATIC VOID ColorKeyBlt24
  633. (
  634. #ifdef WINNT_VER40
  635. PDEV *ppdev,
  636. DRIVERDATA *lpDDHALData,
  637. #else
  638. LPGLOBALDATA lpDDHALData,
  639. #endif
  640. DWORD drawbltdef,
  641. DDRECTL DstDDRect,
  642. DDRECTL SrcDDRect,
  643. DDRECTL KeyDDRect,
  644. DWORD dwColorKey
  645. )
  646. {
  647. short xStep = 1;
  648. short yStep = 1;
  649. WORD xExt;
  650. // check for overlap
  651. if ((abs(DstDDRect.loc.pt.X - SrcDDRect.loc.pt.X) < DstDDRect.ext.pt.X) &&
  652. (abs(DstDDRect.loc.pt.Y - SrcDDRect.loc.pt.Y) < DstDDRect.ext.pt.Y))
  653. {
  654. // see if we need to blt from bottom to top
  655. if (DstDDRect.loc.pt.Y > SrcDDRect.loc.pt.Y)
  656. {
  657. // point to bottom scanline and update bltdef
  658. drawbltdef |= MAKELONG(0, BD_YDIR);
  659. DstDDRect.loc.pt.Y += (DstDDRect.ext.pt.Y - 1);
  660. SrcDDRect.loc.pt.Y += (DstDDRect.ext.pt.Y - 1);
  661. KeyDDRect.loc.pt.Y += (DstDDRect.ext.pt.Y - 1);
  662. yStep = -1;
  663. }
  664. // see if we need to blt from right to left
  665. if (DstDDRect.loc.pt.X > SrcDDRect.loc.pt.X)
  666. {
  667. // point to right edge pixel
  668. DstDDRect.loc.pt.X += (DstDDRect.ext.pt.X - 1);
  669. SrcDDRect.loc.pt.X += (DstDDRect.ext.pt.X - 1);
  670. KeyDDRect.loc.pt.X += (DstDDRect.ext.pt.X - 1);
  671. xStep = -1;
  672. }
  673. }
  674. // if width is too narrow, do blt a pixel at a time
  675. // Also blt a pixel at a time for certain overlapping src/dst combinations
  676. // that won't work correctly otherwise. While setting BD_YDIR to blt from
  677. // bottom to top and also bltting in SRAM width stripes from right to left
  678. // do work at 24bpp, they unfortunately don't work for certain overlap cases.
  679. // In particular BD_YDIR doesn't work when you need it (period!) and bltting
  680. // in SRAM width stripes from right to left doesn't work if the src and dst
  681. // have the same y. Take out the two || cases and try the tddraw
  682. // BLT_BltFast, SRCKEY, From/To same surface test and see for yourself.
  683. if ( (MIN_WIDTH >= DstDDRect.ext.pt.X)
  684. || (0 > yStep)
  685. || ((0 > xStep) && (DstDDRect.loc.pt.Y == SrcDDRect.loc.pt.Y))
  686. )
  687. {
  688. BltOnePixelAtATime:
  689. // loop over scanlines
  690. while (0 < DstDDRect.ext.pt.Y)
  691. {
  692. DWORD dst = DstDDRect.loc.DW;
  693. DWORD src = SrcDDRect.loc.DW;
  694. DWORD key = KeyDDRect.loc.DW;
  695. xExt = DstDDRect.ext.pt.X;
  696. // loop over pixels in scanline
  697. while (0 < xExt)
  698. {
  699. #ifdef WINNT_VER40
  700. ppdev->pfnDrvSrcBlt(ppdev, lpDDHALData,
  701. #else
  702. pfnDrvSrcBlt(
  703. lpDDHALData,
  704. #endif
  705. drawbltdef, dst, src, key, dwColorKey, MAKELONG(1,1));
  706. // adjust extent and ptrs (x is in low word)
  707. xExt--;
  708. dst += xStep;
  709. src += xStep;
  710. key += xStep;
  711. }
  712. // adjust extent and ptrs (y is in high word)
  713. DstDDRect.ext.pt.Y--;
  714. SrcDDRect.loc.pt.Y += yStep;
  715. DstDDRect.loc.pt.Y += yStep;
  716. KeyDDRect.loc.pt.Y += yStep;
  717. }
  718. }
  719. // if width is less than SRAM width, just do a single blt
  720. else if (STRIPE_WIDTH >= DstDDRect.ext.pt.X)
  721. {
  722. // except if there's overlap, do it the slow way
  723. //if ((0 > xStep) || (0 > yStep))
  724. if (0 > xStep) // check for (0 > yStep) already handled above
  725. goto BltOnePixelAtATime;
  726. // just blt it
  727. #ifdef WINNT_VER40
  728. ppdev->pfnDrvSrcBlt(ppdev, lpDDHALData,
  729. #else
  730. pfnDrvSrcBlt(
  731. lpDDHALData,
  732. #endif
  733. drawbltdef,
  734. DstDDRect.loc.DW,
  735. SrcDDRect.loc.DW,
  736. KeyDDRect.loc.DW,
  737. dwColorKey,
  738. DstDDRect.ext.DW);
  739. }
  740. // stripe the blt into SRAM width blts
  741. else
  742. {
  743. xExt = STRIPE_WIDTH;
  744. // blt from right to left
  745. if (0 > xStep)
  746. {
  747. DstDDRect.loc.pt.X++;
  748. SrcDDRect.loc.pt.X++;
  749. KeyDDRect.loc.pt.X++;
  750. while (1)
  751. {
  752. // adjust ptrs to start of stripe
  753. DstDDRect.loc.pt.X -= xExt;
  754. SrcDDRect.loc.pt.X -= xExt;
  755. KeyDDRect.loc.pt.X -= xExt;
  756. // blt the stripe
  757. #ifdef WINNT_VER40
  758. ppdev->pfnDrvSrcBlt(ppdev, lpDDHALData,
  759. #else
  760. pfnDrvSrcBlt(
  761. lpDDHALData,
  762. #endif
  763. drawbltdef,
  764. DstDDRect.loc.DW,
  765. SrcDDRect.loc.DW,
  766. KeyDDRect.loc.DW,
  767. dwColorKey,
  768. MAKELONG(xExt,DstDDRect.ext.pt.Y));
  769. // adjust remaining extent
  770. DstDDRect.ext.pt.X -= xExt;
  771. // are we done?
  772. if (0 == DstDDRect.ext.pt.X)
  773. break;
  774. // last stripe might not be STRIPE_WIDTH wide
  775. if (xExt > DstDDRect.ext.pt.X)
  776. {
  777. xExt = DstDDRect.ext.pt.X;
  778. // if the last stripe is too narrow,
  779. // finish the blt the even slower way
  780. if (MIN_WIDTH >= xExt)
  781. {
  782. // but first point to x pixel to start with
  783. SrcDDRect.loc.pt.X--;
  784. DstDDRect.loc.pt.X--;
  785. KeyDDRect.loc.pt.X--;
  786. goto BltOnePixelAtATime;
  787. }
  788. }
  789. }
  790. }
  791. // blt from left to right
  792. else
  793. {
  794. while (1)
  795. {
  796. // blt the stripe
  797. #ifdef WINNT_VER40
  798. ppdev->pfnDrvSrcBlt(ppdev, lpDDHALData,
  799. #else
  800. pfnDrvSrcBlt(
  801. lpDDHALData,
  802. #endif
  803. drawbltdef,
  804. DstDDRect.loc.DW,
  805. SrcDDRect.loc.DW,
  806. KeyDDRect.loc.DW,
  807. dwColorKey,
  808. MAKELONG(xExt,DstDDRect.ext.pt.Y));
  809. // adjust remaining extent
  810. DstDDRect.ext.pt.X -= xExt;
  811. // are we done?
  812. if (0 >= DstDDRect.ext.pt.X)
  813. break;
  814. // adjust ptrs to start of next stripe
  815. SrcDDRect.loc.pt.X += xExt;
  816. DstDDRect.loc.pt.X += xExt;
  817. KeyDDRect.loc.pt.X += xExt;
  818. // last stripe might not be STRIPE_WIDTH wide
  819. if (xExt > DstDDRect.ext.pt.X)
  820. {
  821. xExt = DstDDRect.ext.pt.X;
  822. // if the last stripe is too narrow,
  823. // finish the blt the even slower way
  824. if (MIN_WIDTH >= xExt)
  825. {
  826. // ptrs already set
  827. goto BltOnePixelAtATime;
  828. }
  829. }
  830. }
  831. }
  832. }
  833. }
  834. /***************************************************************************
  835. *
  836. * FUNCTION: Blt65()
  837. *
  838. * DESCRIPTION:
  839. *
  840. ****************************************************************************/
  841. #ifdef WINNT_VER40
  842. DWORD Blt65(PDD_BLTDATA pbd)
  843. {
  844. DRIVERDATA* lpDDHALData;
  845. PDEV* ppdev;
  846. PVGAR pREG;
  847. #else // Win95
  848. DWORD __stdcall
  849. Blt65 ( LPDDHAL_BLTDATA pbd)
  850. {
  851. LPGLOBALDATA lpDDHALData = GetDDHALContext( pbd->lpDD);
  852. #endif
  853. HRESULT ddrval;
  854. DWORD dwFlags;
  855. DDRECTL DstDDRect;
  856. DDRECTL SrcDDRect;
  857. #ifdef WINNT_VER40
  858. PDD_SURFACE_GLOBAL dst;
  859. PDD_SURFACE_GLOBAL src;
  860. DISPDBG((DBGLVL, "DDraw - Blt65\n"));
  861. ppdev = (PDEV*) pbd->lpDD->dhpdev;
  862. lpDDHALData = (DRIVERDATA*) &ppdev->DriverData; //why ?
  863. pREG = (PVGAR) lpDDHALData->RegsAddress;
  864. #else // Win95
  865. LPDDRAWI_DDRAWSURFACE_GBL dst;
  866. LPDDRAWI_DDRAWSURFACE_GBL src;
  867. #if defined(REMOVE_GLOBAL_VARS) && (REMOVE_GLOBAL_VARS != 0)
  868. PDEV *ppdev;
  869. ppdev = GetPDevice(pbd->lpDD);
  870. #endif
  871. #endif // WINNT_VER40
  872. DD_LOG(("Blt65 Entry\r\n"));
  873. #ifdef WINNT_VER40
  874. SYNC_W_3D(ppdev);
  875. // Punt, we don't support Host memory to Screen BLT
  876. if ((NULL != pbd->lpDDSrcSurface) &&
  877. (pbd->lpDDSrcSurface->lpGbl->xHint != 0) &&
  878. (pbd->lpDDSrcSurface->lpGbl->yHint != 0) &&
  879. (pbd->lpDDSrcSurface->dwReserved1 == 0))
  880. {
  881. pbd->ddRVal = DDERR_UNSUPPORTED;
  882. return DDHAL_DRIVER_NOTHANDLED;
  883. }
  884. #endif
  885. #if 1 // PC98
  886. #ifdef WINNT_VER40
  887. if ( (pbd->lpDDSrcSurface != NULL)
  888. && (pbd->lpDDSrcSurface->lpGbl->lPitch < ppdev->lDeltaScreen)
  889. )
  890. {
  891. pbd->ddRVal = DDERR_UNSUPPORTED;
  892. return DDHAL_DRIVER_NOTHANDLED;
  893. }
  894. #else
  895. if ( (pbd->lpDDSrcSurface != NULL)
  896. && (pbd->lpDDSrcSurface->lpGbl->lPitch < pDriverData->HALInfo.vmiData.lDisplayPitch)
  897. )
  898. {
  899. pbd->ddRVal = DDERR_UNSUPPORTED;
  900. return DDHAL_DRIVER_NOTHANDLED;
  901. }
  902. #endif
  903. #endif
  904. // NOTES:
  905. // Everything you need is in lpBlt->bltFX .
  906. // Look at lpBlt->dwFlags to determine what kind of blt you are doing,
  907. // DDBLT_xxxx are the flags.
  908. //
  909. // COLORKEY NOTES:
  910. // ColorKey ALWAYS comes in BLTFX. You don't have to look it up in
  911. // the surface.
  912. #ifdef WINNT_VER40 // WINNT_VER40
  913. #else // ----- #elseif WINNT_VER40 -----
  914. // if direct draw is NOT using display list, it must sync here
  915. // updateFlipStatus may access the hardware!
  916. if (!lpDDHALData->DisplayListDDraw && ((lpDDHALData->DrvSemaphore & DRVSEM_3D_BUSY) || (lpDDHALData->DrvSemaphore & DRVSEM_DISPLAY_LIST)))
  917. {
  918. qmRequestDirectAccess();
  919. }
  920. #endif // WINNT_VER40
  921. // is a flip in progress?
  922. #ifdef WINNT_VER40
  923. ddrval = vUpdateFlipStatus(&ppdev->flipRecord,pbd->lpDDDestSurface->lpGbl->fpVidMem);
  924. #else
  925. #if defined(DDRAW_COMPAT_10)
  926. ddrval = pfnUpdateFlipStatus(pbd->lpDDDestSurface->lpData->fpVidMem,lpDDHALData);
  927. #else
  928. ddrval = pfnUpdateFlipStatus(pbd->lpDDDestSurface->lpGbl->fpVidMem,lpDDHALData);
  929. #endif
  930. #endif
  931. if (ddrval != DD_OK)
  932. {
  933. pbd->ddRVal = ddrval;
  934. DD_LOG(("Blt65 Exit - flip in progress, returning %08lX\r\n", ddrval));
  935. return (DDHAL_DRIVER_HANDLED);
  936. }
  937. // If async, then only work if blter isn't busy.
  938. // This should probably be a little more specific to each call !!!
  939. dwFlags = pbd->dwFlags;
  940. #if 1
  941. // billy and dah boyz strike again
  942. // tddraw agp Case 59 asks us to blt between to nonlocal video memory
  943. // surfaces even though we report that we don't support offscreen
  944. // plain nonlocal video memory surfaces
  945. // why is ddraw allocating offscreen plain surfaces in agp memory?
  946. #if DDRAW_COMPAT >= 50
  947. // see if the dest is in nonlocal video memory
  948. if (DDSCAPS_NONLOCALVIDMEM & pbd->lpDDDestSurface->ddsCaps.dwCaps)
  949. {
  950. pbd->ddRVal = DDERR_UNSUPPORTED;
  951. return DDHAL_DRIVER_NOTHANDLED;
  952. }
  953. // if there is a src, see if it's in nonlocal video memory
  954. if ((NULL != pbd->lpDDSrcSurface) &&
  955. (DDSCAPS_NONLOCALVIDMEM & pbd->lpDDSrcSurface->ddsCaps.dwCaps))
  956. {
  957. pbd->ddRVal = DDERR_UNSUPPORTED;
  958. return DDHAL_DRIVER_NOTHANDLED;
  959. }
  960. #endif
  961. #endif
  962. #ifndef WINNT_VER40
  963. // if the destination surface of this blt is a texture
  964. if (DDSCAPS_TEXTURE & pbd->lpDDDestSurface->ddsCaps.dwCaps)
  965. {
  966. LP_SURFACE_DATA lpSurfaceData;
  967. lpSurfaceData = (LP_SURFACE_DATA)(pbd->lpDDDestSurface->dwReserved1);
  968. // if the texture is a non-agp host texture (i.e. pci memory)
  969. if (lpSurfaceData->dwFlags & SURF_HOST_BASED_TEXTURE)
  970. {
  971. // punt the blt to direct draw hel
  972. pbd->ddRVal = DDERR_UNSUPPORTED;
  973. return DDHAL_DRIVER_NOTHANDLED;
  974. }
  975. }
  976. // if the source surface of this blt is non-null and is a texture
  977. if ((NULL != pbd->lpDDSrcSurface) &&
  978. (DDSCAPS_TEXTURE & pbd->lpDDSrcSurface->ddsCaps.dwCaps))
  979. {
  980. LP_SURFACE_DATA lpSurfaceData;
  981. lpSurfaceData = (LP_SURFACE_DATA)(pbd->lpDDSrcSurface->dwReserved1);
  982. // if the texture is a non-agp host texture (i.e. pci memory)
  983. if (lpSurfaceData->dwFlags & SURF_HOST_BASED_TEXTURE)
  984. {
  985. // punt the blt to direct draw hel
  986. pbd->ddRVal = DDERR_UNSUPPORTED;
  987. return DDHAL_DRIVER_NOTHANDLED;
  988. }
  989. }
  990. #endif
  991. // get offset, width, and height for destination
  992. #if defined(DDRAW_COMPAT_10)
  993. dst = pbd->lpDDDestSurface->lpData;
  994. #else
  995. dst = pbd->lpDDDestSurface->lpGbl;
  996. #endif
  997. #ifdef WINNT_VER40
  998. DstDDRect.loc.DW = cvlxy(ppdev->lDeltaScreen,dst->fpVidMem,BYTESPERPIXEL);
  999. #else // Win95
  1000. DstDDRect.loc.DW = cvlxy(lpDDHALData,dst->fpVidMem-lpDDHALData->ScreenAddress,BYTESPERPIXEL);
  1001. #endif
  1002. DstDDRect.loc.DW += MAKELONG(pbd->rDest.left,pbd->rDest.top);
  1003. DstDDRect.ext.pt.X = (WORD)(pbd->rDest.right - pbd->rDest.left);
  1004. DstDDRect.ext.pt.Y = (WORD)(pbd->rDest.bottom - pbd->rDest.top);
  1005. // If someone is running a full-screen exclusive app it is the
  1006. // responsibility of the app to take care of the cursor. We don't
  1007. // call BeginAccess or EndAccess for them.
  1008. //
  1009. // However, if someone is running a windowed app and they have
  1010. // attached a clipper object to the destination surface then they
  1011. // are more like a normal windows app and we call BeginAccess and
  1012. // EndAccess for them around a blt. That is the only circumstance
  1013. // where we currently do cursor exclusion.
  1014. //
  1015. // We do intend to add calls to BeginAccess and EndAccess around
  1016. // a rectangle lock of the primary surface. In this case, we
  1017. // would only do cursor exclusion if a lock rect is specified.
  1018. // This will be implemented with DirectDraw 2.0.
  1019. //
  1020. // I believe that you should not do automatic cursor exclusion in
  1021. // the driver because you will penalize all blts and locks.
  1022. // Grab the hardware - disable HW cursor updates.
  1023. LOCK_HW_SEMAPHORE();
  1024. // Decipher the flags.
  1025. if (dwFlags & DDBLT_ROP)
  1026. {
  1027. static const WORD mix2blt[] =
  1028. { // all ops color vram
  1029. BD_RES ,
  1030. BD_RES | BD_OP0 | BD_OP1,
  1031. BD_RES | BD_OP0 | BD_OP1,
  1032. BD_RES | BD_OP1,
  1033. BD_RES | BD_OP0 | BD_OP1,
  1034. BD_RES | BD_OP0 ,
  1035. BD_RES | BD_OP0 | BD_OP1,
  1036. BD_RES | BD_OP0 | BD_OP1,
  1037. BD_RES | BD_OP0 | BD_OP1,
  1038. BD_RES | BD_OP0 | BD_OP1,
  1039. BD_RES | BD_OP0 ,
  1040. BD_RES | BD_OP0 | BD_OP1,
  1041. BD_RES | BD_OP1,
  1042. BD_RES | BD_OP0 | BD_OP1,
  1043. BD_RES | BD_OP0 | BD_OP1,
  1044. BD_RES
  1045. }; // all ops color vram
  1046. DWORD dwROP = pbd->bltFX.dwROP;
  1047. WORD rop = (WORD) LOBYTE( HIWORD( dwROP ) );
  1048. WORD mix = rop & 0x0f;
  1049. WORD bdf = mix2blt[mix];
  1050. if (bdf & BD_OP1) // SRC rops
  1051. {
  1052. #if defined(DDRAW_COMPAT_10)
  1053. src = pbd->lpDDSrcSurface->lpData;
  1054. #else
  1055. src = pbd->lpDDSrcSurface->lpGbl;
  1056. #endif
  1057. #ifdef WINNT_VER40
  1058. SrcDDRect.loc.DW = cvlxy(ppdev->lDeltaScreen,src->fpVidMem,BYTESPERPIXEL);
  1059. #else // Win95
  1060. SrcDDRect.loc.DW = cvlxy(lpDDHALData,src->fpVidMem-lpDDHALData->ScreenAddress,BYTESPERPIXEL);
  1061. #endif
  1062. SrcDDRect.loc.DW += MAKELONG(pbd->rSrc.left,pbd->rSrc.top);
  1063. SrcDDRect.ext.pt.X = (WORD)(pbd->rSrc.right - pbd->rSrc.left);
  1064. SrcDDRect.ext.pt.Y = (WORD)(pbd->rSrc.bottom - pbd->rSrc.top);
  1065. if (dwFlags & DDBLT_KEYSRCOVERRIDE) // Source Color Key
  1066. {
  1067. DWORD dwColor =
  1068. #ifdef WINNT_VER40
  1069. DupColor(ppdev,
  1070. #else
  1071. DupColor(
  1072. lpDDHALData,
  1073. #endif
  1074. pbd->bltFX.ddckSrcColorkey.dwColorSpaceLowValue);
  1075. DD_LOG(("Src Color Key Blt\r\n"));
  1076. #ifdef DEBUG
  1077. if (FALSE)
  1078. SaveSurfaceToBmp(pbd->lpDDSrcSurface);
  1079. #endif
  1080. if ((SrcDDRect.ext.pt.X != DstDDRect.ext.pt.X) ||
  1081. (SrcDDRect.ext.pt.Y != DstDDRect.ext.pt.Y))
  1082. {
  1083. #ifdef WINNT_VER40
  1084. // If there is no scratch buffer allocated then punt the
  1085. // transparent stretch BLT
  1086. if (lpDDHALData->ScratchBufferOrg == 0)
  1087. {
  1088. ddrval = DDERR_UNSUPPORTED;
  1089. goto blt_exit;
  1090. };
  1091. #endif
  1092. if ( !(pbd->lpDDSrcSurface->dwFlags & DDRAWISURF_HASPIXELFORMAT) &&
  1093. (rop == 0x00CC) )
  1094. {
  1095. if (16 >= BITSPERPIXEL)
  1096. {
  1097. DWORD StretchCntl;
  1098. if (8 == BITSPERPIXEL)
  1099. {
  1100. StretchCntl = (RGB_8_FMT << SRC_FMT_SHIFT) |
  1101. (RGB_8_FMT << DST_FMT_SHIFT) |
  1102. 0;
  1103. }
  1104. else
  1105. {
  1106. // this only works because the src & dst fmt's in stretch control
  1107. // for 565, 24bpp & 32bpp are the same as the bytes/pixel
  1108. StretchCntl = (BYTESPERPIXEL << SRC_FMT_SHIFT) |
  1109. (BYTESPERPIXEL << DST_FMT_SHIFT) |
  1110. 0;
  1111. }
  1112. #ifdef WINNT_VER40
  1113. TransparentStretch65(ppdev, lpDDHALData,
  1114. #else
  1115. TransparentStretch65(
  1116. lpDDHALData,
  1117. #endif
  1118. SrcDDRect, DstDDRect, StretchCntl, dwColor);
  1119. }
  1120. else
  1121. {
  1122. #ifdef WINNT_VER40
  1123. StretchColor(ppdev, lpDDHALData,
  1124. #else
  1125. StretchColor(
  1126. lpDDHALData,
  1127. #endif
  1128. DstDDRect.loc.pt.X, DstDDRect.loc.pt.Y,
  1129. DstDDRect.ext.pt.X, DstDDRect.ext.pt.Y,
  1130. SrcDDRect.loc.pt.X, SrcDDRect.loc.pt.Y,
  1131. SrcDDRect.ext.pt.X, SrcDDRect.ext.pt.Y,
  1132. dwColor);
  1133. }
  1134. goto blt_exit;
  1135. }
  1136. else
  1137. {
  1138. DD_LOG(("Unsupported SrcColorKey Blt -> punt\r\n"));
  1139. ddrval = DDERR_UNSUPPORTED;
  1140. goto blt_exit;
  1141. }
  1142. }
  1143. if (24 != BITSPERPIXEL)
  1144. {
  1145. // if it's 5465AC or earlier, do hw transparency bug workaround
  1146. #ifdef WINNT_VER40
  1147. if (1 >= ppdev->dwLgDevRev)
  1148. #else
  1149. #if 1 //PDR#11507 CK with ConCurrent RAM has the same transparent blt problem with AC.
  1150. if (1 >= lpDDHALData->bLgRevID)
  1151. #else
  1152. if ( ( 1 >= lpDDHALData->bLgRevID ) ||
  1153. ( (0x25 == lpDDHALData->bLgRevID) &&
  1154. lpDDHALData->bConCurrentRAM) )
  1155. #endif
  1156. #endif
  1157. {
  1158. // convert to byte extents and positions
  1159. SrcDDRect.loc.pt.X *= (WORD)BYTESPERPIXEL;
  1160. SrcDDRect.ext.pt.X *= (WORD)BYTESPERPIXEL;
  1161. DstDDRect.loc.pt.X *= (WORD)BYTESPERPIXEL;
  1162. DstDDRect.ext.pt.X *= (WORD)BYTESPERPIXEL;
  1163. if (//(8 >= SrcDDRect.ext.pt.X) &&
  1164. ((7 & SrcDDRect.loc.pt.X) > (7 & DstDDRect.loc.pt.X)))
  1165. {
  1166. WORD x_ext;
  1167. x_ext = 8 - (SrcDDRect.loc.pt.X & 7);
  1168. if (x_ext < SrcDDRect.ext.pt.X)
  1169. {
  1170. #ifdef WINNT_VER40
  1171. ppdev->pfnDrvSrcMBlt(ppdev, lpDDHALData,
  1172. #else
  1173. pfnDrvSrcMBlt(
  1174. lpDDHALData,
  1175. #endif
  1176. #if OP2_ONLY_SRC_COLORKEY
  1177. MAKELONG((DD_TRANS | ROP_OP2_copy),
  1178. ((BD_RES+BD_OP2)*IS_VRAM)),
  1179. #else
  1180. MAKELONG(rop|DD_TRANS, bdf | BD_OP2),
  1181. #endif
  1182. DstDDRect.loc.DW,
  1183. SrcDDRect.loc.DW,
  1184. SrcDDRect.loc.DW, // Src transparency
  1185. dwColor,
  1186. MAKELONG(x_ext,DstDDRect.ext.pt.Y));
  1187. SrcDDRect.loc.pt.X += x_ext;
  1188. DstDDRect.loc.pt.X += x_ext;
  1189. SrcDDRect.ext.pt.X -= x_ext;
  1190. DstDDRect.ext.pt.X -= x_ext;
  1191. }
  1192. }
  1193. #ifdef WINNT_VER40
  1194. ppdev->pfnDrvSrcMBlt(ppdev, lpDDHALData,
  1195. #else
  1196. pfnDrvSrcMBlt(
  1197. lpDDHALData,
  1198. #endif
  1199. #if OP2_ONLY_SRC_COLORKEY
  1200. MAKELONG((DD_TRANS | ROP_OP2_copy),
  1201. ((BD_RES+BD_OP2)*IS_VRAM)),
  1202. #else
  1203. MAKELONG(rop|DD_TRANS, bdf | BD_OP2),
  1204. #endif
  1205. DstDDRect.loc.DW,
  1206. SrcDDRect.loc.DW,
  1207. SrcDDRect.loc.DW, // Src transparency
  1208. dwColor,
  1209. DstDDRect.ext.DW);
  1210. }
  1211. // 5465AD and later can do it as a single blt
  1212. else
  1213. {
  1214. #ifdef WINNT_VER40
  1215. ppdev->pfnDrvSrcBlt(ppdev, lpDDHALData,
  1216. #else
  1217. pfnDrvSrcBlt(
  1218. lpDDHALData,
  1219. #endif
  1220. #if OP2_ONLY_SRC_COLORKEY
  1221. MAKELONG((DD_TRANS | ROP_OP2_copy),
  1222. ((BD_RES+BD_OP2)*IS_VRAM)),
  1223. #else
  1224. MAKELONG(rop|DD_TRANS, bdf | BD_OP2),
  1225. #endif
  1226. DstDDRect.loc.DW,
  1227. SrcDDRect.loc.DW,
  1228. SrcDDRect.loc.DW, // Src transparency
  1229. dwColor,
  1230. DstDDRect.ext.DW);
  1231. }
  1232. }
  1233. else // 24bpp workaround (needed on 5465AD also)
  1234. {
  1235. #ifdef WINNT_VER40
  1236. ColorKeyBlt24(ppdev,lpDDHALData,
  1237. #else
  1238. ColorKeyBlt24(
  1239. lpDDHALData,
  1240. #endif
  1241. #if OP2_ONLY_SRC_COLORKEY
  1242. MAKELONG((DD_TRANS | ROP_OP2_copy),
  1243. ((BD_RES+BD_OP2)*IS_VRAM)),
  1244. #else
  1245. MAKELONG(rop|DD_TRANS, bdf|BD_OP2),
  1246. #endif
  1247. DstDDRect,
  1248. SrcDDRect,
  1249. SrcDDRect, // src transparency
  1250. dwColor);
  1251. }
  1252. #ifdef DEBUG
  1253. if (FALSE)
  1254. SaveSurfaceToBmp(pbd->lpDDDestSurface);
  1255. #endif
  1256. } // (dwFlags & DDBLT_KEYSRCOVERRIDE) // Source Color Key
  1257. else if (dwFlags & DDBLT_KEYDESTOVERRIDE) // Destination Color Key
  1258. {
  1259. DWORD dwColor;
  1260. dwColor =
  1261. #ifdef WINNT_VER40
  1262. DupColor(ppdev,
  1263. #else
  1264. DupColor(
  1265. lpDDHALData,
  1266. #endif
  1267. pbd->bltFX.ddckDestColorkey.dwColorSpaceLowValue);
  1268. DD_LOG(("Dst Color Key Blt\r\n"));
  1269. // Punt if stretch or shrink requested.
  1270. if ((SrcDDRect.ext.pt.X != DstDDRect.ext.pt.X) ||
  1271. (SrcDDRect.ext.pt.Y != DstDDRect.ext.pt.Y))
  1272. {
  1273. DD_LOG(("Unsupported DstColorKey Blt -> punt\r\n"));
  1274. ddrval = DDERR_UNSUPPORTED;
  1275. goto blt_exit;
  1276. }
  1277. #ifdef WINNT_VER40
  1278. // If the dwSize not equal to the size of DDBLTFX structure
  1279. // Punt it.
  1280. //
  1281. // For the WHQL TDDRAW test case 29, for some reason, the DDBLTFX
  1282. // structure in DD_BLTDATA is invalid. The dwSize and the
  1283. // ddckDestColorkey fields contain garbage value.
  1284. // In order to pass the test, we force the dwColor to zero if
  1285. // the dwSize of DDBLTFX is invalid.
  1286. if (pbd->bltFX.dwSize != sizeof(DDBLTFX))
  1287. {
  1288. // ddrval = DDERR_UNSUPPORTED;
  1289. // goto blt_exit;
  1290. dwColor = 0;
  1291. };
  1292. #endif
  1293. if (24 != BITSPERPIXEL)
  1294. {
  1295. #ifdef WINNT_VER40
  1296. ppdev->pfnDrvSrcBlt(ppdev, lpDDHALData,
  1297. #else
  1298. pfnDrvSrcBlt(
  1299. lpDDHALData,
  1300. #endif
  1301. MAKELONG(rop|DD_TRANS|DD_TRANSOP, bdf | BD_OP2),
  1302. DstDDRect.loc.DW,
  1303. SrcDDRect.loc.DW,
  1304. DstDDRect.loc.DW, // Dst transparency
  1305. dwColor, //
  1306. DstDDRect.ext.DW);
  1307. }
  1308. else
  1309. {
  1310. #ifdef WINNT_VER40
  1311. ColorKeyBlt24(ppdev,lpDDHALData,
  1312. #else
  1313. ColorKeyBlt24(
  1314. lpDDHALData,
  1315. #endif
  1316. MAKELONG(rop|DD_TRANS|DD_TRANSOP, bdf|BD_OP2),
  1317. DstDDRect,
  1318. SrcDDRect,
  1319. DstDDRect, // dst transparency
  1320. dwColor);
  1321. }
  1322. } // (dwFlags & DDBLT_KEYDESTOVERRIDE) // Destination Color Key
  1323. else
  1324. {
  1325. #if _WIN32_WINNT >= 0x0500
  1326. #define BLAM (DDRAWISURF_HASPIXELFORMAT)
  1327. #else
  1328. #define BLAM (DDRAWISURF_HASPIXELFORMAT | DDRAWISURF_HASOVERLAYDATA)
  1329. #endif
  1330. if ((BLAM == (BLAM & pbd->lpDDDestSurface->dwFlags)) &&
  1331. (BLAM == (BLAM & pbd->lpDDSrcSurface->dwFlags))
  1332. #if _WIN32_WINNT >= 0x0500
  1333. && (pbd->lpDDDestSurface->ddsCaps.dwCaps & DDSCAPS_OVERLAY)
  1334. && (pbd->lpDDSrcSurface->ddsCaps.dwCaps & DDSCAPS_OVERLAY)
  1335. #endif
  1336. )
  1337. {
  1338. if (//(FOURCC_UYVY == dst->ddpfSurface.dwFourCC) &&
  1339. //(FOURCC_UYVY == src->ddpfSurface.dwFourCC) &&
  1340. (SrcDDRect.ext.pt.X == DstDDRect.ext.pt.X) &&
  1341. (SrcDDRect.ext.pt.Y == DstDDRect.ext.pt.Y))
  1342. {
  1343. #ifndef WINNT_VER40
  1344. LP_SURFACE_DATA lpSrcSurfaceData;
  1345. LP_SURFACE_DATA lpDstSurfaceData;
  1346. #endif
  1347. DWORD dstbpp,srcbpp;
  1348. dstbpp = pbd->lpDDDestSurface->lpGbl->ddpfSurface.dwRGBBitCount / 8;
  1349. srcbpp = pbd->lpDDSrcSurface->lpGbl->ddpfSurface.dwRGBBitCount / 8;
  1350. if (dstbpp != srcbpp)
  1351. {
  1352. ddrval = DDERR_UNSUPPORTED;
  1353. goto blt_exit;
  1354. }
  1355. #ifndef WINNT_VER40
  1356. // see if either the src or dst is a linear surface
  1357. // if so do a CPU memcpy
  1358. lpSrcSurfaceData = (LP_SURFACE_DATA)(pbd->lpDDSrcSurface->dwReserved1);
  1359. lpDstSurfaceData = (LP_SURFACE_DATA)(pbd->lpDDDestSurface->dwReserved1);
  1360. if ((FLG_LINEAR & lpSrcSurfaceData->dwOverlayFlags) ||
  1361. (FLG_LINEAR & lpDstSurfaceData->dwOverlayFlags))
  1362. {
  1363. if (ROP_OP1_copy == rop)
  1364. {
  1365. // mind numbing fb to fb copy
  1366. FBToFBCopy((BYTE *)(lpDDHALData->ScreenAddress + DstDDRect.loc.pt.Y * PITCH + DstDDRect.loc.pt.X * 2),
  1367. dst->lPitch,
  1368. (BYTE *)(lpDDHALData->ScreenAddress + SrcDDRect.loc.pt.Y * PITCH + SrcDDRect.loc.pt.X * 2),
  1369. src->lPitch,
  1370. DstDDRect.ext,
  1371. dstbpp);
  1372. }
  1373. else
  1374. {
  1375. // punt it
  1376. ddrval = DDERR_UNSUPPORTED;
  1377. goto blt_exit;
  1378. }
  1379. }
  1380. else
  1381. #endif
  1382. {
  1383. SrcDDRect.loc.pt.X *= (WORD)BYTESPERPIXEL;
  1384. DstDDRect.loc.pt.X *= (WORD)BYTESPERPIXEL;
  1385. SrcDDRect.ext.pt.X *= (WORD)dstbpp;
  1386. DstDDRect.ext.pt.X *= (WORD)dstbpp;
  1387. #ifdef WINNT_VER40
  1388. ppdev->pfnDrvSrcMBlt(ppdev, lpDDHALData,
  1389. #else
  1390. pfnDrvSrcMBlt(
  1391. lpDDHALData,
  1392. #endif
  1393. MAKELONG(rop, bdf),
  1394. DstDDRect.loc.DW,
  1395. SrcDDRect.loc.DW,
  1396. 0UL, // don't care
  1397. 0UL,
  1398. DstDDRect.ext.DW);
  1399. }
  1400. }
  1401. else
  1402. {
  1403. ddrval = DDERR_UNSUPPORTED;
  1404. goto blt_exit;
  1405. }
  1406. }
  1407. else if ((SrcDDRect.ext.pt.X != DstDDRect.ext.pt.X) ||
  1408. (SrcDDRect.ext.pt.Y != DstDDRect.ext.pt.Y) ||
  1409. (DDRAWISURF_HASPIXELFORMAT & pbd->lpDDSrcSurface->dwFlags))
  1410. {
  1411. DWORD StretchCntl;
  1412. DDRECTL OrigSrcDDRect;
  1413. DDRECTL OrigDstDDRect;
  1414. int nDstBytesPixel = BYTESPERPIXEL;
  1415. int nSrcBytesPixel = BYTESPERPIXEL;
  1416. if (8 == BITSPERPIXEL)
  1417. {
  1418. StretchCntl = (RGB_8_FMT << SRC_FMT_SHIFT) |
  1419. (RGB_8_FMT << DST_FMT_SHIFT) |
  1420. 0;
  1421. }
  1422. else if ((DDRAWISURF_HASPIXELFORMAT & pbd->lpDDSrcSurface->dwFlags) &&
  1423. (DDPF_FOURCC & src->ddpfSurface.dwFlags) &&
  1424. (FOURCC_UYVY == src->ddpfSurface.dwFourCC))
  1425. {
  1426. StretchCntl = (YUV_422_FMT << SRC_FMT_SHIFT)
  1427. | (BYTESPERPIXEL << DST_FMT_SHIFT)
  1428. | XINTERP_ENABLE | YINTERP_ENABLE
  1429. ;
  1430. nSrcBytesPixel = 2;
  1431. }
  1432. else
  1433. {
  1434. // this only works because the src & dst fmt's in stretch control
  1435. // for 565, 24bpp & 32bpp are the same as the bytes/pixel
  1436. StretchCntl = (BYTESPERPIXEL << SRC_FMT_SHIFT)
  1437. | (BYTESPERPIXEL << DST_FMT_SHIFT)
  1438. #if 0
  1439. // tddraw agp Cases 21, 23 & 42 do stretch blts with ddraw and
  1440. // the same stretch through gdi, then they expect the results
  1441. // to be identical
  1442. // Since our display driver is not using interpolation on stretch
  1443. // blts then we either need to rewrite StretchBlt in the display
  1444. // driver (lots of days of work) or disable interpolation in
  1445. // ddraw (a one line change)
  1446. | XINTERP_ENABLE | YINTERP_ENABLE
  1447. #endif
  1448. ;
  1449. }
  1450. // now compute byte coordinates of src and dst
  1451. // upper left of surface is based on frame buffer pixel format
  1452. // offset into surface is based on surface pixel format
  1453. #ifdef WINNT_VER40
  1454. OrigDstDDRect.loc.DW = cvlxy(ppdev->lDeltaScreen,dst->fpVidMem,BYTESPERPIXEL);
  1455. #else
  1456. OrigDstDDRect.loc.DW = cvlxy(lpDDHALData,dst->fpVidMem-lpDDHALData->ScreenAddress,
  1457. BYTESPERPIXEL);
  1458. #endif
  1459. OrigDstDDRect.loc.pt.X *= (USHORT)nDstBytesPixel;
  1460. DstDDRect.loc.DW = OrigDstDDRect.loc.DW;
  1461. #ifdef WINNT_VER40
  1462. OrigSrcDDRect.loc.DW = cvlxy(ppdev->lDeltaScreen,src->fpVidMem,BYTESPERPIXEL);
  1463. #else
  1464. OrigSrcDDRect.loc.DW = cvlxy(lpDDHALData,src->fpVidMem-lpDDHALData->ScreenAddress,
  1465. BYTESPERPIXEL);
  1466. #endif
  1467. OrigSrcDDRect.loc.pt.X *= (USHORT)nDstBytesPixel; // YES, it's nDstBytesPixel
  1468. SrcDDRect.loc.DW = OrigSrcDDRect.loc.DW;
  1469. #ifndef WINNT_VER40 // nt doesn't get this info
  1470. if (pbd->IsClipped)
  1471. {
  1472. OrigDstDDRect.loc.DW += MAKELONG(pbd->rOrigDest.left * nDstBytesPixel,
  1473. pbd->rOrigDest.top);
  1474. OrigDstDDRect.ext.pt.X = (WORD)((pbd->rOrigDest.right - pbd->rOrigDest.left) *
  1475. nDstBytesPixel);
  1476. OrigDstDDRect.ext.pt.Y = (WORD)(pbd->rOrigDest.bottom - pbd->rOrigDest.top);
  1477. OrigSrcDDRect.loc.DW += MAKELONG(pbd->rOrigSrc.left * nSrcBytesPixel,
  1478. pbd->rOrigSrc.top);
  1479. OrigSrcDDRect.ext.pt.X = (WORD)((pbd->rOrigSrc.right - pbd->rOrigSrc.left) *
  1480. nSrcBytesPixel);
  1481. OrigSrcDDRect.ext.pt.Y = (WORD)(pbd->rOrigSrc.bottom - pbd->rOrigSrc.top);
  1482. DstDDRect.loc.DW += MAKELONG(pbd->rDest.left * nDstBytesPixel,
  1483. pbd->rDest.top);
  1484. DstDDRect.ext.pt.X = (WORD)((pbd->rDest.right - pbd->rDest.left) *
  1485. nDstBytesPixel);
  1486. DstDDRect.ext.pt.Y = (WORD)(pbd->rDest.bottom - pbd->rDest.top);
  1487. SrcDDRect.loc.DW += MAKELONG(pbd->rSrc.left * nSrcBytesPixel,
  1488. pbd->rSrc.top);
  1489. SrcDDRect.ext.pt.X = (WORD)((pbd->rSrc.right - pbd->rSrc.left) *
  1490. nSrcBytesPixel);
  1491. SrcDDRect.ext.pt.Y = (WORD)(pbd->rSrc.bottom - pbd->rSrc.top);
  1492. }
  1493. else
  1494. #endif
  1495. {
  1496. OrigDstDDRect.loc.DW += MAKELONG(pbd->rDest.left * nDstBytesPixel,
  1497. pbd->rDest.top);
  1498. DstDDRect.loc.DW = OrigDstDDRect.loc.DW;
  1499. OrigDstDDRect.ext.pt.X = (WORD)((pbd->rDest.right - pbd->rDest.left) *
  1500. nDstBytesPixel);
  1501. DstDDRect.ext.pt.X = OrigDstDDRect.ext.pt.X;
  1502. OrigDstDDRect.ext.pt.Y = (WORD)(pbd->rDest.bottom - pbd->rDest.top);
  1503. DstDDRect.ext.pt.Y = OrigDstDDRect.ext.pt.Y;
  1504. OrigSrcDDRect.loc.DW += MAKELONG(pbd->rSrc.left * nSrcBytesPixel,
  1505. pbd->rSrc.top);
  1506. SrcDDRect.loc.DW = OrigSrcDDRect.loc.DW;
  1507. OrigSrcDDRect.ext.pt.X = (WORD)((pbd->rSrc.right - pbd->rSrc.left) *
  1508. nSrcBytesPixel);
  1509. SrcDDRect.ext.pt.X = OrigSrcDDRect.ext.pt.X;
  1510. OrigSrcDDRect.ext.pt.Y = (WORD)(pbd->rSrc.bottom - pbd->rSrc.top);
  1511. SrcDDRect.ext.pt.Y = OrigSrcDDRect.ext.pt.Y;
  1512. }
  1513. #ifdef WINNT_VER40
  1514. DrvStretch65(ppdev, lpDDHALData,
  1515. #else
  1516. DrvStretch65(
  1517. lpDDHALData,
  1518. #endif
  1519. SrcDDRect,
  1520. DstDDRect,
  1521. StretchCntl,
  1522. OrigSrcDDRect,
  1523. OrigDstDDRect);
  1524. }
  1525. else
  1526. {
  1527. #if ENABLE_CLIPPEDBLTS
  1528. DWORD dstBaseXY;
  1529. DWORD srcBaseXY;
  1530. #ifdef WINNT_VER40
  1531. dstBaseXY = cvlxy(ppdev->lDeltaScreen,dst->fpVidMem,BYTESPERPIXEL);
  1532. srcBaseXY = cvlxy(ppdev->lDeltaScreen,src->fpVidMem,BYTESPERPIXEL);
  1533. #else // Win95
  1534. dstBaseXY = cvlxy(dst->fpVidMem-lpDDHALData->ScreenAddress,BYTESPERPIXEL);
  1535. srcBaseXY = cvlxy(src->fpVidMem-lpDDHALData->ScreenAddress,BYTESPERPIXEL);
  1536. #endif
  1537. if (pbd->IsClipped)
  1538. {
  1539. // compute original dst coordinates
  1540. DstDDRect.loc.DW = dstBaseXY + MAKELONG(pbd->rOrigDest.left, pbd->rOrigDest.top);
  1541. DstDDRect.ext.pt.X = (WORD)(pbd->rOrigDest.right - pbd->rOrigDest.left);
  1542. DstDDRect.ext.pt.Y = (WORD)(pbd->rOrigDest.bottom - pbd->rOrigDest.top);
  1543. // compute original src coordinates
  1544. SrcDDRect.loc.DW = srcBaseXY + MAKELONG(pbd->rOrigSrc.left, pbd->rOrigSrc.top);
  1545. SrcDDRect.ext.pt.X = (WORD)(pbd->rOrigSrc.right - pbd->rOrigSrc.left);
  1546. SrcDDRect.ext.pt.Y = (WORD)(pbd->rOrigSrc.bottom - pbd->rOrigSrc.top);
  1547. // do the blts
  1548. #ifdef WINNT_VER40
  1549. ppdev->pfnClippedDrvSrcBlt(ppdev, lpDDHALData,
  1550. #else
  1551. pfnClippedDrvSrcBlt(
  1552. lpDDHALData,
  1553. #endif
  1554. MAKELONG(rop|DD_CLIP, bdf),
  1555. DstDDRect.loc.DW,
  1556. SrcDDRect.loc.DW,
  1557. 0UL, // don't care
  1558. 0UL,
  1559. DstDDRect.ext.DW,
  1560. dstBaseXY,
  1561. srcBaseXY,
  1562. pbd->dwRectCnt,
  1563. pbd->prDestRects);
  1564. }
  1565. else // just do a single blt
  1566. {
  1567. // compute dst coordinates
  1568. DstDDRect.loc.DW = dstBaseXY + MAKELONG(pbd->rDest.left, pbd->rDest.top);
  1569. DstDDRect.ext.pt.X = (WORD)(pbd->rDest.right - pbd->rDest.left);
  1570. DstDDRect.ext.pt.Y = (WORD)(pbd->rDest.bottom - pbd->rDest.top);
  1571. // compute src coordinates
  1572. SrcDDRect.loc.DW = srcBaseXY + MAKELONG(pbd->rSrc.left, pbd->rSrc.top);
  1573. SrcDDRect.ext.pt.X = (WORD)(pbd->rSrc.right - pbd->rSrc.left);
  1574. SrcDDRect.ext.pt.Y = (WORD)(pbd->rSrc.bottom - pbd->rSrc.top);
  1575. #endif // ENABLE_CLIPPEDBLTS
  1576. // do the blt
  1577. #ifdef WINNT_VER40
  1578. ppdev->pfnDrvSrcBlt(ppdev, lpDDHALData,
  1579. #else
  1580. pfnDrvSrcBlt(
  1581. lpDDHALData,
  1582. #endif
  1583. MAKELONG(rop, bdf),
  1584. DstDDRect.loc.DW,
  1585. SrcDDRect.loc.DW,
  1586. 0UL, // don't care
  1587. 0UL,
  1588. DstDDRect.ext.DW);
  1589. #if ENABLE_CLIPPEDBLTS
  1590. }
  1591. #endif // ENABLE_CLIPPEDBLTS
  1592. }
  1593. }
  1594. }
  1595. else // DST ONLY rops
  1596. {
  1597. #if ENABLE_CLIPPEDBLTS
  1598. DWORD dstBaseXY;
  1599. #endif // ENABLE_CLIPPEDBLTS
  1600. DD_LOG(("Dst Only Blt\r\n"));
  1601. #if ENABLE_CLIPPEDBLTS
  1602. #ifdef WINNT_VER40
  1603. dstBaseXY = cvlxy(ppdev->lDeltaScreen,dst->fpVidMem,BYTESPERPIXEL);
  1604. #else // Win95
  1605. dstBaseXY = cvlxy(dst->fpVidMem-lpDDHALData->ScreenAddress,BYTESPERPIXEL);
  1606. #endif
  1607. if (pbd->IsClipped)
  1608. {
  1609. // compute original dst coordinates
  1610. DstDDRect.loc.DW = dstBaseXY + MAKELONG(pbd->rOrigDest.left, pbd->rOrigDest.top);
  1611. DstDDRect.ext.pt.X = (WORD)(pbd->rOrigDest.right - pbd->rOrigDest.left);
  1612. DstDDRect.ext.pt.Y = (WORD)(pbd->rOrigDest.bottom - pbd->rOrigDest.top);
  1613. // do the blts
  1614. #ifdef WINNT_VER40
  1615. ppdev->pfnDrvClippedDstBlt(ppdev, lpDDHALData,
  1616. #else
  1617. pfnDrvClippedDstBlt(
  1618. lpDDHALData,
  1619. #endif
  1620. MAKELONG(rop|DD_CLIP, bdf),
  1621. DstDDRect.loc.DW,
  1622. 0UL, // don't care
  1623. DstDDRect.ext.DW,
  1624. dstBaseXY,
  1625. pbd->dwRectCnt,
  1626. pbd->prDestRects);
  1627. }
  1628. else // just do a single blt
  1629. {
  1630. // compute dst coordinates
  1631. DstDDRect.loc.DW = dstBaseXY + MAKELONG(pbd->rDest.left, pbd->rDest.top);
  1632. DstDDRect.ext.pt.X = (WORD)(pbd->rDest.right - pbd->rDest.left);
  1633. DstDDRect.ext.pt.Y = (WORD)(pbd->rDest.bottom - pbd->rDest.top);
  1634. #endif // ENABLE_CLIPPEDBLTS
  1635. #ifdef WINNT_VER40
  1636. ppdev->pfnDrvDstBlt(ppdev, lpDDHALData,
  1637. #else
  1638. pfnDrvDstBlt(
  1639. lpDDHALData,
  1640. #endif
  1641. MAKELONG(rop, bdf),
  1642. DstDDRect.loc.DW,
  1643. 0UL, // don't care
  1644. DstDDRect.ext.DW);
  1645. #if ENABLE_CLIPPEDBLTS
  1646. }
  1647. #endif // ENABLE_CLIPPEDBLTS
  1648. } // endif (bdf & BD_OP1) // SRC rops
  1649. } // (dwFlags & DDBLT_ROP)
  1650. else if (dwFlags & DDBLT_COLORFILL)
  1651. {
  1652. DWORD dwColor;
  1653. #if ENABLE_CLIPPEDBLTS
  1654. DWORD dstBaseXY;
  1655. #endif
  1656. DD_LOG(("Solid Color Fill\r\n"));
  1657. #ifdef WINNT_VER40
  1658. dwColor = DupColor(ppdev,pbd->bltFX.dwFillColor);
  1659. #else
  1660. dwColor = DupColor(lpDDHALData,pbd->bltFX.dwFillColor);
  1661. #endif
  1662. #if ENABLE_CLIPPEDBLTS
  1663. #ifdef WINNT_VER40
  1664. dstBaseXY = cvlxy(ppdev->lDeltaScreen,dst->fpVidMem,BYTESPERPIXEL);
  1665. #else // Win95
  1666. dstBaseXY = cvlxy(dst->fpVidMem-lpDDHALData->ScreenAddress,BYTESPERPIXEL);
  1667. #endif
  1668. if (pbd->IsClipped)
  1669. {
  1670. // compute original dst coordinates
  1671. DstDDRect.loc.DW = dstBaseXY + MAKELONG(pbd->rOrigDest.left, pbd->rOrigDest.top);
  1672. DstDDRect.ext.pt.X = (WORD)(pbd->rOrigDest.right - pbd->rOrigDest.left);
  1673. DstDDRect.ext.pt.Y = (WORD)(pbd->rOrigDest.bottom - pbd->rOrigDest.top);
  1674. // do the blts
  1675. #ifdef WINNT_VER40
  1676. ppdev->pfnClippedDrvDstBlt(ppdev, lpDDHALData,
  1677. #else
  1678. pfnDrvClippedDstBlt(
  1679. lpDDHALData,
  1680. #endif
  1681. MAKELONG(ROP_OP1_copy | DD_CLIP, BD_RES | (BD_OP1 * IS_SOLID)),
  1682. DstDDRect.loc.DW,
  1683. dwColor,
  1684. DstDDRect.ext.DW,
  1685. dstBaseXY,
  1686. pbd->dwRectCnt,
  1687. pbd->prDestRects);
  1688. }
  1689. else // just do a single blt
  1690. {
  1691. // compute dst coordinates
  1692. DstDDRect.loc.DW = dstBaseXY + MAKELONG(pbd->rDest.left, pbd->rDest.top);
  1693. DstDDRect.ext.pt.X = (WORD)(pbd->rDest.right - pbd->rDest.left);
  1694. DstDDRect.ext.pt.Y = (WORD)(pbd->rDest.bottom - pbd->rDest.top);
  1695. #endif // ENABLE_CLIPPEDBLTS
  1696. #ifdef WINNT_VER40
  1697. ppdev->pfnDrvDstBlt(ppdev, lpDDHALData,
  1698. #else
  1699. pfnDrvDstBlt(
  1700. lpDDHALData,
  1701. #endif
  1702. MAKELONG(ROP_OP1_copy, BD_RES | (BD_OP1 * IS_SOLID)),
  1703. DstDDRect.loc.DW,
  1704. dwColor, // fill color
  1705. DstDDRect.ext.DW);
  1706. #if ENABLE_CLIPPEDBLTS
  1707. }
  1708. #endif
  1709. }
  1710. #ifndef WINNT_VER40 // Not WINNT_VER40
  1711. else if (bD3DInit && dwFlags & DDBLT_DEPTHFILL)
  1712. {
  1713. DWORD dwFillDepth;
  1714. #if ENABLE_CLIPPEDBLTS // I don't think we'll ever get a clipped zbuffer but you never know ...
  1715. DWORD dstBaseXY;
  1716. #endif // ENABLE_CLIPPEDBLTS
  1717. DD_LOG(("Depth Fill Blt\r\n"));
  1718. #ifdef WINNT_VER40
  1719. dwFillDepth = DupZFill(ppdev,pbd->bltFX.dwFillDepth,dst->ddpfSurface.dwZBufferBitDepth);
  1720. #else
  1721. dwFillDepth = DupZFill(lpDDHALData,pbd->bltFX.dwFillDepth,dst->ddpfSurface.dwZBufferBitDepth);
  1722. #endif
  1723. #if ENABLE_CLIPPEDBLTS
  1724. #ifdef WINNT_VER40
  1725. dstBaseXY = cvlxy(ppdev->lDeltaScreen,dst->fpVidMem,BYTESPERPIXEL);
  1726. #else // Win95
  1727. dstBaseXY = cvlxy(dst->fpVidMem-lpDDHALData->ScreenAddress,BYTESPERPIXEL);
  1728. #endif
  1729. if (pbd->IsClipped)
  1730. {
  1731. // compute original dst coordinates
  1732. DstDDRect.loc.DW = dstBaseXY + MAKELONG(pbd->rOrigDest.left, pbd->rOrigDest.top);
  1733. DstDDRect.ext.pt.X = (WORD)(pbd->rOrigDest.right - pbd->rOrigDest.left);
  1734. DstDDRect.ext.pt.Y = (WORD)(pbd->rOrigDest.bottom - pbd->rOrigDest.top);
  1735. // convert to byte blt
  1736. // 16 bit zbuffer in 32 bit frame buffer trashes everything to right
  1737. // of zbuffer
  1738. // Fixes PDR #9152
  1739. DstDDRect.loc.pt.X *= (WORD)(dst->ddpfSurface.dwZBufferBitDepth / 8);
  1740. DstDDRect.ext.pt.X *= (WORD)(dst->ddpfSurface.dwZBufferBitDepth / 8);
  1741. // do the blts
  1742. #ifdef WINNT_VER40
  1743. ppdev->pfnClippedDrvDstMBlt(ppdev, lpDDHALData,
  1744. #else
  1745. pfnClippedDrvDstMBlt(
  1746. lpDDHALData,
  1747. #endif
  1748. MAKELONG(ROP_OP1_copy | DD_CLIP, BD_RES | (BD_OP1 * IS_SOLID)),
  1749. DstDDRect.loc.DW,
  1750. dwFillDepth,
  1751. DstDDRect.ext.DW,
  1752. dstBaseXY,
  1753. pbd->dwRectCnt,
  1754. pbd->prDestRects);
  1755. }
  1756. else // just do a single blt
  1757. {
  1758. // compute dst coordinates
  1759. DstDDRect.loc.DW = dstBaseXY + MAKELONG(pbd->rDest.left, pbd->rDest.top);
  1760. DstDDRect.ext.pt.X = (WORD)(pbd->rDest.right - pbd->rDest.left);
  1761. DstDDRect.ext.pt.Y = (WORD)(pbd->rDest.bottom - pbd->rDest.top);
  1762. #endif // ENABLE_CLIPPEDBLTS
  1763. // convert to byte blt
  1764. // 16 bit zbuffer in 32 bit frame buffer trashes everything to right
  1765. // of zbuffer
  1766. // Fixes PDR #9152
  1767. DstDDRect.loc.pt.X *= (WORD)(dst->ddpfSurface.dwZBufferBitDepth / 8);
  1768. DstDDRect.ext.pt.X *= (WORD)(dst->ddpfSurface.dwZBufferBitDepth / 8);
  1769. #ifdef WINNT_VER40
  1770. ppdev->pfnDrvDstMBlt(ppdev, lpDDHALData,
  1771. #else
  1772. pfnDrvDstMBlt(
  1773. lpDDHALData,
  1774. #endif
  1775. MAKELONG(ROP_OP1_copy, BD_RES | (BD_OP1 * IS_SOLID)),
  1776. DstDDRect.loc.DW,
  1777. dwFillDepth,
  1778. DstDDRect.ext.DW);
  1779. #if ENABLE_CLIPPEDBLTS
  1780. }
  1781. #endif // ENABLE_CLIPPEDBLTS
  1782. }
  1783. #endif
  1784. else
  1785. {
  1786. DD_LOG(("Unsupported blt - dwFlags = %08lX\r\n", dwFlags));
  1787. ddrval = DDERR_UNSUPPORTED;
  1788. goto blt_exit;
  1789. } // endif (dwFlags & DDBLT_ROP)
  1790. blt_exit:
  1791. // Release the hardware - enable HW cursor updates.
  1792. UNLOCK_HW_SEMAPHORE();
  1793. if (ddrval != DD_OK)
  1794. return DDHAL_DRIVER_NOTHANDLED;
  1795. pbd->ddRVal = DD_OK;
  1796. DD_LOG(("Blt65 Exit\r\n"));
  1797. return DDHAL_DRIVER_HANDLED;
  1798. } /* Blt65 */
  1799. #endif // WINNT_VER35