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.

4303 lines
136 KiB

  1. /***************************************************************************
  2. *
  3. * ******************************************
  4. * * Copyright (c) 1996, Cirrus Logic, Inc. *
  5. * * All Rights Reserved *
  6. * ******************************************
  7. *
  8. * PROJECT: Laguna I (CL-GD546x) -
  9. *
  10. * FILE: ddblt.c
  11. *
  12. * AUTHOR: Benny Ng
  13. *
  14. * DESCRIPTION:
  15. * This module implements the DirectDraw BLT components
  16. * for the Laguna NT driver.
  17. *
  18. * MODULES:
  19. * WINNT WIN95
  20. * DdGetBltStatus() GetBltStatus32()
  21. * SetGamma()
  22. * DrvStretch64() DrvStretch64()
  23. * DrvStretch62() DrvStretch62()
  24. * DdBlt() Blt32()
  25. * DupColor() DupColor()
  26. * EnoughFifoForBlt() EnoughFifoForBlt()
  27. * RGBResizeBOF64()
  28. * RGB16ShrinkBOF64()
  29. *
  30. * REVISION HISTORY:
  31. * 7/12/96 Benny Ng Initial version
  32. *
  33. * $Log: X:/log/laguna/ddraw/src/ddblt.c $
  34. *
  35. * Rev 1.25 Feb 16 1998 16:20:02 frido
  36. * Fixed a NT 4.0 compilation bug (lpData is called lpGbl).
  37. *
  38. * Rev 1.24 14 Jan 1998 06:18:58 eleland
  39. *
  40. * support for display list page-flipping: calls to UpdateFlipStatus are
  41. * thru pointer to function pfnUpdateFlipStatus
  42. *
  43. * Rev 1.23 07 Jan 1998 17:45:30 xcong
  44. * Fix the change for WIN95 which breaks NT in DUP_COLOR macro.
  45. *
  46. * Rev 1.22 06 Jan 1998 14:31:28 xcong
  47. * Change all the macros to use lpDDHALData instead of pDriverData.
  48. *
  49. * Rev 1.21 06 Jan 1998 11:44:42 xcong
  50. * Change pDriverData into local lpDDHALData for multi-monitor support.
  51. *
  52. * Rev 1.20 03 Oct 1997 14:46:50 RUSSL
  53. * Initial changes for use of hw clipped blts
  54. * All changes wrapped in #if ENABLE_CLIPPEDBLTS/#endif blocks and
  55. * ENABLE_CLIPPEDBLTS defaults to 0 (so the code is disabled)
  56. *
  57. * Rev 1.19 01 Oct 1997 17:44:24 eleland
  58. * added check in blt32() to detect blts to host texture surfaces and
  59. * punt those blts back to the ddraw HEL
  60. *
  61. * Rev 1.18 30 Jul 1997 20:56:22 RANDYS
  62. *
  63. * Added code to check for zero extent blts
  64. *
  65. * Rev 1.17 18 Jul 1997 10:23:34 RUSSL
  66. * Modified StretchColor to use function ptr to blt routines rather than
  67. * directly program registers. This is for compatiblity with display lists
  68. *
  69. * Rev 1.16 14 Jul 1997 14:49:32 RUSSL
  70. * Modified BltInit's initialization of pfnDrvStrBlt for Win95
  71. *
  72. * Rev 1.15 08 Jul 1997 11:15:20 RUSSL
  73. * Removed an ASSERT that is no longer valid in StretchColor
  74. *
  75. * Rev 1.14 07 Jul 1997 10:57:14 dzenz
  76. * Added check of DRVSEM_DISPLAY_LIST semaphore to ascertain if
  77. * qmRequestDirectAccess needs to be called.
  78. *
  79. * Rev 1.13 08 Apr 1997 12:17:06 einkauf
  80. * WINNT_VER40 affected only: add SYNC_W_3D to coordinate MCD/2D HW access
  81. *
  82. * Rev 1.12 03 Apr 1997 15:24:48 RUSSL
  83. * Added pfnDrvDstMBlt global var
  84. * Added initializing pfnDrvDstMBlt in BltInit
  85. * Modified DDBLT_DEPTHFILL case in Blt32 to blt based on surface colordepth
  86. * it was clearing 16bit zbuffers in 32bit modes with pixel blts so would
  87. * wipe out everything to the right of the actual zbuffer
  88. * Fixes at least PDRs #9152, 9150 & 8789 (maybe others as well)
  89. *
  90. * Rev 1.11 01 Apr 1997 09:15:24 RUSSL
  91. * Added calls to SyncWithQueueManager in GetBltStatus32
  92. *
  93. * Rev 1.10 26 Mar 1997 14:08:22 RUSSL
  94. * Added pfnDrvSrcMBlt global var
  95. * Added initializing pfnDrvSrcMBlt in BltInit
  96. * Moved sync with queue manager in Blt32 in front of updateFlipStatus since
  97. * updateFlipStatus may access the hardware
  98. *
  99. * Rev 1.9 18 Mar 1997 07:50:24 bennyn
  100. * Resolved NT compiling error by #ifdef queue manager sync call
  101. *
  102. * Rev 1.8 12 Mar 1997 15:02:02 RUSSL
  103. * replaced a block of includes with include of precomp.h for
  104. * precompiled headers
  105. *
  106. * Rev 1.7 07 Mar 1997 12:51:38 RUSSL
  107. * Modified DDRAW_COMPAT usage
  108. *
  109. * Rev 1.6 03 Mar 1997 10:32:34 eleland
  110. * modified queue manager sync call to check 2d display list
  111. * flag; removed USE_QUEUE_MANAGER #ifdef
  112. *
  113. * Rev 1.5 07 Feb 1997 13:22:36 KENTL
  114. * Merged in Evan Leland's modifications to get Display List mode working:
  115. * * include qmgr.h
  116. * * Call qmRequesetDirectAcces() if 3D is busy (Disabled)
  117. *
  118. * Rev 1.4 21 Jan 1997 14:45:42 RUSSL
  119. * Added include of ddinline.h
  120. *
  121. * Rev 1.3 15 Jan 1997 10:45:20 RUSSL
  122. * Made Win95 function ptr vars global
  123. * Moved following inline functions to bltP.h: DupZFill, DupColor &
  124. * EnoughFifoForBlt
  125. *
  126. * Rev 1.2 13 Dec 1996 15:28:32 CRAIGN
  127. * Added a Frido YUV move fix.
  128. *
  129. * Rev 1.1 25 Nov 1996 16:16:10 bennyn
  130. * Fixed misc compiling errors for NT
  131. *
  132. * Rev 1.0 25 Nov 1996 14:43:02 RUSSL
  133. * Initial revision.
  134. *
  135. * Rev 1.6 25 Nov 1996 14:40:02 RUSSL
  136. * Yet another merge of winNT & win95 code
  137. *
  138. * Rev 1.5 25 Nov 1996 11:39:02 RUSSL
  139. * Added TransparentStretch function
  140. *
  141. * Rev 1.4 18 Nov 1996 16:16:18 RUSSL
  142. * Added file logging for DDraw entry points and register writes
  143. *
  144. * Rev 1.3 12 Nov 1996 09:42:02 CRAIGN
  145. * Frido 1112s2 release... fixes TDDRAW case 26.
  146. * Changed transparency for DDBLT_KEYDESTOVERRIDE to "not equal."
  147. *
  148. * Rev 1.2 11 Nov 1996 12:36:48 CRAIGN
  149. * Frido 1112 release - added software color key stretch.
  150. *
  151. * Rev 1.1 06 Nov 1996 12:28:42 CRAIGN
  152. * Frido 1106 - added check for rectangle movement.
  153. *
  154. * Rev 1.0 01 Nov 1996 13:09:30 RUSSL
  155. * Merge WIN95 & WINNT code for Blt32
  156. *
  157. * Rev 1.9 01 Nov 1996 09:23:24 BENNYN
  158. * Initial copy of shareable DD blt code
  159. *
  160. * COMBINED WINNT & WIN95 VERSIONS OF BLT CODE
  161. *
  162. * Rev 1.17 25 Oct 1996 11:55:54 RUSSL
  163. * Forgot to remove the undef RDRAM_8BIT
  164. *
  165. * Rev 1.16 25 Oct 1996 11:50:16 RUSSL
  166. * Added use of function pointers for all the short blt functions (like
  167. * DrvDstBlt, DrvSrcBlt, etc.). Moved the short blt functions to a
  168. * separate file (blt_dir.c). Modified DrvStretch64, DrvStretch62,
  169. * RGBResizeBOF64 & RGB16ShrinkBOF64 to use the blt function pointers
  170. * rather than directly call one of the short blt functions or write
  171. * directly to the registers. This enables the short blt functions to
  172. * be written as display lists rather than directly writing to the
  173. * registers (in fact, that's whats in blt_dl.c)
  174. *
  175. * Added BltInit function to initialize the function pointers. BltInit
  176. * needs to be called by buildHALInfo32.
  177. *
  178. * Rev 1.15 21 Oct 1996 11:56:08 RUSSL
  179. * Added RGB16ShrinkBOF64 to handle 16bpp shrink blts on the 5464
  180. * Now RGBResizeBOF64 only handles 8bpp stretches, 8bpp shrinks and
  181. * 16bpp stretches on the 5464
  182. * Added QFREE checking before blts in both RGB???BOF64 functions
  183. *
  184. * Rev 1.14 16 Oct 1996 16:10:40 RUSSL
  185. * Added RGBResizeBOF64 to handle resize blts on 5464
  186. * 8bpp stretches, 8bpp shrinks and 16bpp stretches ain't perfect but
  187. * hopefully they're acceptable
  188. * 16bpp shrinks are still broken
  189. *
  190. * Rev 1.13 07 Oct 1996 09:03:04 RUSSL
  191. * Modified DDRAW_COMPAT_xx conditionally compiled stuff
  192. *
  193. * Rev 1.12 04 Oct 1996 11:39:10 KENTL
  194. * Fixed PDR#6799 - playing two AVI's result in first window replicated in
  195. * second. Changed the way Blt32 does an x-coordinate computation.
  196. *
  197. * Rev 1.11 04 Oct 1996 10:46:50 KENTL
  198. * Added fix for 32bpp video bug: we were trying to do stretches in 32bpp,
  199. * which a) is not supported in HW and b) was being interpreted as 16bpp
  200. * which cause really lousy things to happen on the screen.
  201. *
  202. * Rev 1.9 04 Sep 1996 17:32:06 MARTINB
  203. * Corrected shrink by 8 bug in odd sized mpegs.
  204. * Corrected multiple mpeg sources corrupting working stroage.
  205. *
  206. * Rev 1.8 22 Aug 1996 10:37:14 MARTINB
  207. * Corrected a number of QFREE check constants for the strech62 routines that
  208. * were causing sound breakup on moving / resizing a video window.
  209. *
  210. * Rev 1.7 14 Aug 1996 16:53:20 MARTINB
  211. * Yet another last minute fix to the last minute fix. This one fixes
  212. * the banding in 422 video caused by doing the blt twice. The second time
  213. * incorrectly !!
  214. *
  215. * Rev 1.6 13 Aug 1996 13:25:02 MARTINB
  216. * Moved shrink rejection for 565/8bit formats to correct place in blt32 logic
  217. *
  218. * Rev 1.5 13 Aug 1996 08:31:12 MARTINB
  219. * Added stretch routines for CL-GD5464 support
  220. * renamed previous stretch logic to DrvStretch62.
  221. *
  222. * Rev 1.4 23 Jul 1996 11:20:04 KENTL
  223. * Merged in Jeff Orts D3D integration changes.
  224. * * Created DupZFill()
  225. * * Added code to do Z-Fill blits.
  226. *
  227. * Rev 1.3 19 Jul 1996 16:24:38 CRAIGN
  228. * Removed two int 3s that I left in the code.
  229. *
  230. * Rev 1.2 19 Jul 1996 09:31:20 CRAIGN
  231. * Added workaround for Stretch Bug o' Death.
  232. * Instead of doing SRAM blts to make sure that PTAG is set/reset,
  233. * use a destcopy blt to PTAGFooPixel. This x/y coordinate is set by the
  234. * display driver to be one pixel below the bottom of the screen (where the
  235. * scratch buffer lives).
  236. *
  237. * Rev 1.1 15 Jul 1996 16:58:40 RUSSL
  238. * Added support for DirectDraw 3.0
  239. *
  240. * Rev 1.0 26 Jun 1996 11:05:06 RUSSL
  241. * Initial revision.
  242. *
  243. ****************************************************************************
  244. ****************************************************************************/
  245. /*----------------------------- INCLUDES ----------------------------------*/
  246. #include "precomp.h"
  247. // If WinNT 3.5 skip all the source code
  248. #if defined WINNT_VER35 // WINNT_VER35
  249. #else
  250. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  251. #ifndef WINNT_VER40 // Not WINNT_VER40
  252. #include "flip.h"
  253. #include "surface.h"
  254. #include "blt.h"
  255. #include "palette.h"
  256. #include "qmgr.h"
  257. #include "bltP.h"
  258. #include "ddinline.h"
  259. #include "ddshared.h"
  260. #endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
  261. /*----------------------------- DEFINES -----------------------------------*/
  262. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  263. #ifdef WINNT_VER40 // WINNT_VER40
  264. // DBGBREAKPOINT();
  265. #define AFPRINTF(n)
  266. #define DBGLVL 1
  267. #define DBGLVL1 1
  268. #define DBGLVL2 1 // DrvSrcBlt & SrvDstBlt
  269. #define DBGLVL3 1 // DrvStretchBlt
  270. #define LGDEVID ppdev->dwLgDevID
  271. #define OFFSCR_YUV_VAR ppdev->offscr_YUV
  272. #define MEMCMP(A,B) memcmp(&ppdev->offscr_YUV.SrcRect, (A),(B))
  273. #define DRAW_ENGINE_BUSY DrawEngineBusy(lpDDHALData)
  274. #define ENOUGH_FIFO_FOR_BLT EnoughFifoForBlt(DRIVERDATA* lpDDHALData)
  275. #define SET_GAMMA SetGamma(PDEV* ppdev, DRIVERDATA* lpDDHALData)
  276. #define UPDATE_FLIP_STATUS(arg) vUpdateFlipStatus(&ppdev->flipRecord, (arg))
  277. #define DRVSTRETCH64 DrvStretch64(PDEV* ppdev, DRIVERDATA* lpDDHALData,
  278. #define DRVSTRETCH62 DrvStretch62(PDEV* ppdev, DRIVERDATA* lpDDHALData,
  279. #define DUP_COLOR DupColor(PDEV* ppdev,
  280. #define RGB_RESIZEBOF64 RGBResizeBOF64(PDEV* ppdev, DRIVERDATA* lpDDHALData,
  281. #define RGB_16SHRINKBOF64 RGB16ShrinkBOF64(PDEV* ppdev, DRIVERDATA* lpDDHALData,
  282. #define DUPZFILL DupZFill(PDEV* ppdev,
  283. #define CALL_ENOUGH_FIFO_FOR_BLT EnoughFifoForBlt(lpDDHALData)
  284. #define CALL_DELAY_9BIT_BLT(arg) ppdev->pfnDelay9BitBlt(ppdev,lpDDHALData, (arg))
  285. #define CALL_EDGE_FILL_BLT(A,B,C,D,E,F) ppdev->pfnEdgeFillBlt(ppdev,lpDDHALData, (A),(B),(C),(D),(E),(F))
  286. #define CALL_MEDGE_FILL_BLT(A,B,C,D,E,F) ppdev->pfnMEdgeFillBlt(ppdev,lpDDHALData, (A),(B),(C),(D),(E),(F))
  287. #define CALL_DRV_DST_BLT(A,B,C,D) ppdev->pfnDrvDstBlt(ppdev,lpDDHALData, (A),(B),(C),(D))
  288. #define CALL_DRV_DST_MBLT(A,B,C,D) ppdev->pfnDrvDstMBlt(ppdev,lpDDHALData, (A),(B),(C),(D))
  289. #define CALL_DRV_SRC_BLT(A,B,C,D,E,F) ppdev->pfnDrvSrcBlt(ppdev,lpDDHALData, (A),(B),(C),(D),(E),(F))
  290. #define CALL_DRV_STR_BLT(A) ppdev->pfnDrvStrBlt(ppdev,lpDDHALData, (A))
  291. #define CALL_DRV_STR_MBLT(A) ppdev->pfnDrvStrMBlt(ppdev,lpDDHALData, (A))
  292. #define CALL_DRV_STR_MBLTX(A) ppdev->pfnDrvStrMBltX(ppdev,lpDDHALData, (A))
  293. #define CALL_DRV_STR_MBLTY(A) ppdev->pfnDrvStrMBltY(ppdev,lpDDHALData, (A))
  294. #define CALL_DRV_STR_BLTY(A) ppdev->pfnDrvStrBltY(ppdev,lpDDHALData, (A))
  295. #define CALL_DRV_STR_BLTX(A) ppdev->pfnDrvStrBltX(ppdev,lpDDHALData, (A))
  296. #define CALL_DIR_DELAY_9BIT_BLT(arg) DIR_Delay9BitBlt(ppdev,lpDDHALData, (arg))
  297. #define CALL_DIR_EDGE_FILL_BLT(A,B,C,D,E,F) DIR_EdgeFillBlt(ppdev,lpDDHALData, (A),(B),(C),(D),(E),(F))
  298. #define CALL_DIR_MEDGE_FILL_BLT(A,B,C,D,E,F) DIR_MEdgeFillBlt(ppdev,lpDDHALData, (A),(B),(C),(D),(E),(F))
  299. #define CALL_DIR_DRV_DST_BLT(A,B,C,D) DIR_DrvDstBlt(ppdev,lpDDHALData, (A),(B),(C),(D))
  300. #define CALL_DIR_DRV_STR_BLT(A) DIR_DrvStrBlt(ppdev,lpDDHALData, (A))
  301. #define CALL_DIR_DRV_STR_MBLT(A) DIR_DrvStrMBlt(ppdev,lpDDHALData, (A))
  302. #define CALL_DIR_DRV_STR_MBLTX(A) DIR_DrvStrMBltX(ppdev,lpDDHALData, (A))
  303. #define CALL_DIR_DRV_STR_MBLTY(A) DIR_DrvStrMBltY(ppdev,lpDDHALData, (A))
  304. #define CALL_DRVSTRETCH64(A,B,C,D,E,F,G,H,I,J,K,L) DrvStretch64(ppdev,lpDDHALData,(A),(B),(C),(D),(E),(F),(G),(H),(I),(J),(K),(L))
  305. #define CALL_DRVSTRETCH62(A,B,C,D,E,F,G,H,I,J,K,L) DrvStretch62(ppdev,lpDDHALData,(A),(B),(C),(D),(E),(F),(G),(H),(I),(J),(K),(L))
  306. #define CALL_DUP_COLOR(A) DupColor(ppdev, (A))
  307. #define CALL_RGB_RESIZEBOF64(A,B,C,D,E,F,G,H) RGBResizeBOF64(ppdev,lpDDHALData,(A),(B),(C),(D),(E),(F),(G),(H))
  308. #define CALL_RGB_16SHRINKBOF64(A,B,C,D,E,F,G,H) RGB16ShrinkBOF64(ppdev,lpDDHALData,(A),(B),(C),(D),(E),(F),(G),(H))
  309. #define CALL_DUPZFILL(A,B) DupZFill(ppdev, (A),(B))
  310. #define STRETCHCOLOR StretchColor(PDEV* ppdev, DRIVERDATA* lpDDHALData,
  311. #define CALL_STRETCHCOLOR(A,B,C,D,E,F,G,H,I) StretchColor(ppdev,lpDDHALData,(A),(B),(C),(D),(E),(F),(G),(H),(I))
  312. #define TRANSPARENTSTRETCH TransparentStretch(PDEV* ppdev, DRIVERDATA* lpDDHALData,
  313. #define CALL_TRANSPARENTSTRETCH(A,B,C,D,E,F,G,H,I) TransparentStretch(ppdev,lpDDHALData,(A),(B),(C),(D),(E),(F),(G),(H),(I))
  314. #else // ----- #elseif WINNT_VER40-----
  315. #define TRACE_STRETCH 1
  316. #define TRACE_ALL 1
  317. #define LGDEVID lpDDHALData->dwLgVenDevID
  318. #define OFFSCR_YUV_VAR offscr_YUV
  319. #define MEMCMP(A,B) memcmp(&offscr_YUV.SrcRect, (A),(B))
  320. #define ENOUGH_FIFO_FOR_BLT EnoughFifoForBlt(lpDDHALData)
  321. #define SET_GAMMA SetGamma(lpDDHALData)
  322. #define UPDATE_FLIP_STATUS(arg) updateFlipStatus((arg), lpDDHALData)
  323. #define DRVSTRETCH64 DrvStretch64(
  324. #define DRVSTRETCH62 DrvStretch62(
  325. #define DUP_COLOR DupColor(
  326. #define RGB_RESIZEBOF64 RGBResizeBOF64(
  327. #define RGB_16SHRINKBOF64 RGB16ShrinkBOF64(
  328. #define DUPZFILL DupZFill(
  329. #define CALL_ENOUGH_FIFO_FOR_BLT EnoughFifoForBlt(lpDDHALData)
  330. #define CALL_DELAY_9BIT_BLT(arg) pfnDelay9BitBlt(lpDDHALData,(arg))
  331. #define CALL_EDGE_FILL_BLT(A,B,C,D,E,F) pfnEdgeFillBlt(lpDDHALData,(A),(B),(C),(D),(E),(F))
  332. #define CALL_MEDGE_FILL_BLT(A,B,C,D,E,F) pfnMEdgeFillBlt(lpDDHALData,(A),(B),(C),(D),(E),(F))
  333. #define CALL_DRV_DST_BLT(A,B,C,D) pfnDrvDstBlt(lpDDHALData,(A),(B),(C),(D))
  334. #define CALL_DRV_DST_MBLT(A,B,C,D) pfnDrvDstMBlt(lpDDHALData,(A),(B),(C),(D))
  335. #define CALL_DRV_SRC_BLT(A,B,C,D,E,F) pfnDrvSrcBlt(lpDDHALData,(A),(B),(C),(D),(E),(F))
  336. #define CALL_DRV_STR_BLT(A) pfnDrvStrBlt(lpDDHALData,(A))
  337. #define CALL_DRV_STR_MBLT(A) pfnDrvStrMBlt(lpDDHALData,(A))
  338. #define CALL_DRV_STR_MBLTX(A) pfnDrvStrMBltX(lpDDHALData,(A))
  339. #define CALL_DRV_STR_MBLTY(A) pfnDrvStrMBltY(lpDDHALData,(A))
  340. #define CALL_DRV_STR_BLTY(A) pfnDrvStrBltY(lpDDHALData,(A))
  341. #define CALL_DRV_STR_BLTX(A) pfnDrvStrBltX(lpDDHALData,(A))
  342. #define CALL_DIR_DELAY_9BIT_BLT(arg) DIR_Delay9BitBlt(lpDDHALData,(arg))
  343. #define CALL_DIR_EDGE_FILL_BLT(A,B,C,D,E,F) DIR_EdgeFillBlt(lpDDHALData,(A),(B),(C),(D),(E),(F))
  344. #define CALL_DIR_MEDGE_FILL_BLT(A,B,C,D,E,F) DIR_MEdgeFillBlt(lpDDHALData,(A),(B),(C),(D),(E),(F))
  345. #define CALL_DIR_DRV_DST_BLT(A,B,C,D) DIR_DrvDstBlt(lpDDHALData,(A),(B),(C),(D))
  346. #define CALL_DIR_DRV_STR_BLT(A) DIR_DrvStrBlt(lpDDHALData,(A))
  347. #define CALL_DIR_DRV_STR_MBLT(A) DIR_DrvStrMBlt(lpDDHALData,(A))
  348. #define CALL_DIR_DRV_STR_MBLTX(A) DIR_DrvStrMBltX(lpDDHALData,(A))
  349. #define CALL_DIR_DRV_STR_MBLTY(A) DIR_DrvStrMBltY(lpDDHALData,(A))
  350. #define CALL_DRVSTRETCH64(A,B,C,D,E,F,G,H,I,J,K,L) DrvStretch64(lpDDHALData,(A),(B),(C),(D),(E),(F),(G),(H),(I),(J),(K),(L))
  351. #define CALL_DRVSTRETCH62(A,B,C,D,E,F,G,H,I,J,K,L) DrvStretch62(lpDDHALData,(A),(B),(C),(D),(E),(F),(G),(H),(I),(J),(K),(L))
  352. #define CALL_DUP_COLOR(A) DupColor(lpDDHALData,(A))
  353. #define CALL_RGB_RESIZEBOF64(A,B,C,D,E,F,G,H) RGBResizeBOF64(lpDDHALData,(A),(B),(C),(D),(E),(F),(G),(H))
  354. #define CALL_RGB_16SHRINKBOF64(A,B,C,D,E,F,G,H) RGB16ShrinkBOF64(lpDDHALData,(A),(B),(C),(D),(E),(F),(G),(H))
  355. #define CALL_DUPZFILL(A,B) DupZFill(lpDDHALData,(A),(B))
  356. #define STRETCHCOLOR StretchColor(
  357. #define CALL_STRETCHCOLOR(A,B,C,D,E,F,G,H,I) StretchColor(lpDDHALData,(A),(B),(C),(D),(E),(F),(G),(H),(I))
  358. #define TRANSPARENTSTRETCH TransparentStretch(
  359. #define CALL_TRANSPARENTSTRETCH(A,B,C,D,E,F,G,H,I) TransparentStretch(lpDDHALData,(A),(B),(C),(D),(E),(F),(G),(H),(I))
  360. #endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
  361. typedef short DDAX;
  362. typedef struct {DDAX accum; DDAX maj; DDAX min;} AXIS;
  363. #define EDGE_CLIP // Trim excess pixels from edges (>= 10%) in 8Bpp Mode
  364. #define EDGE_CLIP_16 // Trim excess pixels from edges (>= 10%) in 8Bpp Mode
  365. #define BOGUS_YUV 0x0081 // Top of palette below Windows reserved area
  366. //#define BOGUS_8BIT
  367. #define LOCK_HW_SEMAPHORE() (lpDDHALData->DrvSemaphore |= DRVSEM_IN_USE)
  368. #define UNLOCK_HW_SEMAPHORE() (lpDDHALData->DrvSemaphore &= ~ DRVSEM_IN_USE)
  369. /*--------------------- STATIC FUNCTION PROTOTYPES ------------------------*/
  370. #ifdef WINNT_VER40
  371. static __inline DWORD DUP_COLOR DWORD dwColor );
  372. #else
  373. static __inline DWORD DUP_COLOR LPGLOBALDATA lpDDHALData, DWORD dwColor );
  374. #endif
  375. static __inline BOOL ENOUGH_FIFO_FOR_BLT;
  376. /*--------------------------- ENUMERATIONS --------------------------------*/
  377. /*----------------------------- TYPEDEFS ----------------------------------*/
  378. /*-------------------------- STATIC VARIABLES -----------------------------*/
  379. static const WORD lncntl[] = {LN_8BIT, LN_RGB565, LN_24PACK, LN_24ARGB,};
  380. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  381. #ifndef WINNT_VER40 // Not WINNT_VER40
  382. ASSERTFILE("blt.c");
  383. OFFSCR_YUV offscr_YUV = {{ 0, 0, 0, 0}, FALSE};
  384. PFN_DELAY9BLT pfnDelay9BitBlt;
  385. PFN_EDGEFILLBLT pfnEdgeFillBlt;
  386. PFN_MEDGEFILLBLT pfnMEdgeFillBlt;
  387. PFN_DRVDSTBLT pfnDrvDstBlt;
  388. PFN_DRVDSTMBLT pfnDrvDstMBlt;
  389. PFN_DRVSRCBLT pfnDrvSrcBlt;
  390. PFN_DRVSRCMBLT pfnDrvSrcMBlt;
  391. PFN_DRVSTRBLT pfnDrvStrBlt;
  392. PFN_DRVSTRMBLT pfnDrvStrMBlt;
  393. PFN_DRVSTRMBLTY pfnDrvStrMBltY;
  394. PFN_DRVSTRMBLTX pfnDrvStrMBltX;
  395. PFN_DRVSTRBLTY pfnDrvStrBltY;
  396. PFN_DRVSTRBLTX pfnDrvStrBltX;
  397. extern PFN_UPDATEFLIPSTATUS pfnUpdateFlipStatus;
  398. #if ENABLE_CLIPPEDBLTS
  399. PFN_CLIPPEDDRVDSTBLT pfnClippedDrvDstBlt;
  400. PFN_CLIPPEDDRVDSTMBLT pfnClippedDrvDstMBlt;
  401. PFN_CLIPPEDDRVSRCBLT pfnClippedDrvSrcBlt;
  402. #endif
  403. #endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
  404. /*-------------------------- GLOBAL FUNCTIONS -----------------------------*/
  405. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  406. #ifdef WINNT_VER40 // WINNT_VER40
  407. //***** SetGamma ********************************************************
  408. // Use only for YUV 8BPP
  409. //
  410. #define LOWER_YUV 16
  411. #define UPPER_YUV 240
  412. #define LOWER_PALETTE 0
  413. #define UPPER_PALETTE 255
  414. void SetGamma(PDEV* ppdev, DRIVERDATA* lpDDHALData)
  415. {
  416. int indx;
  417. PVGAR pREG = (PVGAR) lpDDHALData->RegsAddress;
  418. DISPDBG((DBGLVL, "DDraw - SetGamma\n"));
  419. for ( indx = LOWER_PALETTE ; indx <= UPPER_PALETTE ; indx++ )
  420. { // Initialise gamma palette
  421. int value;
  422. value = ((indx - LOWER_YUV) * UPPER_PALETTE) / (UPPER_YUV - LOWER_YUV);
  423. if ( value < LOWER_PALETTE )
  424. value = LOWER_PALETTE;
  425. if ( value > UPPER_PALETTE )
  426. value = UPPER_PALETTE;
  427. LL8(grPalette_Write_Address, (BYTE)(indx));
  428. LL8(grPalette_Data, (BYTE)(value)); // Red
  429. LL8(grPalette_Data, (BYTE)(value)); // Grn
  430. LL8(grPalette_Data, (BYTE)(value)); // Blu
  431. };
  432. } // SetGamma
  433. #endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
  434. /***************************************************************************
  435. *
  436. * FUNCTION: RGBResizeBOF64
  437. *
  438. * DESCRIPTION: Handles 8bpp RGB stretches, 8bpp RGB shrinks and
  439. * 16bpp RGB stretches on the 5464
  440. *
  441. ****************************************************************************/
  442. #define SRAM_SIZE 128
  443. void RGB_RESIZEBOF64
  444. #ifndef WINNT_VER40
  445. LPGLOBALDATA lpDDHALData,
  446. #endif
  447. int xDst, int yDst, int cxDst, int cyDst,
  448. int xSrc, int ySrc, int cxSrc, int cySrc )
  449. {
  450. const int nBytesPixel = BYTESPERPIXEL;
  451. // setting nSRAMPixels to the number of pixels that fit in sram divided
  452. // by two gives better shrinks at 8bpp and doesn't lock up the chip on
  453. // stretches at 16bpp
  454. const int nSRAMPixels = (SRAM_SIZE / nBytesPixel) / 2;
  455. const int nSRAMMask = nSRAMPixels - 1;
  456. autoblt_regs bltr;
  457. AXIS axis[2];
  458. int nDst[2];
  459. int nSrc[2];
  460. int i;
  461. DDAX accx;
  462. int srcxext;
  463. int dstxext;
  464. int srcx;
  465. int xext;
  466. DD_LOG(("RGBResizeBOF64 - %d bpp %s in X\r\n", nBytesPixel,
  467. (cxDst < cxSrc) ? "shrink" : "stretch"));
  468. DD_LOG(("dst=%08lX dstext=%08lX src=%08lX srcext=%08lX\r\n",
  469. MAKELONG(xDst,yDst),MAKELONG(cxDst,cyDst),
  470. MAKELONG(xSrc,ySrc),MAKELONG(cxSrc,cySrc)));
  471. #ifndef WINNT_VER40
  472. // Verify this is an 8bpp shrink or stretch
  473. // or its a 16bpp stretch
  474. ASSERT((1 == nBytesPixel) || (cxSrc <= cxDst));
  475. DBG_MESSAGE((" RGBResizeBOF64 - Dst %08lXh,%08lXh %08lX,%08lX",xDst,yDst,cxDst,cyDst));
  476. DBG_MESSAGE((" Src %08lXh,%08lXh %08lX,%08lX",xSrc,ySrc,cxSrc,cySrc));
  477. #endif
  478. // initialize auto blt struct
  479. bltr.DRAWBLTDEF.DW = MAKELONG(ROP_OP1_copy, (BD_RES+BD_OP1)*IS_VRAM);
  480. bltr.OP0_opRDRAM.DW = MAKELONG(LOWORD(xDst),LOWORD(yDst));
  481. bltr.OP1_opRDRAM.DW = MAKELONG(LOWORD(xSrc),LOWORD(ySrc));
  482. bltr.BLTEXT.DW = MAKELONG(LOWORD(cxDst),LOWORD(cyDst));
  483. bltr.LNCNTL.W = lncntl[nBytesPixel-1] << LN_YUV_SHIFT;
  484. bltr.SRCX = cxSrc * nBytesPixel;
  485. // Enable interpolation unless we have a palette (8bpp)
  486. if (1 < nBytesPixel)
  487. bltr.LNCNTL.W |= (LN_XINTP_EN | LN_YINTP_EN);
  488. bltr.SHRINKINC.W = 0x0000;
  489. if (cxDst < cxSrc)
  490. {
  491. bltr.LNCNTL.W |= LN_XSHRINK;
  492. bltr.LNCNTL.W &= ~LN_XINTP_EN;
  493. bltr.SHRINKINC.pt.X = (cxSrc / cxDst);
  494. }
  495. if ( cyDst < cySrc )
  496. {
  497. bltr.LNCNTL.W |= LN_YSHRINK;
  498. bltr.LNCNTL.W &= ~LN_YINTP_EN;
  499. bltr.SHRINKINC.pt.Y = (cySrc / cyDst);
  500. }
  501. // Compute DDA terms.
  502. nDst[0] = cxDst;
  503. nDst[1] = cyDst;
  504. nSrc[0] = cxSrc;
  505. nSrc[1] = cySrc;
  506. for (i = 0; i < 2; i++)
  507. {
  508. int kDst = 1;
  509. if (bltr.LNCNTL.W & ((i==0) ? LN_XINTP_EN : LN_YINTP_EN))
  510. {
  511. nDst[i] *= 4;
  512. nSrc[i] *= 4;
  513. nSrc[i] -= 3;
  514. kDst = 0x8000 / nDst[i];
  515. }
  516. if (bltr.LNCNTL.W & ((i==0) ? LN_XSHRINK : LN_YSHRINK))
  517. { /* Shrink Terms */
  518. axis[i].maj = (short)nDst[i];
  519. axis[i].min = - (nSrc[i] % nDst[i]);
  520. axis[i].accum = axis[i].maj - 1
  521. - ((nSrc[i] % nDst[i]) / (nSrc[i]/nDst[i] + 1));
  522. }
  523. else
  524. { /* Stretch Terms */
  525. axis[i].maj = kDst * nDst[i];
  526. axis[i].min = -kDst * nSrc[i];
  527. axis[i].accum = axis[i].maj - 1
  528. - ((axis[i].maj % -axis[i].min) / (nDst[i]/nSrc[i] + 1));
  529. }
  530. }
  531. bltr.MAJ_X = axis[0].maj;
  532. bltr.MIN_X = axis[0].min;
  533. bltr.ACCUM_X = axis[0].accum;
  534. bltr.MAJ_Y = axis[1].maj;
  535. bltr.MIN_Y = axis[1].min;
  536. bltr.ACCUM_Y = axis[1].accum;
  537. // write settings that don't vary over stripes to the chip
  538. CALL_DRV_STR_BLTY(&bltr);
  539. if (bltr.LNCNTL.W & LN_XSHRINK)
  540. {
  541. // 8bpp shrink in X
  542. accx = bltr.ACCUM_X;
  543. while (cxDst > 0)
  544. {
  545. // walk DDA to determine number of src & dst pixels to blt in
  546. // current stripe
  547. // computes error term (accx) for next stripe also
  548. srcxext = 0;
  549. dstxext = 0;
  550. for (;;)
  551. {
  552. // check for worst case srcxext larger than num pixels that
  553. // fit in sram
  554. if ((srcxext + bltr.SHRINKINC.pt.X + 1) > nSRAMPixels)
  555. break;
  556. accx += bltr.MIN_X;
  557. srcxext += bltr.SHRINKINC.pt.X;
  558. if (0 > accx)
  559. {
  560. accx += bltr.MAJ_X;
  561. srcxext++;
  562. }
  563. dstxext++;
  564. if (dstxext >= cxDst)
  565. break;
  566. }
  567. // adjust dst extent
  568. bltr.BLTEXT.pt.X = (USHORT)dstxext;
  569. // blt current stripe
  570. CALL_DRV_STR_BLTX(&bltr);
  571. // adjust dst extent remaining
  572. cxDst -= dstxext;
  573. // update auto blt struct settings
  574. // increment xDst & xSrc
  575. // store error term for next stripe
  576. bltr.OP0_opRDRAM.pt.X += (USHORT)dstxext;
  577. bltr.OP1_opRDRAM.pt.X += (USHORT)srcxext;
  578. bltr.ACCUM_X = accx;
  579. }
  580. }
  581. else
  582. {
  583. // stretch in X
  584. // set values for initial stripe
  585. xext = ((xDst + nSRAMPixels) & (~nSRAMMask)) - xDst;
  586. accx = bltr.ACCUM_X;
  587. srcx = xSrc;
  588. while (cxDst > xext)
  589. {
  590. // update auto blt struct settings
  591. bltr.OP0_opRDRAM.pt.X = (USHORT)xDst;
  592. bltr.OP1_opRDRAM.pt.X = (USHORT)srcx;
  593. bltr.ACCUM_X = accx;
  594. bltr.BLTEXT.pt.X = (USHORT)xext;
  595. // blt current stripe
  596. CALL_DRV_STR_BLTX(&bltr);
  597. // increment xDst and decrement remaining dst extent
  598. xDst += xext;
  599. cxDst -= xext;
  600. // walk DDA to compute error term (accx) and xSrc for next stripe
  601. for (i = 0; i < xext; i++)
  602. {
  603. accx += bltr.MIN_X;
  604. if (0 > accx)
  605. {
  606. accx += bltr.MAJ_X;
  607. srcx++;
  608. }
  609. }
  610. // set dst ext of current stripe
  611. xext = nSRAMPixels;
  612. }
  613. // if there's some area left to blt, then do it
  614. if (0 < cxDst)
  615. {
  616. // update auto blt struct settings
  617. bltr.OP0_opRDRAM.pt.X = (USHORT)xDst;
  618. bltr.OP1_opRDRAM.pt.X = (USHORT)srcx;
  619. bltr.ACCUM_X = accx;
  620. bltr.BLTEXT.pt.X = (USHORT)cxDst;
  621. // blt final stripe
  622. CALL_DRV_STR_BLTX(&bltr);
  623. }
  624. }
  625. }
  626. /***************************************************************************
  627. *
  628. * FUNCTION: RGB16ShrinkBOF64
  629. *
  630. * DESCRIPTION: Handles 16bpp RGB shrinks on the 5464
  631. *
  632. ****************************************************************************/
  633. #define ENABLE_INTERPOLATED_BLTS 1
  634. void RGB_16SHRINKBOF64
  635. #ifndef WINNT_VER40
  636. LPGLOBALDATA lpDDHALData,
  637. #endif
  638. int xDst, int yDst, int cxDst, int cyDst,
  639. int xSrc, int ySrc, int cxSrc, int cySrc )
  640. {
  641. const int nBytesPixel = BYTESPERPIXEL;
  642. const int nSRAMPixels = (SRAM_SIZE / nBytesPixel) / 2;
  643. const int nSRAMMask = nSRAMPixels - 1;
  644. autoblt_regs SrcToScratch;
  645. autoblt_regs ScratchToDst;
  646. int xScratch, yScratch;
  647. int cxScratch, cyScratch;
  648. AXIS axis[2];
  649. int nDst[2];
  650. int nSrc[2];
  651. int i;
  652. DDAX accx;
  653. int srcx;
  654. int xext;
  655. int nSRAMext;
  656. int cxTemp;
  657. int xTemp;
  658. DD_LOG(("RGB16ResizeBOF64 - 16 bpp shrink in X\r\n"));
  659. DD_LOG(("dst=%08lX dstext=%08lX src=%08lX srcext=%08lX\r\n",
  660. MAKELONG(xDst,yDst),MAKELONG(cxDst,cyDst),
  661. MAKELONG(xSrc,ySrc),MAKELONG(cxSrc,cySrc)));
  662. #ifndef WINNT_VER40
  663. // Verify this is a 16bpp shrink!
  664. ASSERT(cxSrc > cxDst);
  665. ASSERT(nBytesPixel == 2);
  666. DBG_WARNING((" RGB16ShrinkBOF64 - Dst %08lXh,%08lXh %08lX,%08lX",xDst,yDst,cxDst,cyDst));
  667. DBG_WARNING((" Src %08lXh,%08lXh %08lX,%08lX",xSrc,ySrc,cxSrc,cySrc));
  668. #endif
  669. xScratch = LOWORD(lpDDHALData->ScratchBufferOrg);
  670. yScratch = HIWORD(lpDDHALData->ScratchBufferOrg);
  671. cyScratch = cyDst;
  672. // initialize auto blt struct for src to scratch buffer
  673. SrcToScratch.DRAWBLTDEF.DW = MAKELONG(ROP_OP1_copy, (BD_RES+BD_OP1)*IS_VRAM);
  674. SrcToScratch.OP0_opRDRAM.DW = MAKELONG(LOWORD(xScratch),LOWORD(yScratch));
  675. SrcToScratch.OP1_opRDRAM.DW = MAKELONG(LOWORD(xSrc),LOWORD(ySrc));
  676. SrcToScratch.LNCNTL.W = lncntl[nBytesPixel-1] << LN_YUV_SHIFT;
  677. SrcToScratch.SRCX = cxSrc * nBytesPixel;
  678. #if ENABLE_INTERPOLATED_BLTS
  679. // Enable interpolation unless we have a palette (8bpp)
  680. if (1 < nBytesPixel)
  681. SrcToScratch.LNCNTL.W |= (LN_XINTP_EN | LN_YINTP_EN);
  682. #endif
  683. SrcToScratch.SHRINKINC.W = 0x0000;
  684. // THIS IS A SHRINK IN X!
  685. cxScratch = cxSrc & ~1;
  686. nSRAMext = 0x38;
  687. while (cxScratch > cxDst)
  688. {
  689. cxScratch >>= 1;
  690. nSRAMext >>= 1;
  691. }
  692. /* Check for zero extent blt */
  693. if (nSRAMext == 0)
  694. return;
  695. SrcToScratch.BLTEXT.DW = MAKELONG(LOWORD(cxScratch),1);
  696. // Yes, the following line doesn't make any sense but using
  697. // half the dest x ext on a 16bpp rgb shrink to compute the
  698. // minor, major and initial accumulator terms appears to get
  699. // the hw to work correctly
  700. cxScratch /= 2;
  701. SrcToScratch.LNCNTL.W |= LN_XSHRINK;
  702. #if ENABLE_INTERPOLATED_BLTS
  703. SrcToScratch.LNCNTL.W &= ~LN_XINTP_EN;
  704. #endif
  705. SrcToScratch.SHRINKINC.pt.X = (cxSrc / cxScratch);
  706. if ( cyDst < cySrc )
  707. {
  708. SrcToScratch.LNCNTL.W |= LN_YSHRINK;
  709. #if ENABLE_INTERPOLATED_BLTS
  710. SrcToScratch.LNCNTL.W &= ~LN_YINTP_EN;
  711. #endif
  712. SrcToScratch.SHRINKINC.pt.Y = (cySrc / cyScratch);
  713. }
  714. // Compute DDA terms
  715. nDst[0] = cxScratch;
  716. nDst[1] = cyScratch;
  717. nSrc[0] = cxSrc;
  718. nSrc[1] = cySrc;
  719. for (i = 0; i < 2; i++)
  720. {
  721. int kDst = 1;
  722. #if ENABLE_INTERPOLATED_BLTS
  723. if (SrcToScratch.LNCNTL.W & ((i==0) ? LN_XINTP_EN : LN_YINTP_EN))
  724. {
  725. nDst[i] *= 4;
  726. nSrc[i] *= 4;
  727. nSrc[i] -= 3;
  728. kDst = 0x8000 / nDst[i];
  729. }
  730. #endif
  731. if (SrcToScratch.LNCNTL.W & ((i==0) ? LN_XSHRINK : LN_YSHRINK))
  732. { /* Shrink Terms */
  733. axis[i].maj = (short)nDst[i];
  734. axis[i].min = - (nSrc[i] % nDst[i]);
  735. axis[i].accum = axis[i].maj - 1
  736. - ((nSrc[i] % nDst[i]) / (nSrc[i]/nDst[i] + 1));
  737. }
  738. else
  739. { /* Stretch Terms */
  740. axis[i].maj = kDst * nDst[i];
  741. axis[i].min = -kDst * nSrc[i];
  742. axis[i].accum = axis[i].maj - 1
  743. - ((axis[i].maj % -axis[i].min) / (nDst[i]/nSrc[i] + 1));
  744. }
  745. }
  746. SrcToScratch.MAJ_X = axis[0].maj;
  747. SrcToScratch.MIN_X = axis[0].min;
  748. SrcToScratch.ACCUM_X = axis[0].accum;
  749. SrcToScratch.MAJ_Y = axis[1].maj;
  750. SrcToScratch.MIN_Y = axis[1].min;
  751. SrcToScratch.ACCUM_Y = axis[1].accum;
  752. // Now that we have the major, minor and initial accumulator terms
  753. // computed, adjust dest x ext back to full width so we do the full
  754. // width of the blt below
  755. cxScratch *= 2;
  756. // initialize auto blt struct for scratch buffer to dst
  757. ScratchToDst.DRAWBLTDEF.DW = MAKELONG(ROP_OP1_copy, (BD_RES+BD_OP1)*IS_VRAM);
  758. ScratchToDst.OP0_opRDRAM.DW = MAKELONG(LOWORD(xDst),LOWORD(yDst));
  759. ScratchToDst.OP1_opRDRAM.DW = MAKELONG(LOWORD(xScratch),LOWORD(yScratch));
  760. ScratchToDst.BLTEXT.DW = MAKELONG(LOWORD(cxDst),1);
  761. ScratchToDst.LNCNTL.W = lncntl[nBytesPixel-1] << LN_YUV_SHIFT;
  762. ScratchToDst.SRCX = cxScratch * nBytesPixel;
  763. #if ENABLE_INTERPOLATED_BLTS
  764. // Enable interpolation unless we have a palette (8bpp)
  765. if (1 < nBytesPixel)
  766. ScratchToDst.LNCNTL.W |= (LN_XINTP_EN | LN_YINTP_EN);
  767. #endif
  768. ScratchToDst.SHRINKINC.W = 0x0000;
  769. // THIS IS A STRETCH IN X!
  770. // THIS IS 1:1 IN Y
  771. // Compute DDA terms
  772. nDst[0] = cxDst;
  773. nDst[1] = cyDst;
  774. nSrc[0] = cxScratch;
  775. nSrc[1] = cyScratch;
  776. for (i = 0; i < 2; i++)
  777. {
  778. int kDst = 1;
  779. #if ENABLE_INTERPOLATED_BLTS
  780. if (ScratchToDst.LNCNTL.W & ((i==0) ? LN_XINTP_EN : LN_YINTP_EN))
  781. {
  782. nDst[i] *= 4;
  783. nSrc[i] *= 4;
  784. nSrc[i] -= 3;
  785. kDst = 0x8000 / nDst[i];
  786. }
  787. #endif
  788. if (ScratchToDst.LNCNTL.W & ((i==0) ? LN_XSHRINK : LN_YSHRINK))
  789. { /* Shrink Terms */
  790. axis[i].maj = (short)nDst[i];
  791. axis[i].min = - (nSrc[i] % nDst[i]);
  792. axis[i].accum = axis[i].maj - 1
  793. - ((nSrc[i] % nDst[i]) / (nSrc[i]/nDst[i] + 1));
  794. }
  795. else
  796. { /* Stretch Terms */
  797. axis[i].maj = kDst * nDst[i];
  798. axis[i].min = -kDst * nSrc[i];
  799. axis[i].accum = axis[i].maj - 1
  800. - ((axis[i].maj % -axis[i].min) / (nDst[i]/nSrc[i] + 1));
  801. }
  802. }
  803. ScratchToDst.MAJ_X = axis[0].maj;
  804. ScratchToDst.MIN_X = axis[0].min;
  805. ScratchToDst.ACCUM_X = axis[0].accum;
  806. ScratchToDst.MAJ_Y = axis[1].maj;
  807. ScratchToDst.MIN_Y = axis[1].min;
  808. ScratchToDst.ACCUM_Y = axis[1].accum;
  809. // loop over scanlines in dst
  810. // do two blts for each, one from src to scratch buffer
  811. // then one from scratch buffer to dst
  812. while (0 < cyDst)
  813. {
  814. // blt one scanline high from src to scratch buffer
  815. // set values for initial stripe
  816. xext = nSRAMext;
  817. accx = SrcToScratch.ACCUM_X;
  818. srcx = xSrc;
  819. // write settings that don't vary over stripes to the chip
  820. CALL_DRV_STR_BLTY(&SrcToScratch);
  821. cxTemp = cxScratch;
  822. xTemp = xScratch;
  823. while (cxTemp > xext)
  824. {
  825. // update auto blt struct settings
  826. SrcToScratch.OP0_opRDRAM.pt.X = (USHORT)xTemp;
  827. SrcToScratch.OP1_opRDRAM.pt.X = (USHORT)srcx;
  828. SrcToScratch.BLTEXT.pt.X = (USHORT)xext;
  829. // blt current stripe
  830. CALL_DRV_STR_BLTX(&SrcToScratch);
  831. // increment xDst and decrement remaining dst extent
  832. xTemp += xext;
  833. cxTemp -= xext;
  834. // walk DDA to compute error term (accx) and xSrc for next stripe
  835. for (i = 0; i < xext; i++)
  836. {
  837. SrcToScratch.ACCUM_X += SrcToScratch.MIN_X;
  838. // Even though the following line should be correct
  839. // the hw doesn't work correctly so we'll skip it
  840. // here and adjust srcx after the for loop
  841. //srcx += SrcToScratch.SHRINKINC.pt.X;
  842. if (0 > (short)SrcToScratch.ACCUM_X)
  843. {
  844. SrcToScratch.ACCUM_X += SrcToScratch.MAJ_X;
  845. srcx++;
  846. }
  847. }
  848. // now adjust srcx with a bizarre equation that appears to get
  849. // the hw to work correctly
  850. srcx += ((nSRAMext / 2) * SrcToScratch.SHRINKINC.pt.X);
  851. }
  852. // if there's some area left to blt, then do it
  853. if (0 < cxTemp)
  854. {
  855. // update auto blt struct settings
  856. SrcToScratch.OP0_opRDRAM.pt.X = (USHORT)xTemp;
  857. SrcToScratch.OP1_opRDRAM.pt.X = (USHORT)srcx;
  858. SrcToScratch.BLTEXT.pt.X = (USHORT)cxTemp;
  859. // blt final stripe
  860. CALL_DRV_STR_BLTX(&SrcToScratch);
  861. }
  862. // reset ACCUM_X for beginning of next scanline
  863. SrcToScratch.ACCUM_X = accx;
  864. // walk Y DDA for src to scratch buffer blt
  865. SrcToScratch.ACCUM_Y += SrcToScratch.MIN_Y;
  866. SrcToScratch.OP1_opRDRAM.pt.Y += SrcToScratch.SHRINKINC.pt.Y;
  867. if (0 > (short)SrcToScratch.ACCUM_Y)
  868. {
  869. SrcToScratch.ACCUM_Y += SrcToScratch.MAJ_Y;
  870. SrcToScratch.OP1_opRDRAM.pt.Y++;
  871. }
  872. // blt from scratch buffer to dst
  873. // stretch in X, 1:1 in Y
  874. // set values for initial stripe
  875. xext = ((xDst + nSRAMPixels) & (~nSRAMMask)) - xDst;
  876. accx = ScratchToDst.ACCUM_X;
  877. srcx = xScratch;
  878. // write settings that don't vary over stripes to the chip
  879. CALL_DRV_STR_BLTY(&ScratchToDst);
  880. xTemp = xDst;
  881. cxTemp = cxDst;
  882. while (cxTemp > xext)
  883. {
  884. // update auto blt struct settings
  885. ScratchToDst.OP0_opRDRAM.pt.X = (USHORT)xTemp;
  886. ScratchToDst.OP1_opRDRAM.pt.X = (USHORT)srcx;
  887. ScratchToDst.BLTEXT.pt.X = (USHORT)xext;
  888. // blt current stripe
  889. CALL_DRV_STR_BLTX(&ScratchToDst);
  890. // increment xDst and decrement remaining dst extent
  891. xTemp += xext;
  892. cxTemp -= xext;
  893. // walk DDA to compute error term (accx) and xSrc for next stripe
  894. for (i = 0; i < xext; i++)
  895. {
  896. ScratchToDst.ACCUM_X += ScratchToDst.MIN_X;
  897. if (0 > (short)ScratchToDst.ACCUM_X)
  898. {
  899. ScratchToDst.ACCUM_X += ScratchToDst.MAJ_X;
  900. srcx++;
  901. }
  902. }
  903. // set dst ext of current stripe
  904. xext = nSRAMPixels;
  905. }
  906. // if there's some area left to blt, then do it
  907. if (0 < cxTemp)
  908. {
  909. // update auto blt struct settings
  910. ScratchToDst.OP0_opRDRAM.pt.X = (USHORT)xTemp;
  911. ScratchToDst.OP1_opRDRAM.pt.X = (USHORT)srcx;
  912. ScratchToDst.BLTEXT.pt.X = (USHORT)cxTemp;
  913. // blt final stripe
  914. CALL_DRV_STR_BLTX(&ScratchToDst);
  915. }
  916. // reset ACCUM_X for beginning of next scanline
  917. ScratchToDst.ACCUM_X = accx;
  918. // adjust dst ptr and dst extent
  919. ScratchToDst.OP0_opRDRAM.pt.Y++;
  920. cyDst--;
  921. }
  922. }
  923. /****************************************************************************
  924. * FUNCTION NAME: DdGetBltStatus (NT)
  925. * GetBltStatus32 (Win95)
  926. *
  927. * DESCRIPTION: Doesn't currently really care what surface is specified,
  928. * just checks and goes.
  929. ****************************************************************************/
  930. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  931. #ifdef WINNT_VER40 // WINNT_VER40
  932. DWORD DdGetBltStatus(PDD_GETBLTSTATUSDATA lpGetBltStatus)
  933. {
  934. DRIVERDATA* lpDDHALData;
  935. PDEV* ppdev;
  936. HRESULT ddRVal;
  937. DISPDBG((DBGLVL, "DDraw - DdGetBltStatus\n"));
  938. ppdev = (PDEV*) lpGetBltStatus->lpDD->dhpdev;
  939. lpDDHALData = (DRIVERDATA*) &ppdev->DriverData;
  940. #else // ----- #elseif WINNT_VER40 -----
  941. DWORD __stdcall GetBltStatus32( LPDDHAL_GETBLTSTATUSDATA lpGetBltStatus)
  942. {
  943. LPGLOBALDATA lpDDHALData = GetDDHALContext( lpGetBltStatus->lpDD);
  944. HRESULT ddRVal;
  945. #endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
  946. DD_LOG(("GetBltStatus32 Entry\r\n"));
  947. #ifndef WINNT_VER40
  948. SyncWithQueueManager(lpDDHALData);
  949. #endif
  950. #ifdef WINNT_VER40
  951. SYNC_W_3D(ppdev); // if 3D context(s) active, make sure 3D engine idle before continuing...
  952. #endif
  953. // DDGBS_CANBLT: can we add a blt?
  954. ddRVal = DD_OK;
  955. if (lpGetBltStatus->dwFlags == DDGBS_CANBLT)
  956. {
  957. // is a flip in progress?
  958. #ifdef WINNT_VER40
  959. ddRVal = vUpdateFlipStatus(
  960. &ppdev->flipRecord,
  961. lpGetBltStatus->lpDDSurface->lpGbl->fpVidMem);
  962. #else
  963. #if defined(DDRAW_COMPAT_10)
  964. ddRVal = pfnUpdateFlipStatus(
  965. lpGetBltStatus->lpDDSurface->lpData->fpVidMem,
  966. lpDDHALData);
  967. #else
  968. ddRVal = pfnUpdateFlipStatus(
  969. lpGetBltStatus->lpDDSurface->lpGbl->fpVidMem,
  970. lpDDHALData);
  971. #endif
  972. #endif
  973. if (ddRVal == DD_OK)
  974. {
  975. // so there was no flip going on, is there room in the fifo
  976. // to add a blt?
  977. if (!CALL_ENOUGH_FIFO_FOR_BLT)
  978. ddRVal = DDERR_WASSTILLDRAWING;
  979. else
  980. ddRVal = DD_OK;
  981. };
  982. }
  983. else
  984. {
  985. // DDGBS_ISBLTDONE case: is a blt in progress?
  986. if (DRAW_ENGINE_BUSY)
  987. ddRVal = DDERR_WASSTILLDRAWING;
  988. else
  989. ddRVal = DD_OK;
  990. };
  991. lpGetBltStatus->ddRVal = ddRVal;
  992. DD_LOG(("GetBltStatus32 Exit\r\n"));
  993. return(DDHAL_DRIVER_HANDLED);
  994. } // DDGetBltStatus or GetBltStatus32
  995. /***************************************************************************
  996. *
  997. * FUNCTION: DrvStretch64
  998. *
  999. * DESCRIPTION:
  1000. *
  1001. ****************************************************************************/
  1002. void DRVSTRETCH64
  1003. #ifndef WINNT_VER40
  1004. LPGLOBALDATA lpDDHALData,
  1005. #endif
  1006. int xDst, int yDst, int cxDst, int cyDst,
  1007. int xSrc, int ySrc, int cxSrc, int cySrc,
  1008. int nBytesPixel, int SrcType, int BaseOffset,
  1009. int OnScreen)
  1010. {
  1011. int cxClip = cxDst;
  1012. int cyClip = cyDst;
  1013. int cxFill = 0;
  1014. int cyFill = cyDst;
  1015. int xFill = xDst;
  1016. int yFill = yDst;
  1017. int cxTrim = 0;
  1018. int iratio, i;
  1019. #ifdef RDRAM_8BIT
  1020. PVGAR pREG = (PVGAR) lpDDHALData->RegsAddress;
  1021. #endif
  1022. autoblt_regs bltr;
  1023. AXIS axis[2];
  1024. int nDst[2];
  1025. int nSrc[2];
  1026. #ifdef RDRAM_8BIT
  1027. RECTL SrcRectl;
  1028. int nFound = FALSE;
  1029. #endif
  1030. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1031. #ifdef WINNT_VER40 // WINNT_VER40
  1032. DISPDBG((DBGLVL3, "DDraw - DrvStretch64 xD=%x, yD=%x, cxD=%x, cyD=%x, xS=%x, yS=%x, cxS=%x, cyS=%x, bpp=%x, t=%x, bo=%x, scn=%x\n",
  1033. xDst, yDst, cxDst, cyDst,
  1034. xSrc, ySrc, cxSrc, cySrc,
  1035. nBytesPixel, SrcType, BaseOffset, OnScreen));
  1036. #endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
  1037. DD_LOG(("DrvStretch64 - dst=%08lX dstext=%08lX src=%08lX srcext=%08lX\r\n",
  1038. MAKELONG(xDst,yDst),MAKELONG(cxDst,cyDst),
  1039. MAKELONG(xSrc,ySrc),MAKELONG(cxSrc,cySrc)));
  1040. #ifdef RDRAM_8BIT
  1041. if (!lpDDHALData->fNineBitRDRAMS)
  1042. {
  1043. if (SrcType == LN_YUV422)
  1044. {
  1045. SrcRectl.left = xSrc;
  1046. SrcRectl.top = ySrc;
  1047. SrcRectl.right = xSrc+cxSrc;
  1048. SrcRectl.bottom = ySrc+cySrc;
  1049. if (MEMCMP(&SrcRectl, sizeof(SrcRectl)) == 0)
  1050. nFound = TRUE;
  1051. if (nFound)
  1052. {
  1053. #if 0
  1054. DBG_MESSAGE(("Stretch: Found Offscreen Area P1(%x,%x) P2(%x,%x) Dst(%x, %x) Dst(%x %x)\n",
  1055. SrcRectl.left,
  1056. SrcRectl.top,
  1057. SrcRectl.right,
  1058. SrcRectl.bottom,
  1059. xDst,
  1060. yDst,
  1061. xDst+cxDst,
  1062. yDst+cyDst));
  1063. #endif
  1064. LL16(grX_Start_2, xDst + ((4 - (xDst & 3)) & 3));
  1065. LL16(grY_Start_2, yDst);
  1066. LL16(grX_End_2, xDst+(cxDst>>3<<3));
  1067. LL16(grY_End_2, yDst+cyDst);
  1068. }
  1069. else
  1070. {
  1071. #if 0
  1072. DBG_MESSAGE(("Stretch: Not Found Offscreen Area P1(%x,%x) P2(%x,%x)\n",
  1073. SrcRectl.left,
  1074. SrcRectl.top,
  1075. SrcRectl.right,
  1076. SrcRectl.bottom));
  1077. #endif
  1078. LL16(grX_Start_2, 0);
  1079. LL16(grY_Start_2, 0);
  1080. LL16(grX_End_2, 0);
  1081. LL16(grY_End_2, 0);
  1082. // Black Blit Here
  1083. CALL_DRV_DST_BLT(0x107000CC,MAKELONG(xDst,yDst),0,MAKELONG(cxDst,cyDst));
  1084. return ;
  1085. }
  1086. } // endif (SrcType == LN_YUV422)
  1087. } // endif (!lpDDHALData->fNineBitRDRAMS)
  1088. #endif
  1089. #ifdef TRACE_STRETCH
  1090. DBG_MESSAGE(("DrvStretch64: %4d,%4d %4dx%4d -> %4d,%4d %4dx%4d (%d %d) %d",
  1091. xSrc, ySrc, cxSrc, cySrc,
  1092. xDst, yDst, cxDst, cyDst,
  1093. nBytesPixel, SrcType, BaseOffset));
  1094. #endif
  1095. if ((SrcType == LN_YUV422) ||
  1096. ((SrcType == LN_RGB565) && (nBytesPixel == 1)))
  1097. { // Force alignment of output to QWORD ( it is documented as DWORD but broken)
  1098. if (nBytesPixel == 2)
  1099. { // 16 bit frame buffer ( Note all ptrs/extents in terms of 16 bpp )
  1100. // The X portions will be mutiplied by 2 by chip on being written )
  1101. if (cxDst > cxSrc)
  1102. iratio = cxDst / cxSrc; // integer ratio of stretch
  1103. else
  1104. iratio = cxSrc / cxDst; // integer ratio of shrink
  1105. if (xDst & 3) // This should be for LN_YUV422 only
  1106. {
  1107. cxFill = 4 - (xDst & 3);
  1108. cxTrim = cxFill; // save trim count for source clipping if required
  1109. if ( cxFill > cxClip )
  1110. cxFill = cxClip; // check for no stretch left
  1111. cxClip -= cxFill; // reduce size
  1112. cxDst -= cxFill; // reduce size
  1113. xDst += cxFill; // force alignment to next even DWORD boundary
  1114. CALL_EDGE_FILL_BLT(xFill, yFill, cxFill, cyFill,
  1115. MAKELONG(BOGUS_YUV, BOGUS_YUV),
  1116. FALSE);
  1117. } // endif (xDst & 3)
  1118. cxFill = cxClip & 3;
  1119. if (OnScreen && cxFill )
  1120. {
  1121. cxClip -= cxFill; // force size to next smaller even DWORD count
  1122. xFill = xDst + cxClip;
  1123. if ( cxClip >= cxSrc)
  1124. { // If shrink defer edge fill to later as there may be more
  1125. CALL_EDGE_FILL_BLT(xFill, yFill, cxFill, cyFill,
  1126. MAKELONG(BOGUS_YUV, BOGUS_YUV), FALSE);
  1127. }
  1128. } // endif ( cxFill )
  1129. if ( (cxClip < cxSrc) )
  1130. { // Edge Clip on shrinks only ( add config flag check here )
  1131. // extra pixels to discard above integer ratio
  1132. int excess = (cxSrc / iratio) - cxClip;
  1133. #ifdef TRACE_STRETCH
  1134. DBG_MESSAGE((" Edge Clip iratio = %d excess = %d Trim %% = %d", iratio, excess, lpDDHALData->EdgeTrim));
  1135. #endif
  1136. if ( excess && cxTrim )
  1137. { // These excess pixels are caused by our Dest alignment
  1138. // problems on the Left edge
  1139. if ( excess < (cxTrim * iratio) )
  1140. {
  1141. cxSrc -= excess;
  1142. xSrc += excess;
  1143. excess = 0;
  1144. }
  1145. else
  1146. {
  1147. cxSrc -= cxTrim * iratio;
  1148. xSrc += cxTrim * iratio;
  1149. excess -= cxTrim * iratio;
  1150. }
  1151. } // endif ( (cxClip < cxSrc) )
  1152. if ( excess && cxFill)
  1153. { // These excess pixels are caused by our Dest alignment
  1154. // problems on the Right edge
  1155. if ( excess < (cxFill * iratio) )
  1156. {
  1157. cxSrc -= excess;
  1158. excess = 0;
  1159. }
  1160. else
  1161. {
  1162. cxSrc -= cxFill * iratio;
  1163. excess -= cxFill * iratio;
  1164. }
  1165. } // endif ( excess && cxFill)
  1166. if ( excess && (excess <= (lpDDHALData->EdgeTrim * cxSrc)/100 ))
  1167. { // if excess is less than % of frame trim edges
  1168. int trim = excess / 2; // half the excess of pixels
  1169. xSrc += trim; // offset pixel pointer
  1170. cxSrc -= excess; // all the excess in pixels
  1171. #ifdef TRACE_STRETCH
  1172. DBG_MESSAGE((" Edge Clip Left = %d, xSrc = %d, cxSrc = %d", trim, xSrc, cxSrc));
  1173. #endif
  1174. }
  1175. if ( iratio == 1 )
  1176. { // we may have just changed a shrink to a 1 : 1
  1177. // if excess is zero do edge fill now
  1178. // extra pixels to discard above integer ratio
  1179. excess = ( cxSrc / iratio ) - cxClip;
  1180. if ( !excess && cxFill )
  1181. {
  1182. xFill = xDst + cxClip;
  1183. CALL_EDGE_FILL_BLT(xFill, yFill, cxFill, cyFill,
  1184. MAKELONG(BOGUS_YUV, BOGUS_YUV), FALSE);
  1185. }
  1186. } // endif ( iratio == 1 )
  1187. }
  1188. else
  1189. { // Stretch adjustments
  1190. if ( xSrc - BaseOffset )
  1191. { // if we are not starting from left edge of source image
  1192. if ( cxTrim )
  1193. { // And we were forced to offset for left edge alignment
  1194. #ifdef TRACE_STRETCH
  1195. DBG_MESSAGE((" Edge Trim for stretch iratio = %d , cxTrim = %d xSrc %d", iratio, cxTrim, xSrc));
  1196. #endif
  1197. cxSrc -= cxTrim / iratio;
  1198. xSrc += cxTrim / iratio;
  1199. }
  1200. }
  1201. } // endif ( (cxClip < cxSrc) )
  1202. // Global adjustments
  1203. if ( xSrc & 1 ) // HW bug workaound for clipping
  1204. {
  1205. xSrc += 1; // Align to SRC DWORD Boundary
  1206. cxSrc -= 1; // Account for smaller size
  1207. }
  1208. }
  1209. else
  1210. { // 8 Bit frame buffer.
  1211. // Force alignment of output to QWORD ( it is documented as DWORD but broken)
  1212. if ( cxDst >= (cxSrc*2) )
  1213. iratio = cxDst / (2 * cxSrc); // integer ratio of stretch
  1214. else
  1215. iratio = (2 * cxSrc ) / cxDst; // integer ratio of shrink
  1216. if ( xDst & 7 ) /* This should be for LN_YUV422 only */
  1217. {
  1218. cxFill = 8 - (xDst & 7);
  1219. if ( cxFill > cxClip )
  1220. cxFill = cxClip; // check for no stretch left
  1221. cxClip -= cxFill; // reduce size
  1222. cxDst -= cxFill; // reduce size
  1223. xDst += cxFill; // force alignment to next even WORD boundary
  1224. CALL_EDGE_FILL_BLT(xFill, yFill, cxFill, cyFill,
  1225. 0x00000000, FALSE);
  1226. } // endif ( xDst & 7 )
  1227. cxFill = cxClip & 7;
  1228. if (OnScreen && cxFill )
  1229. {
  1230. cxClip -= cxFill; /* force size to next smaller even DWORD count */
  1231. if ( cxClip >= (cxSrc * 2))
  1232. { // If shrink defer edge fill to later as there may be more
  1233. xFill = xDst + cxClip;
  1234. CALL_EDGE_FILL_BLT(xFill, yFill, cxFill, cyFill,
  1235. 0x00000000, FALSE);
  1236. }
  1237. } // endif ( cxFill )
  1238. // change pixel pointer to byte pointer
  1239. // taking account of X origin of buffer
  1240. xSrc = BaseOffset + (xSrc - BaseOffset) * 2;
  1241. cxSrc *= 2; // change pixel count to byte count
  1242. #ifdef EDGE_CLIP
  1243. if ( (cxClip < cxSrc) && lpDDHALData->EdgeTrim)
  1244. { // Edge Clip on shrinks only ( add config flag check here )
  1245. int excess;
  1246. excess = ( cxSrc / iratio ) - cxClip; // extra pixels to discard
  1247. // above integer ratio
  1248. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1249. #ifdef WINNT_VER40 // WINNT_VER40
  1250. DISPDBG((DBGLVL1,
  1251. "DDraw - Edge Clip iratio = %d excess = %d Trim %% = %d",
  1252. iratio, excess, lpDDHALData->EdgeTrim));
  1253. #else // ----- #elseif WINNT_VER40 -----
  1254. DBG_MESSAGE((" Edge Clip iratio = %d excess = %d Trim %% = %d",
  1255. iratio, excess, lpDDHALData->EdgeTrim));
  1256. #endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
  1257. if ( excess && cxTrim )
  1258. { // These excess pixels are caused by our Dest alignment
  1259. // problems on the Left edge
  1260. if ( excess < (cxTrim * iratio) )
  1261. {
  1262. cxSrc -= excess;
  1263. xSrc += excess;
  1264. excess = 0;
  1265. }
  1266. else
  1267. {
  1268. cxSrc -= cxTrim * iratio;
  1269. xSrc += cxTrim * iratio;
  1270. excess -= cxTrim * iratio;
  1271. }
  1272. } // endif ( excess && cxTrim )
  1273. if ( excess && cxFill)
  1274. { // These excess pixels are caused by our Dest alignment
  1275. // problems on the Right edge
  1276. if ( excess < (cxFill * iratio) )
  1277. {
  1278. cxSrc -= excess;
  1279. excess = 0;
  1280. }
  1281. else
  1282. {
  1283. cxSrc -= cxFill * iratio;
  1284. excess -= cxFill * iratio;
  1285. }
  1286. } // endif ( excess && cxFill)
  1287. if ( excess && ( excess <= (lpDDHALData->EdgeTrim * cxSrc)/100 ) )
  1288. { // if excess is less than specific % of frame trim edges
  1289. int trim = excess / 2; // half the excess as pixels
  1290. xSrc += trim; // offset pixel pointer
  1291. cxSrc -= excess; // all the excess in bytes
  1292. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1293. #ifdef WINNT_VER40 // WINNT_VER40
  1294. DISPDBG((DBGLVL1,
  1295. "DDraw - Edge Clip Left = %d, xSrc = %d, cxSrc = %d",
  1296. trim, xSrc, cxSrc));
  1297. #else // ----- #elseif WINNT_VER40 -----
  1298. DBG_MESSAGE((" Edge Clip Left = %d, xSrc = %d, cxSrc = %d",
  1299. trim, xSrc, cxSrc));
  1300. #endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
  1301. } // endif (excess && ( excess <= (lpDDHALData->EdgeTrim * cxSrc)/100))
  1302. if ( iratio == 1 )
  1303. { // we may have just changed a shrink to a 1 : 1
  1304. // if excess is no zero do edge fill now
  1305. // extra pixels to discard above integer ratio
  1306. excess = ( cxSrc / iratio ) - cxClip;
  1307. if ( !excess && cxFill )
  1308. {
  1309. xFill = xDst + cxClip;
  1310. CALL_EDGE_FILL_BLT(xFill, yFill, cxFill, cyFill,
  1311. 0x00000000, FALSE);
  1312. }
  1313. } // endif ( iratio == 1 )
  1314. } // endif ( (cxClip < cxSrc) && lpDDHALData->EdgeTrim)
  1315. #endif
  1316. if ( xSrc & 3 ) /* HW bug workaound for clipping */
  1317. {
  1318. cxSrc -= 4 - (xSrc & 3); /* reduce size */
  1319. xSrc = (xSrc + 3) & ~ 3; /* Align to SRC DWORD Boundary */
  1320. }
  1321. } // endif (nBytesPixel == 2)
  1322. }
  1323. if ( cxClip == 0 )
  1324. return; // discard zero extent stretchs
  1325. if (nBytesPixel == 1 && ((SrcType == LN_YUV422) || (SrcType == LN_RGB565))
  1326. || ((nBytesPixel == 2) && (SrcType == LN_YUV422)))
  1327. {
  1328. CALL_DELAY_9BIT_BLT(FALSE);
  1329. bltr.DRAWBLTDEF.DW = MAKELONG(0x04CC, BD_RES | BD_OP1);
  1330. lpDDHALData->YUVLeft = (USHORT)xDst; // Save 9th bit rect coords for main
  1331. lpDDHALData->YUVTop = (USHORT)yDst; // driver for exclusion purposes.
  1332. lpDDHALData->YUVXExt = (USHORT)cxClip;
  1333. lpDDHALData->YUVYExt = (USHORT)cyClip;
  1334. // tell main driver the rectangle is valid
  1335. lpDDHALData->DrvSemaphore |= DRVSEM_YUV_RECT_VALID;
  1336. }
  1337. else
  1338. bltr.DRAWBLTDEF.DW = MAKELONG(0x00CC, BD_RES | BD_OP1);
  1339. bltr.OP0_opRDRAM.DW = MAKELONG(xDst, yDst);
  1340. bltr.OP1_opRDRAM.DW = MAKELONG(xSrc, ySrc);
  1341. bltr.BLTEXT.DW = MAKELONG(cxClip, cyClip);
  1342. bltr.LNCNTL.W = SrcType << LN_YUV_SHIFT;
  1343. // Enable interpolation unless we have a palette (8bpp).
  1344. if (SrcType != LN_8BIT )
  1345. bltr.LNCNTL.W |= LN_XINTP_EN | LN_YINTP_EN;
  1346. bltr.SHRINKINC.w = 0x0000;
  1347. if ( cxClip < cxSrc )
  1348. {
  1349. bltr.LNCNTL.W |= LN_XSHRINK;
  1350. bltr.LNCNTL.W &= ~LN_XINTP_EN; // Clear Average bit for ALL shrinks
  1351. bltr.SHRINKINC.pt.X = (cxSrc / cxClip);
  1352. }
  1353. if ( cyDst < cySrc )
  1354. {
  1355. bltr.LNCNTL.W |= LN_YSHRINK;
  1356. bltr.LNCNTL.W &= ~LN_YINTP_EN;
  1357. bltr.SHRINKINC.pt.Y = (cySrc / cyDst);
  1358. }
  1359. if ( SrcType == LN_YUV422 || SrcType == LN_RGB565 )
  1360. {
  1361. if ( nBytesPixel == 1 )
  1362. bltr.SRCX = (USHORT)cxSrc; // If mixed mode is *2 already
  1363. else
  1364. bltr.SRCX = cxSrc * 2;
  1365. }
  1366. else
  1367. bltr.SRCX = cxSrc * nBytesPixel;
  1368. #ifdef TRACE_STRETCH
  1369. DBG_MESSAGE((" cSrc = %d , %d : cDst = %d , %d : cClip = %d , %d",
  1370. cxSrc, cySrc, cxDst, cyDst, cxClip, cyClip));
  1371. #endif
  1372. // Compute DDA terms.
  1373. nDst[0] = cxClip; nDst[1] = cyDst;
  1374. nSrc[0] = cxSrc; nSrc[1] = cySrc;
  1375. for (i = 0; i < 2; i++)
  1376. {
  1377. int kDst = 1;
  1378. if (bltr.LNCNTL.W & ((i==0) ? LN_XINTP_EN : LN_YINTP_EN))
  1379. {
  1380. nDst[i] *= 4;
  1381. nSrc[i] *= 4;
  1382. nSrc[i] -= 3;
  1383. kDst = 0x8000 / nDst[i];
  1384. }
  1385. if (bltr.LNCNTL.W & ((i==0) ? LN_XSHRINK : LN_YSHRINK))
  1386. { /* Shrink Terms */
  1387. axis[i].maj = (short)nDst[i];
  1388. axis[i].min = - (nSrc[i] % nDst[i]);
  1389. axis[i].accum = axis[i].maj - 1
  1390. - ((nSrc[i] % nDst[i]) / (nSrc[i]/nDst[i] + 1));
  1391. }
  1392. else
  1393. { /* Stretch Terms */
  1394. axis[i].maj = kDst * nDst[i];
  1395. axis[i].min = -kDst * nSrc[i];
  1396. axis[i].accum = axis[i].maj - 1
  1397. - ((axis[i].maj % -axis[i].min) / (nDst[i]/nSrc[i] + 1));
  1398. }
  1399. } // endfor
  1400. bltr.MAJ_X = axis[0].maj;
  1401. bltr.MIN_X = axis[0].min;
  1402. bltr.ACCUM_X = axis[0].accum;
  1403. bltr.MAJ_Y = axis[1].maj;
  1404. bltr.MIN_Y = axis[1].min;
  1405. bltr.ACCUM_Y = axis[1].accum;
  1406. if ( ((SrcType == LN_8BIT) || (SrcType == LN_YUV422))
  1407. && !(bltr.LNCNTL.W & LN_XSHRINK) )
  1408. {
  1409. // Put DDA parameter check/adjust (Optional for 5462/required for 5464)
  1410. const short maj_x = bltr.MAJ_X;
  1411. const short min_x = bltr.MIN_X;
  1412. short xaccum = bltr.ACCUM_X;
  1413. short copy_xDst = bltr.BLTEXT.pt.X;
  1414. short src_ext;
  1415. short inc_dx = 1;
  1416. short inc_sx = 0;
  1417. short SrcDstSz;
  1418. SrcDstSz = ( SrcType == LN_8BIT ) ? 1 : 2 ;
  1419. if ( (bltr.LNCNTL.W & LN_XSHRINK) )
  1420. inc_sx = bltr.SHRINKINC.pt.X;
  1421. inc_sx *= SrcDstSz;
  1422. inc_dx *= SrcDstSz;
  1423. copy_xDst *= (short)nBytesPixel;
  1424. src_ext = SrcDstSz; // Source size starts with a pixel !!
  1425. do
  1426. { // Step through the X DDA accounting for src pixels consumed
  1427. copy_xDst -= inc_dx;
  1428. src_ext += inc_sx;
  1429. xaccum += min_x;
  1430. if ( xaccum < 0 )
  1431. {
  1432. xaccum += maj_x;
  1433. src_ext += SrcDstSz;
  1434. }
  1435. } while ( copy_xDst > 0 );
  1436. bltr.SRCX = src_ext;
  1437. // End DDA parameter check / adjust.
  1438. CALL_DRV_STR_BLT(&bltr); // Single stretch
  1439. if ( (SrcType == LN_YUV422) )
  1440. CALL_DELAY_9BIT_BLT(TRUE);
  1441. }
  1442. // else if (SrcType == LN_RGB565 && !(bltr.LNCNTL.W & LN_XSHRINK))
  1443. else if (SrcType == LN_RGB565)
  1444. {
  1445. // HWBUG !!! -- Break into sram-aligned vertical tiles
  1446. // based on destination alignment
  1447. // dword and tile masks
  1448. const int mdwrd = 4 ;
  1449. const int mtile_s = 128 - 1; // sram is 128 bytes
  1450. int mtile_d = 128 - 1 ; // 5464 Dest Workaround half tile size mask
  1451. int endx = xDst + cxClip; // last x, exclusive
  1452. int dstxe = endx & ~mtile_d; // start of last tile
  1453. int accx = axis[0].accum;
  1454. int dstx = xDst;
  1455. int srcx = xSrc;
  1456. int src_ext = 0;
  1457. int sav_accx;
  1458. int sav_dstx;
  1459. int sav_srcx;
  1460. int sav_src_ext;
  1461. int copy_srcx;
  1462. int xext;
  1463. int inc_sx;
  1464. #ifndef WINNT_VER40
  1465. ASSERT( BITSPERPIXEL != 24 ); // HWBUG !!!
  1466. #endif
  1467. if (bltr.LNCNTL.W & LN_XSHRINK)
  1468. {
  1469. mtile_d = 128 - 1;
  1470. dstxe = endx & ~mtile_d;
  1471. }
  1472. if ( nBytesPixel == 2 )
  1473. {
  1474. cxSrc *= 2; /* convert size to Bytes from pixels */
  1475. cxDst *= 2;
  1476. srcx = (xSrc *= 2);
  1477. dstx = (xDst *= 2);
  1478. bltr.OP0_opRDRAM.pt.X *= 2;
  1479. bltr.OP1_opRDRAM.pt.X *= 2;
  1480. endx *= 2;
  1481. dstxe = endx & ~mtile_d;
  1482. }
  1483. if (LGDEVID == CL_GD5464)
  1484. {
  1485. bltr.SHRINKINC.pt.X *= 2;
  1486. CALL_DRV_STR_MBLTY(&bltr); // Load the invariant registers
  1487. bltr.SHRINKINC.pt.X /= 2;
  1488. }
  1489. else
  1490. CALL_DRV_STR_MBLTY(&bltr); // Load the invariant registers
  1491. copy_srcx = bltr.SRCX;
  1492. while (dstx < dstxe)
  1493. {
  1494. bltr.OP0_opRDRAM.PT.X = (USHORT)dstx;
  1495. bltr.OP1_opRDRAM.PT.X = (USHORT)srcx;
  1496. bltr.ACCUM_X = (USHORT)accx;
  1497. xext = 0;
  1498. src_ext = 0;
  1499. inc_sx = bltr.SHRINKINC.pt.X * 2;
  1500. if ( bltr.LNCNTL.W & LN_XSHRINK )
  1501. { // We have to treat the stretch / shrink cases differently
  1502. // because of the need to handle both SRC & DST aligned cases.
  1503. do
  1504. {
  1505. dstx += 2;
  1506. xext += 2;
  1507. accx += axis[0].min;
  1508. srcx += inc_sx;
  1509. src_ext += inc_sx;
  1510. if ( !(srcx & mtile_s) )
  1511. break; // Try double striping !!
  1512. if (accx < 0)
  1513. {
  1514. accx += axis[0].maj;
  1515. srcx += 2;
  1516. src_ext += 2;
  1517. if ( !(srcx & mtile_s) )
  1518. break; // Try double striping !!
  1519. }
  1520. } while ((dstx + 4 ) & mtile_d);
  1521. sav_dstx = dstx;
  1522. sav_accx = accx;
  1523. sav_srcx = srcx;
  1524. sav_src_ext = src_ext;
  1525. do
  1526. {
  1527. dstx += 2;
  1528. xext += 2;
  1529. accx += axis[0].min;
  1530. srcx += inc_sx;
  1531. src_ext += inc_sx;
  1532. if ( !(srcx & mtile_s) )
  1533. break; // Try double striping !!
  1534. if (accx < 0)
  1535. {
  1536. accx += axis[0].maj;
  1537. srcx += 2;
  1538. src_ext += 2;
  1539. if ( !(srcx & mtile_s) )
  1540. break; // Try double striping !!
  1541. }
  1542. } while ((dstx) & mtile_d);
  1543. bltr.SRCX = (USHORT)src_ext;
  1544. }
  1545. else
  1546. {
  1547. do
  1548. {
  1549. dstx += 2;
  1550. xext += 2;
  1551. accx += axis[0].min;
  1552. if (accx < 0)
  1553. {
  1554. accx += axis[0].maj;
  1555. srcx += 2;
  1556. src_ext += 2;
  1557. if ( !(srcx & mtile_s) )
  1558. break; // Try double striping !!
  1559. }
  1560. } while (dstx & mtile_d);
  1561. bltr.SRCX = src_ext + 2;
  1562. sav_dstx = dstx;
  1563. sav_accx = accx;
  1564. sav_srcx = srcx;
  1565. sav_src_ext = src_ext;
  1566. }
  1567. bltr.BLTEXT.PT.X = (USHORT)xext;
  1568. CALL_DRV_STR_MBLTX(&bltr);
  1569. dstx = sav_dstx;
  1570. accx = sav_accx;
  1571. srcx = sav_srcx;
  1572. src_ext = sav_src_ext;
  1573. copy_srcx -= src_ext;
  1574. } // end while (dstx < dstxe)
  1575. // do the last tile
  1576. if (dstx < endx)
  1577. {
  1578. bltr.OP0_opRDRAM.PT.X = (USHORT)dstx;
  1579. bltr.OP1_opRDRAM.PT.X = (USHORT)srcx;
  1580. bltr.ACCUM_X = (USHORT)accx;
  1581. bltr.SRCX = (USHORT)copy_srcx;
  1582. bltr.BLTEXT.PT.X = endx - dstx;
  1583. CALL_DRV_STR_MBLTX(&bltr);
  1584. }
  1585. if ((SrcType == LN_YUV422) || (SrcType == LN_RGB565 && nBytesPixel == 1))
  1586. CALL_DELAY_9BIT_BLT(TRUE);
  1587. }
  1588. else
  1589. {
  1590. // HWBUG !!! -- Break into sram-aligned vertical tiles
  1591. // based on source alignment
  1592. // tile mask
  1593. const int mtile = 128; /* sram is 128 bytes */
  1594. const int mtile_mask = mtile - 1;
  1595. const short maj_x = bltr.MAJ_X;
  1596. const short min_x = bltr.MIN_X;
  1597. int endx = xDst + cxClip; // last x, exclusive, in pixels
  1598. short xaccum;
  1599. int dstx = xDst;
  1600. int srcx = xSrc;
  1601. int dst_ext;
  1602. int src_ext;
  1603. int copy_src_ext;
  1604. #ifndef WINNT_VER40
  1605. ASSERT( BITSPERPIXEL != 24 ); // HWBUG !!!
  1606. #endif
  1607. if ( nBytesPixel == 2 )
  1608. {
  1609. cxSrc *= 2; /* convert size to Bytes from pixels */
  1610. cxDst *= 2;
  1611. srcx = (xSrc *= 2);
  1612. dstx = (xDst *= 2);
  1613. bltr.OP0_opRDRAM.pt.X *= 2;
  1614. bltr.OP1_opRDRAM.pt.X *= 2;
  1615. endx *= 2; /* convert end marker to bytes */
  1616. }
  1617. #ifdef TRACE_STRETCH
  1618. #ifdef TRACE_ALL
  1619. DBG_MESSAGE((" mtile = %d maj = %d min = %d accum = %d shrinkinc = %04x",
  1620. mtile, maj_x, min_x, bltr.ACCUM_X, bltr.SHRINKINC));
  1621. #endif
  1622. #endif
  1623. if (LGDEVID == CL_GD5464 && SrcType != LN_8BIT)
  1624. {
  1625. bltr.SHRINKINC.pt.X *= 2;
  1626. CALL_DRV_STR_MBLTY(&bltr); // Load the invariant registers
  1627. bltr.SHRINKINC.pt.X /= 2;
  1628. }
  1629. else
  1630. CALL_DRV_STR_MBLTY(&bltr); // Load the invariant registers
  1631. do
  1632. {
  1633. // get alignment to first src tile / sram break;
  1634. if ( srcx & mtile_mask ) // initial alignment
  1635. {
  1636. src_ext = mtile - (srcx & mtile_mask);
  1637. if ( src_ext > cxSrc )
  1638. src_ext = cxSrc;
  1639. }
  1640. else
  1641. {
  1642. if ( cxSrc < mtile )
  1643. src_ext = cxSrc; // last partial tile
  1644. else
  1645. src_ext = mtile; // complete tile
  1646. }
  1647. srcx += src_ext; // account for amount of src consumed
  1648. cxSrc -= src_ext;
  1649. // calculate how many destination pixels == src_ext
  1650. xaccum = bltr.ACCUM_X;
  1651. dst_ext = 0;
  1652. copy_src_ext = src_ext;
  1653. do
  1654. {
  1655. dst_ext += 2;
  1656. copy_src_ext -= 2 * bltr.SHRINKINC.pt.X;
  1657. xaccum += min_x;
  1658. if ( xaccum < 0 )
  1659. {
  1660. xaccum += maj_x;
  1661. copy_src_ext -= 2;
  1662. }
  1663. } while ( copy_src_ext > 0 && (dstx + dst_ext <= endx) );
  1664. dst_ext &= ~3; /* force destination extent to DWORDs */
  1665. dstx += dst_ext;
  1666. #ifdef TRACE_STRETCH
  1667. #ifdef TRACE_ALL
  1668. DBG_MESSAGE((" srcx = %d src_ext = %d cxSrc = %d dstx = %d dst_ext = %d end = %d",
  1669. srcx, src_ext, cxSrc, dstx, dst_ext, endx ));
  1670. #endif
  1671. #endif
  1672. if ( SrcType == LN_RGB565 )
  1673. bltr.SRCX = src_ext + 2;
  1674. else
  1675. bltr.SRCX = (USHORT)src_ext;
  1676. bltr.BLTEXT.pt.X = (USHORT)dst_ext;
  1677. if ( dst_ext > 0 )
  1678. CALL_DRV_STR_MBLTX(&bltr);
  1679. bltr.ACCUM_X = xaccum;
  1680. bltr.OP0_opRDRAM.pt.X += (USHORT)dst_ext;
  1681. bltr.OP1_opRDRAM.pt.X += (USHORT)src_ext;
  1682. } while ( (dstx < endx) && ( cxSrc > 0));
  1683. xFill = bltr.OP0_opRDRAM.pt.X;
  1684. cxFill = (xDst + cxDst) - xFill;
  1685. #ifdef TRACE_STRETCH
  1686. DBG_MESSAGE((" srcx=%d src_ext=%d cxSrc=%d dstx=%d dst_ext=%d end=%d xFill=%d cxFill=%d",
  1687. srcx, src_ext, cxSrc, dstx, dst_ext, endx, xFill, cxFill ));
  1688. #endif
  1689. // Edge Fill for trailing edge was deferred. Calculate correct amount
  1690. // Taking into account pixels skipped above for alignment.
  1691. //
  1692. if ((cxFill > 0) && (cxClip = (xFill & 7)) &&
  1693. ((SrcType == LN_YUV422)||((nBytesPixel == 1) && (SrcType == LN_RGB565))))
  1694. { // these must be extra pixels. They must be filled using
  1695. // the same 9th bit and in the same format as the stretch
  1696. if ( SrcType == LN_YUV422 )
  1697. CALL_MEDGE_FILL_BLT(xFill, yFill, cxFill, cyFill,
  1698. MAKELONG(BOGUS_YUV, BOGUS_YUV), TRUE);
  1699. else
  1700. CALL_MEDGE_FILL_BLT(xFill, yFill, cxFill, cyFill,
  1701. 0x00000000, TRUE);
  1702. xFill = bltr.OP0_opRDRAM.pt.X + cxClip;
  1703. cxFill -= cxClip;
  1704. }
  1705. if ((SrcType == LN_YUV422) || (SrcType == LN_RGB565 && nBytesPixel == 1))
  1706. CALL_DELAY_9BIT_BLT(TRUE);
  1707. if ( cxFill > 0 )
  1708. {
  1709. /* perform edge fill Blt */
  1710. if ( nBytesPixel == 2 )
  1711. CALL_MEDGE_FILL_BLT(xFill, yFill, cxFill, cyFill,
  1712. MAKELONG(BOGUS_YUV, BOGUS_YUV), FALSE);
  1713. else
  1714. CALL_EDGE_FILL_BLT(xFill, yFill, cxFill, cyFill,
  1715. 0x00000000, FALSE);
  1716. }
  1717. }
  1718. } // DrvStretch64
  1719. /***************************************************************************
  1720. *
  1721. * FUNCTION: DrvStretch62
  1722. *
  1723. * DESCRIPTION: The 5462 doesn't do display list programming, so
  1724. * all blts must be direct (call the DIR_XXX functions)
  1725. *
  1726. ****************************************************************************/
  1727. void DRVSTRETCH62
  1728. #ifndef WINNT_VER40
  1729. LPGLOBALDATA lpDDHALData,
  1730. #endif
  1731. int xDst, int yDst, int cxDst, int cyDst,
  1732. int xSrc, int ySrc, int cxSrc, int cySrc,
  1733. int nBytesPixel, int SrcType, int BaseOffset,
  1734. int OnScreen)
  1735. {
  1736. int cxClip = cxDst;
  1737. int cyClip = cyDst;
  1738. int cxFill = 0;
  1739. int cyFill = cyDst;
  1740. int xFill = xDst;
  1741. int yFill = yDst;
  1742. int cxTrim = 0;
  1743. int iratio, i;
  1744. #ifdef RDRAM_8BIT
  1745. PVGAR pREG = (PVGAR) lpDDHALData->RegsAddress;
  1746. #endif
  1747. autoblt_regs bltr;
  1748. AXIS axis[2];
  1749. int nDst[2];
  1750. int nSrc[2];
  1751. #ifdef RDRAM_8BIT
  1752. RECTL SrcRectl;
  1753. int nFound = FALSE;
  1754. #endif
  1755. DD_LOG(("DrvStretch62 - dst=%08lX dstext=%08lX src=%08lX srcext=%08lX\r\n",
  1756. MAKELONG(xDst,yDst),MAKELONG(cxDst,cyDst),
  1757. MAKELONG(xSrc,ySrc),MAKELONG(cxSrc,cySrc)));
  1758. #ifdef RDRAM_8BIT
  1759. if (!lpDDHALData->fNineBitRDRAMS)
  1760. {
  1761. if (SrcType == LN_YUV422)
  1762. {
  1763. SrcRectl.left = xSrc;
  1764. SrcRectl.top = ySrc;
  1765. SrcRectl.right = xSrc+cxSrc;
  1766. SrcRectl.bottom = ySrc+cySrc;
  1767. if (MEMCMP(&SrcRectl, sizeof(SrcRectl)) == 0)
  1768. nFound = TRUE;
  1769. if (nFound)
  1770. {
  1771. #if 0
  1772. DBG_MESSAGE(("Stretch: Found Offscreen Area P1(%x,%x) P2(%x,%x) Dst(%x, %x) Dst(%x %x)\n",
  1773. SrcRectl.left,
  1774. SrcRectl.top,
  1775. SrcRectl.right,
  1776. SrcRectl.bottom,
  1777. xDst,
  1778. yDst,
  1779. xDst+cxDst,
  1780. yDst+cyDst));
  1781. #endif
  1782. LL16(grX_Start_2, xDst + ((4 - (xDst & 3)) & 3));
  1783. LL16(grY_Start_2, yDst);
  1784. LL16(grX_End_2, xDst+(cxDst>>3<<3));
  1785. LL16(grY_End_2, yDst+cyDst);
  1786. }
  1787. else
  1788. {
  1789. #if 0
  1790. DBG_MESSAGE(("Stretch: Not Found Offscreen Area P1(%x,%x) P2(%x,%x)\n",
  1791. SrcRectl.left,
  1792. SrcRectl.top,
  1793. SrcRectl.right,
  1794. SrcRectl.bottom));
  1795. #endif
  1796. LL16(grX_Start_2, 0);
  1797. LL16(grY_Start_2, 0);
  1798. LL16(grX_End_2, 0);
  1799. LL16(grY_End_2, 0);
  1800. // Black Blit Here
  1801. CALL_DIR_DRV_DST_BLT(0x107000CC,MAKELONG(xDst,yDst),0,MAKELONG(cxDst,cyDst));
  1802. return ;
  1803. }
  1804. } // endif (SrcType == LN_YUV422)
  1805. } // endif (!lpDDHALData->fNineBitRDRAMS)
  1806. #endif
  1807. #ifdef TRACE_STRETCH
  1808. DBG_MESSAGE(("DrvStretch62: %4d,%4d %4dx%4d -> %4d,%4d %4dx%4d (%d %d) %d",
  1809. xSrc, ySrc, cxSrc, cySrc,
  1810. xDst, yDst, cxDst, cyDst,
  1811. nBytesPixel, SrcType, BaseOffset));
  1812. #endif
  1813. if ((SrcType == LN_YUV422) ||
  1814. ((SrcType == LN_RGB565) && (nBytesPixel == 1)))
  1815. { // Force alignment of output to QWORD ( it is documented as DWORD but broken)
  1816. if ( nBytesPixel == 2 )
  1817. { // 16 bit frame buffer ( Note all ptrs/extents in terms of 16 bpp )
  1818. // The X portions will be mutiplied by 2 by chip on being written )
  1819. if ( cxDst > cxSrc )
  1820. iratio = cxDst / cxSrc; // integer ratio of stretch
  1821. else
  1822. iratio = cxSrc / cxDst; // integer ratio of shrink
  1823. if ( xDst & 3 ) /* This should be for LN_YUV422 only */
  1824. {
  1825. cxFill = 4 - (xDst & 3);
  1826. cxTrim = cxFill; // save trim count for source clipping if required
  1827. if ( cxFill > cxClip )
  1828. cxFill = cxClip; // check for no stretch left
  1829. cxClip -= cxFill; /* reduce size */
  1830. cxDst -= cxFill; /* reduce size */
  1831. xDst += cxFill; /* force alignment to next even DWORD boundary */
  1832. CALL_DIR_DRV_DST_BLT(MAKELONG(0x0000,BD_RES),MAKELONG(xFill,yFill),
  1833. 0,MAKELONG(cxFill,cyFill));
  1834. #ifdef TRACE_STRETCH
  1835. DBG_MESSAGE((" Edge Fill(1) %d,%d %d x %d", xFill, yFill, cxFill, cyFill));
  1836. #endif
  1837. } //endif ( xDst & 3 )
  1838. cxFill = cxClip & 3;
  1839. if ( cxFill )
  1840. {
  1841. cxClip -= cxFill; /* force size to next smaller even DWORD count */
  1842. xFill = xDst + cxClip;
  1843. if ( cxClip >= cxSrc)
  1844. { // If shrink defer edge fill to later as there may be more
  1845. CALL_DIR_EDGE_FILL_BLT(xFill, yFill, cxFill, cyFill,
  1846. MAKELONG(BOGUS_YUV, BOGUS_YUV), FALSE);
  1847. #ifdef TRACE_STRETCH
  1848. DBG_MESSAGE((" Edge Fill(2) %d,%d %d x %d", xFill, yFill, cxFill, cyFill));
  1849. #endif
  1850. } // endif ( cxClip >= cxSrc)
  1851. } // endif ( cxFill )
  1852. if ( (cxClip < cxSrc) )
  1853. { // Edge Clip on shrinks only ( add config flag check here )
  1854. int excess;
  1855. // extra pixels to discard above integer ratio
  1856. excess = ( cxSrc / iratio ) - cxClip;
  1857. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1858. #ifdef WINNT_VER40 // WINNT_VER40
  1859. DISPDBG((DBGLVL1,
  1860. "DDraw - Edge Clip iratio = %d excess = %d Trim %% = %d",
  1861. iratio, excess, 2));
  1862. #else // ----- #elseif WINNT_VER40 -----
  1863. DBG_MESSAGE((" Edge Clip iratio = %d excess = %d Trim %% = %d", iratio, excess, 2));
  1864. #endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
  1865. if ( excess && cxTrim )
  1866. { // These excess pixels are caused by our Dest alignment
  1867. // problems on the Left edge
  1868. if ( excess < (cxTrim * iratio) )
  1869. {
  1870. cxSrc -= excess;
  1871. xSrc += excess;
  1872. excess = 0;
  1873. }
  1874. else
  1875. {
  1876. cxSrc -= cxTrim * iratio;
  1877. xSrc += cxTrim * iratio;
  1878. excess -= cxTrim * iratio;
  1879. }
  1880. } // endif ( excess && cxTrim )
  1881. if ( excess && cxFill)
  1882. { // These excess pixels are caused by our Dest alignment
  1883. // problems on the Right edge
  1884. if ( excess < (cxFill * iratio) )
  1885. {
  1886. cxSrc -= excess;
  1887. excess = 0;
  1888. }
  1889. else
  1890. {
  1891. cxSrc -= cxFill * iratio;
  1892. excess -= cxFill * iratio;
  1893. }
  1894. } // endif ( excess < (cxFill * iratio) )
  1895. if ( excess && (excess < (2 * cxClip)/100 ))
  1896. { // if excess is less than 2% of frame trim edges
  1897. int trim = excess / 2; // half the excess of pixels
  1898. xSrc += trim; // offset pixel pointer
  1899. cxSrc -= excess; // all the excess in pixels
  1900. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1901. #ifdef WINNT_VER40 // WINNT_VER40
  1902. DISPDBG((DBGLVL1,
  1903. "DDraw - Edge Clip Left = %d, xSrc = %d, cxSrc = %d",
  1904. trim, xSrc, cxSrc));
  1905. #else // ----- #elseif WINNT_VER40 -----
  1906. DBG_MESSAGE((" Edge Clip Left = %d, xSrc = %d, cxSrc = %d", trim, xSrc, cxSrc));
  1907. #endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
  1908. }
  1909. if ( iratio == 1 )
  1910. { // we may have just changed a shrink to a 1 : 1
  1911. // if excess is zero do edge fill now
  1912. // extra pixels to discard above integer ratio
  1913. excess = ( cxSrc / iratio ) - cxClip;
  1914. if ( !excess && cxFill )
  1915. {
  1916. xFill = xDst + cxClip;
  1917. CALL_DIR_EDGE_FILL_BLT(xFill, yFill, cxFill, cyFill,
  1918. MAKELONG(BOGUS_YUV, BOGUS_YUV), FALSE);
  1919. #ifdef TRACE_STRETCH
  1920. DBG_MESSAGE((" Edge Fill(7) %d,%d %d x %d", xFill, yFill, cxFill, cyFill));
  1921. #endif
  1922. }
  1923. } // endif ( iratio == 1 )
  1924. }
  1925. else
  1926. { // Stretch adjustments
  1927. if ( xSrc - BaseOffset )
  1928. { // if we are not starting from left edge of source image
  1929. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1930. #ifdef WINNT_VER40 // WINNT_VER40
  1931. DISPDBG((DBGLVL1,
  1932. "DDraw - Edge Trim for stretch iratio = %d , cxTrim = %d xSrc %d",
  1933. iratio, cxTrim, xSrc));
  1934. #else // ----- #elseif WINNT_VER40 -----
  1935. DBG_MESSAGE((" Edge Trim for stretch iratio = %d , cxTrim = %d xSrc %d", iratio, cxTrim, xSrc));
  1936. #endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
  1937. if ( cxTrim )
  1938. { // And we were forced to offset for left edge alignment
  1939. cxSrc -= cxTrim / iratio;
  1940. xSrc += cxTrim / iratio;
  1941. }
  1942. }
  1943. } // endif ( (cxClip < cxSrc) )
  1944. // Global adjustments
  1945. if ( xSrc & 1 ) /* HW bug workaound for clipping */
  1946. {
  1947. xSrc += 1; /* Align to SRC DWORD Boundary */
  1948. cxSrc -= 1; /* Account for smaller size */
  1949. }
  1950. }
  1951. else
  1952. { // 8 Bit frame buffer.
  1953. // Force alignment of output to QWORD ( it is documented as DWORD but broken)
  1954. if ( cxDst >= (cxSrc*2) )
  1955. iratio = cxDst / (2 * cxSrc); // integer ratio of stretch
  1956. else
  1957. iratio = (2 * cxSrc ) / cxDst; // integer ratio of shrink
  1958. if ( xDst & 7 ) /* This should be for LN_YUV422 only */
  1959. {
  1960. cxFill = 8 - (xDst & 7);
  1961. if ( cxFill > cxClip )
  1962. cxFill = cxClip; // check for no stretch left
  1963. cxClip -= cxFill; /* reduce size */
  1964. cxDst -= cxFill; /* reduce size */
  1965. xDst += cxFill; /* force alignment to next even WORD boundary */
  1966. CALL_DIR_DRV_DST_BLT(MAKELONG(0x0000,BD_RES),MAKELONG(xFill,yFill),
  1967. 0,MAKELONG(cxFill,cyFill));
  1968. #ifdef TRACE_STRETCH
  1969. DBG_MESSAGE((" Edge Fill(3) %d,%d %d x %d", xFill, yFill, cxFill, cyFill));
  1970. #endif
  1971. } // endif ( xDst & 7 )
  1972. cxFill = cxClip & 7;
  1973. if ( cxFill )
  1974. {
  1975. cxClip -= cxFill; /* force size to next smaller even DWORD count */
  1976. if ( cxClip >= (cxSrc * 2))
  1977. { // If shrink defer edge fill to later as there may be more
  1978. xFill = xDst + cxClip;
  1979. #ifdef BOGUS_8BIT
  1980. CALL_DIR_EDGE_FILL_BLT(xFill, yFill, cxFill, cyFill,
  1981. MAKELONG(BOGUS_YUV, BOGUS_YUV), FALSE);
  1982. #else
  1983. CALL_DIR_DRV_DST_BLT(MAKELONG(0x0000,BD_RES),MAKELONG(xFill,yFill),
  1984. 0,MAKELONG(cxFill,cyFill));
  1985. #endif
  1986. #ifdef TRACE_STRETCH
  1987. DBG_MESSAGE((" Edge Fill(4) %d,%d %d x %d", xFill, yFill, cxFill, cyFill));
  1988. #endif
  1989. }
  1990. } // endif ( cxFill )
  1991. // change pixel pointer to byte pointer
  1992. // taking account of X origin of buffer
  1993. xSrc = BaseOffset + (xSrc - BaseOffset) * 2;
  1994. cxSrc *= 2; /* change pixel count to byte count */
  1995. #ifdef EDGE_CLIP
  1996. if ( (cxClip < cxSrc) && lpDDHALData->EdgeTrim)
  1997. { // Edge Clip on shrinks only ( add config flag check here )
  1998. int excess;
  1999. // extra pixels to discard above integer ratio
  2000. excess = ( cxSrc / iratio ) - cxClip;
  2001. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  2002. #ifdef WINNT_VER40 // WINNT_VER40
  2003. DISPDBG((DBGLVL1,
  2004. "DDraw - Edge Clip iratio = %d excess = %d Trim %% = %d",
  2005. iratio, excess, lpDDHALData->EdgeTrim));
  2006. #else // ----- #elseif WINNT_VER40 -----
  2007. DBG_MESSAGE((" Edge Clip iratio = %d excess = %d Trim %% = %d",
  2008. iratio, excess, lpDDHALData->EdgeTrim));
  2009. #endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
  2010. if ( excess && cxTrim )
  2011. { // These excess pixels are caused by our Dest alignment
  2012. // problems on the Left edge
  2013. if ( excess < (cxTrim * iratio) )
  2014. {
  2015. cxSrc -= excess;
  2016. xSrc += excess;
  2017. excess = 0;
  2018. }
  2019. else
  2020. {
  2021. cxSrc -= cxTrim * iratio;
  2022. xSrc += cxTrim * iratio;
  2023. excess -= cxTrim * iratio;
  2024. }
  2025. } // endif ( excess && cxTrim )
  2026. if ( excess && cxFill)
  2027. { // These excess pixels are caused by our Dest alignment
  2028. // problems on the Right edge
  2029. if ( excess < (cxFill * iratio) )
  2030. {
  2031. cxSrc -= excess;
  2032. excess = 0;
  2033. }
  2034. else
  2035. {
  2036. cxSrc -= cxFill * iratio;
  2037. excess -= cxFill * iratio;
  2038. }
  2039. } // endif ( excess && cxFill)
  2040. if ( excess && ( excess < (lpDDHALData->EdgeTrim * cxClip)/100 ) )
  2041. { // if excess is less than specific % of frame trim edges
  2042. int trim = excess / 2; // half the excess as pixels
  2043. xSrc += trim; // offset pixel pointer
  2044. cxSrc -= excess; // all the excess in bytes
  2045. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  2046. #ifdef WINNT_VER40 // WINNT_VER40
  2047. DISPDBG((DBGLVL1,
  2048. "DDraw - Edge Clip Left = %d, xSrc = %d, cxSrc = %d",
  2049. trim, xSrc, cxSrc));
  2050. #else // ----- #elseif WINNT_VER40 -----
  2051. DBG_MESSAGE((" Edge Clip Left = %d, xSrc = %d, cxSrc = %d",
  2052. trim, xSrc, cxSrc));
  2053. #endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
  2054. }
  2055. if ( iratio == 1 )
  2056. { // we may have just changed a shrink to a 1 : 1
  2057. // if excess is no zero do edge fill now
  2058. // extra pixels to discard above integer ratio
  2059. excess = ( cxSrc / iratio ) - cxClip;
  2060. if ( !excess && cxFill )
  2061. {
  2062. xFill = xDst + cxClip;
  2063. #ifdef BOGUS_8BIT
  2064. CALL_DIR_EDGE_FILL_BLT(xFill, yFill, cxFill, cyFill,
  2065. MAKELONG(BOGUS_YUV, BOGUS_YUV), FALSE);
  2066. #else
  2067. CALL_DIR_DRV_DST_BLT(MAKELONG(0x0000,BD_RES),MAKELONG(xFill,yFill),
  2068. 0,MAKELONG(cxFill,cyFill));
  2069. #endif
  2070. #ifdef TRACE_STRETCH
  2071. DBG_MESSAGE((" Edge Fill(6) %d,%d %d x %d", xFill, yFill, cxFill, cyFill));
  2072. #endif
  2073. } // endif ( !excess && cxFill )
  2074. } // endif ( iratio == 1 )
  2075. } // endif ( (cxClip < cxSrc) && lpDDHALData->EdgeTrim)
  2076. #endif
  2077. if ( xSrc & 3 ) /* HW bug workaound for clipping */
  2078. {
  2079. cxSrc -= 4 - (xSrc & 3); // reduce size
  2080. xSrc = (xSrc + 3) & ~ 3; // Align to SRC DWORD Boundary
  2081. }
  2082. } // endif ( nBytesPixel == 2 )
  2083. }
  2084. if ( cxClip == 0 )
  2085. return; // discard zero extent stretchs
  2086. if ( nBytesPixel == 1 &&
  2087. ((SrcType == LN_YUV422) || (SrcType == LN_RGB565 )) ||
  2088. ((nBytesPixel == 2) && (SrcType == LN_YUV422) ) )
  2089. {
  2090. /* This is to ensure that the last packet of any previous blt */
  2091. /* does no go out with 9th bit set */
  2092. CALL_DIR_DELAY_9BIT_BLT(FALSE);
  2093. bltr.DRAWBLTDEF.DW = MAKELONG(0x04CC, BD_RES | BD_OP1);
  2094. lpDDHALData->YUVLeft = (USHORT)xDst; // Save 9th bit rect coords for main
  2095. lpDDHALData->YUVTop = (USHORT)yDst; // driver for exclusion purposes.
  2096. lpDDHALData->YUVXExt = (USHORT)cxClip;
  2097. lpDDHALData->YUVYExt = (USHORT)cyClip;
  2098. // tell main driver the rectangle is valid
  2099. lpDDHALData->DrvSemaphore |= DRVSEM_YUV_RECT_VALID;
  2100. }
  2101. else
  2102. bltr.DRAWBLTDEF.DW = MAKELONG(0x00CC, BD_RES | BD_OP1);
  2103. bltr.OP0_opRDRAM.DW = MAKELONG(xDst, yDst);
  2104. bltr.OP1_opRDRAM.DW = MAKELONG(xSrc, ySrc);
  2105. bltr.BLTEXT.DW = MAKELONG(cxClip, cyClip);
  2106. bltr.LNCNTL.W = SrcType << LN_YUV_SHIFT;
  2107. // Enable interpolation unless we have a palette (8bpp).
  2108. if (SrcType != LN_8BIT )
  2109. bltr.LNCNTL.W |= LN_XINTP_EN | LN_YINTP_EN;
  2110. bltr.SHRINKINC.w = 0x0000;
  2111. if ( cxClip < cxSrc )
  2112. {
  2113. bltr.LNCNTL.W |= LN_XSHRINK;
  2114. bltr.LNCNTL.W &= ~LN_XINTP_EN;
  2115. bltr.SHRINKINC.pt.X = (cxSrc / cxClip);
  2116. }
  2117. if ( cyDst < cySrc )
  2118. {
  2119. bltr.LNCNTL.W |= LN_YSHRINK;
  2120. bltr.LNCNTL.W &= ~LN_YINTP_EN;
  2121. bltr.SHRINKINC.pt.Y = (cySrc / cyDst);
  2122. }
  2123. if ( SrcType == LN_YUV422 || SrcType == LN_RGB565 )
  2124. {
  2125. if ( nBytesPixel == 1 )
  2126. bltr.SRCX = (USHORT)cxSrc; // If mixed mode is *2 already
  2127. else
  2128. bltr.SRCX = cxSrc * 2;
  2129. }
  2130. else
  2131. bltr.SRCX = cxSrc * nBytesPixel;
  2132. #ifdef TRACE_STRETCH
  2133. DBG_MESSAGE((" cSrc = %d , %d : cDst = %d , %d : cClip = %d , %d",
  2134. cxSrc, cySrc, cxDst, cyDst, cxClip, cyClip));
  2135. #endif
  2136. // Compute DDA terms.
  2137. nDst[0] = cxClip; nDst[1] = cyDst;
  2138. nSrc[0] = cxSrc; nSrc[1] = cySrc;
  2139. for (i = 0; i < 2; i++)
  2140. {
  2141. int kDst = 1;
  2142. if (bltr.LNCNTL.W & ((i==0) ? LN_XINTP_EN : LN_YINTP_EN))
  2143. {
  2144. nDst[i] *= 4;
  2145. nSrc[i] *= 4;
  2146. nSrc[i] -= 3;
  2147. kDst = 0x8000 / nDst[i];
  2148. }
  2149. if (bltr.LNCNTL.W & ((i==0) ? LN_XSHRINK : LN_YSHRINK))
  2150. { /* Shrink Terms */
  2151. axis[i].maj = (short)nDst[i];
  2152. axis[i].min = - (nSrc[i] % nDst[i]);
  2153. axis[i].accum = axis[i].maj - 1
  2154. - ((nSrc[i] % nDst[i]) / (nSrc[i]/nDst[i] + 1));
  2155. }
  2156. else
  2157. { /* Stretch Terms */
  2158. axis[i].maj = kDst * nDst[i];
  2159. axis[i].min = -kDst * nSrc[i];
  2160. axis[i].accum = axis[i].maj - 1
  2161. - ((axis[i].maj % -axis[i].min) / (nDst[i]/nSrc[i] + 1));
  2162. }
  2163. } // endfor (i = 0; i < 2; i++)
  2164. bltr.MAJ_X = axis[0].maj;
  2165. bltr.MIN_X = axis[0].min;
  2166. bltr.ACCUM_X = axis[0].accum;
  2167. bltr.MAJ_Y = axis[1].maj;
  2168. bltr.MIN_Y = axis[1].min;
  2169. bltr.ACCUM_Y = axis[1].accum;
  2170. if ((SrcType == LN_8BIT) ||
  2171. ((SrcType == LN_YUV422) && !(bltr.LNCNTL.W & LN_XSHRINK)) )
  2172. {
  2173. CALL_DIR_DRV_STR_BLT(&bltr); // Single stretch
  2174. if ( (SrcType == LN_YUV422) )
  2175. {
  2176. // This is to ensure that the last packet of blt does no go out with
  2177. // 9th bit clear It is cheaper than waiting, especially on single
  2178. // stripe BLTs
  2179. CALL_DIR_DELAY_9BIT_BLT(TRUE);
  2180. }
  2181. }
  2182. else if (SrcType == LN_RGB565 && !(bltr.LNCNTL.W & LN_XSHRINK))
  2183. #if 1
  2184. {
  2185. // HWBUG !!! -- Break into sram-aligned vertical tiles
  2186. // based on destination alignment
  2187. // dword and tile masks
  2188. const int mdwrd = 4 ;
  2189. const int tile = 128 ; /* sram is 128 bytes */
  2190. const int mtile = 128 - 1 ; /* sram is 128 bytes */
  2191. int endx = xDst + cxClip; // last x, exclusive
  2192. int dstxe = endx & ~mtile; // start of last tile
  2193. DDAX accx = axis[0].accum;
  2194. int dstx = xDst;
  2195. int srcx = xSrc;
  2196. int src_ext = 0;
  2197. int xext;
  2198. #ifndef WINNT_VER40
  2199. ASSERT( BITSPERPIXEL != 24 ); // HWBUG !!!
  2200. #endif
  2201. if ( nBytesPixel == 2 )
  2202. {
  2203. cxSrc *= 2; /* convert size to Bytes from pixels */
  2204. cxDst *= 2;
  2205. srcx = (xSrc *= 2);
  2206. dstx = (xDst *= 2);
  2207. bltr.OP0_opRDRAM.pt.X *= 2;
  2208. bltr.OP1_opRDRAM.pt.X *= 2;
  2209. endx *= 2;
  2210. dstxe = endx & ~mtile;
  2211. }
  2212. CALL_DIR_DRV_STR_MBLTY(&bltr); // load the invariant sections of the engine
  2213. // step to the next tile
  2214. xext = 0;
  2215. while ((dstx & mtile) && (dstx < endx))
  2216. {
  2217. dstx += 2;
  2218. xext += 2;
  2219. accx += axis[0].min;
  2220. if (accx < 0)
  2221. {
  2222. accx += axis[0].maj;
  2223. srcx += 2;
  2224. src_ext += 2;
  2225. }
  2226. } // endwhile ((dstx & mtile) && (dstx < endx))
  2227. // do the odd pixels we stepped over
  2228. if (xext)
  2229. {
  2230. bltr.BLTEXT.PT.X = (USHORT)xext;
  2231. CALL_DIR_DRV_STR_MBLTX(&bltr);
  2232. }
  2233. // do all the whole tiles but the last
  2234. bltr.SRCX -= (USHORT)src_ext;
  2235. while (dstx < dstxe)
  2236. {
  2237. bltr.OP0_opRDRAM.PT.X = (USHORT)dstx;
  2238. bltr.OP1_opRDRAM.PT.X = (USHORT)srcx;
  2239. bltr.ACCUM_X = accx;
  2240. xext = 0;
  2241. src_ext = 0;
  2242. do
  2243. {
  2244. dstx += 2;
  2245. xext += 2;
  2246. accx += axis[0].min;
  2247. if (accx < 0)
  2248. {
  2249. accx += axis[0].maj;
  2250. srcx += 2;
  2251. src_ext += 2;
  2252. }
  2253. } while (dstx & mtile);
  2254. bltr.BLTEXT.PT.X = (USHORT)xext;
  2255. CALL_DIR_DRV_STR_MBLTX(&bltr);
  2256. bltr.SRCX -= (USHORT)src_ext;
  2257. } // endwhile (dstx < dstxe)
  2258. // do the last tile
  2259. if (dstx < endx)
  2260. {
  2261. bltr.OP0_opRDRAM.PT.X = (USHORT)dstx;
  2262. bltr.OP1_opRDRAM.PT.X = (USHORT)srcx;
  2263. bltr.ACCUM_X = accx;
  2264. bltr.BLTEXT.PT.X = endx - dstx;
  2265. CALL_DIR_DRV_STR_MBLTX(&bltr);
  2266. }
  2267. if ( (SrcType == LN_YUV422) || (SrcType == LN_RGB565 && nBytesPixel == 1) )
  2268. {
  2269. // This is to ensure that the last packet of stretch blt does no go out
  2270. // with 9th bit clear. It is cheaper than waiting, especially on single
  2271. // stripe BLTs
  2272. CALL_DIR_DELAY_9BIT_BLT(TRUE);
  2273. }
  2274. }
  2275. #else
  2276. {
  2277. // HWBUG !!! -- Break into Double aligned vertical stripes
  2278. // based on src and dest alignment
  2279. // dword and tile masks
  2280. const int mdwrd = 4 ;
  2281. const int tile = 128 ; /* sram is 128 bytes */
  2282. const int mtile = 128 - 1 ; /* sram is 128 bytes */
  2283. int endx = xDst + cxClip; // last x, exclusive
  2284. int dstxe = endx & ~mtile; // start of last tile
  2285. DDAX accx = axis[0].accum;
  2286. int dstx = xDst;
  2287. int srcx = xSrc;
  2288. int src_ext = 0;
  2289. int xext;
  2290. #ifndef WINNT_VER40
  2291. ASSERT( BITSPERPIXEL != 24 ); // HWBUG !!!
  2292. #endif
  2293. if ( nBytesPixel == 2 )
  2294. {
  2295. cxSrc *= 2; /* convert size to Bytes from pixels */
  2296. cxDst *= 2;
  2297. srcx = (xSrc *= 2);
  2298. dstx = (xDst *= 2);
  2299. bltr.OP0_opRDRAM.pt.X *= 2;
  2300. bltr.OP1_opRDRAM.pt.X *= 2;
  2301. endx *= 2;
  2302. dstxe = endx & ~mtile;
  2303. }
  2304. // step to the next tile
  2305. xext = 0;
  2306. while ((dstx & mtile) && (dstx < endx))
  2307. {
  2308. dstx += 2;
  2309. xext += 2;
  2310. accx += axis[0].min;
  2311. if (accx < 0)
  2312. {
  2313. accx += axis[0].maj;
  2314. srcx += 2;
  2315. src_ext += 2;
  2316. }
  2317. }
  2318. // do the odd pixels we stepped over
  2319. if (xext)
  2320. {
  2321. bltr.BLTEXT.PT.X = xext;
  2322. CALL_DIR_DRV_STR_MBLT(&bltr);
  2323. }
  2324. // do all the whole tiles but the last
  2325. bltr.SRCX -= src_ext;
  2326. while (dstx < dstxe)
  2327. {
  2328. bltr.OP0_opRDRAM.PT.X = dstx;
  2329. bltr.OP1_opRDRAM.PT.X = srcx;
  2330. bltr.ACCUM_X = accx;
  2331. xext = 0;
  2332. src_ext = 0;
  2333. do
  2334. {
  2335. dstx += 2;
  2336. xext += 2;
  2337. accx += axis[0].min;
  2338. if (accx < 0)
  2339. {
  2340. accx += axis[0].maj;
  2341. srcx += 2;
  2342. src_ext += 2;
  2343. }
  2344. } while (dstx & mtile);
  2345. bltr.BLTEXT.PT.X = xext;
  2346. CALL_DIR_DRV_STR_MBLT(&bltr);
  2347. }
  2348. // do the last tile
  2349. if (dstx < endx)
  2350. {
  2351. bltr.OP0_opRDRAM.PT.X = dstx;
  2352. bltr.OP1_opRDRAM.PT.X = srcx;
  2353. bltr.ACCUM_X = accx;
  2354. bltr.BLTEXT.PT.X = endx - dstx;
  2355. CALL_DIR_DRV_STR_MBLT(&bltr);
  2356. }
  2357. if ( (SrcType == LN_YUV422) || (SrcType == LN_RGB565 && nBytesPixel == 1) )
  2358. {
  2359. /* This is to ensure that the last packet of stretch blt does no go out with 9th bit clear */
  2360. /* It is cheaper than waiting, especially on single stripe BLTs */
  2361. CALL_DIR_DELAY_9BIT_BLT(TRUE);
  2362. }
  2363. }
  2364. #endif
  2365. else
  2366. {
  2367. // HWBUG !!! -- Break into sram-aligned vertical tiles
  2368. // based on source alignment
  2369. // tile mask
  2370. const int mtile = 128; /* sram is 128 bytes */
  2371. const int mtile_mask = mtile - 1;
  2372. const short maj_x = bltr.MAJ_X;
  2373. const short min_x = bltr.MIN_X;
  2374. int endx = xDst + cxClip; // last x, exclusive, in pixels
  2375. short xaccum;
  2376. int dstx = xDst;
  2377. int srcx = xSrc;
  2378. int dst_ext;
  2379. int src_ext;
  2380. int copy_src_ext;
  2381. #ifndef WINNT_VER40
  2382. ASSERT( BITSPERPIXEL != 24 ); // HWBUG !!!
  2383. #endif
  2384. if ( nBytesPixel == 2 )
  2385. {
  2386. cxSrc *= 2; /* convert size to Bytes from pixels */
  2387. cxDst *= 2;
  2388. srcx = (xSrc *= 2);
  2389. dstx = (xDst *= 2);
  2390. bltr.OP0_opRDRAM.pt.X *= 2;
  2391. bltr.OP1_opRDRAM.pt.X *= 2;
  2392. endx *= 2; /* convert end marker to bytes */
  2393. }
  2394. #ifdef TRACE_STRETCH
  2395. #ifdef TRACE_ALL
  2396. DBG_MESSAGE((" mtile = %d maj = %d min = %d accum = %d shrinkinc = %04x",
  2397. mtile, maj_x, min_x, bltr.ACCUM_X, bltr.SHRINKINC));
  2398. #endif
  2399. #endif
  2400. CALL_DIR_DRV_STR_MBLTY(&bltr); // Load the invariant registers
  2401. do
  2402. {
  2403. // get alignment to first src tile / sram break;
  2404. if ( srcx & mtile_mask ) // initial alignment
  2405. {
  2406. src_ext = mtile - (srcx & mtile_mask);
  2407. if ( src_ext > cxSrc )
  2408. src_ext = cxSrc;
  2409. }
  2410. else
  2411. {
  2412. if ( cxSrc < mtile )
  2413. src_ext = cxSrc; // last partial tile
  2414. else
  2415. src_ext = mtile; // complete tile
  2416. }
  2417. srcx += src_ext; // account for amount of src consumed
  2418. cxSrc -= src_ext;
  2419. // calculate how many destination pixels == src_ext
  2420. xaccum = bltr.ACCUM_X;
  2421. dst_ext = 0;
  2422. copy_src_ext = src_ext;
  2423. do
  2424. {
  2425. dst_ext += 2;
  2426. copy_src_ext -= 2 * bltr.SHRINKINC.pt.X;
  2427. xaccum += min_x;
  2428. if ( xaccum < 0 )
  2429. {
  2430. xaccum += maj_x;
  2431. copy_src_ext -= 2;
  2432. }
  2433. } while ( copy_src_ext > 0 && (dstx + dst_ext <= endx) );
  2434. dst_ext &= ~3; /* force destination extent to DWORDs */
  2435. dstx += dst_ext;
  2436. #ifdef TRACE_STRETCH
  2437. #ifdef TRACE_ALL
  2438. DBG_MESSAGE((" srcx = %d src_ext = %d cxSrc = %d dstx = %d dst_ext = %d end = %d",
  2439. srcx, src_ext, cxSrc, dstx, dst_ext, endx ));
  2440. #endif
  2441. #endif
  2442. bltr.BLTEXT.pt.X = (USHORT)dst_ext;
  2443. if ( dst_ext > 0 )
  2444. CALL_DIR_DRV_STR_MBLTX(&bltr);
  2445. bltr.ACCUM_X = xaccum;
  2446. bltr.OP0_opRDRAM.pt.X += (USHORT)dst_ext;
  2447. bltr.OP1_opRDRAM.pt.X += (USHORT)src_ext;
  2448. bltr.SRCX -= (USHORT)src_ext;
  2449. } while ( (dstx < endx) && ( cxSrc > 0));
  2450. xFill = bltr.OP0_opRDRAM.pt.X;
  2451. cxFill = (xDst + cxDst) - xFill;
  2452. #ifdef TRACE_STRETCH
  2453. DBG_MESSAGE((" srcx=%d src_ext=%d cxSrc=%d dstx=%d dst_ext=%d end=%d xFill=%d cxFill=%d",
  2454. srcx, src_ext, cxSrc, dstx, dst_ext, endx, xFill, cxFill ));
  2455. #endif
  2456. // Edge Fill for trailing edge was deferred. Calculate correct amount
  2457. // Taking into account pixels skipped above for alignment.
  2458. if ((cxFill > 0) && (cxClip = (xFill & 7)) && ((SrcType == LN_YUV422)||((nBytesPixel == 1) &&(SrcType == LN_RGB565))))
  2459. {// these must be extra pixels. They must be filled using
  2460. // the same 9th bit and in the same format as the stretch
  2461. cxClip = 8 - cxClip;
  2462. if ( SrcType == LN_YUV422 )
  2463. {
  2464. CALL_DIR_MEDGE_FILL_BLT(xFill,yFill,cxClip,cyFill,
  2465. MAKELONG(BOGUS_YUV-1,BOGUS_YUV-1),TRUE);
  2466. }
  2467. else
  2468. {
  2469. CALL_DIR_MEDGE_FILL_BLT(xFill,yFill,cxClip,cyFill,0,TRUE);
  2470. }
  2471. #ifdef TRACE_STRETCH
  2472. DBG_MESSAGE((" Edge Fill 9th bit set %d,%d %d x %d", xFill, yFill, cxFill, cyFill));
  2473. #endif
  2474. xFill = bltr.OP0_opRDRAM.pt.X + cxClip;
  2475. cxFill -= cxClip;
  2476. }
  2477. if ( (SrcType == LN_YUV422) || (SrcType == LN_RGB565 && nBytesPixel == 1) )
  2478. {
  2479. /* This is to ensure that the last packet of stretch blt does no go out with 9th bit clear */
  2480. /* It is cheaper than waiting, especially on single stripe BLTs */
  2481. CALL_DIR_DELAY_9BIT_BLT(TRUE);
  2482. }
  2483. if ( cxFill > 0 )
  2484. {
  2485. /* perform edge fill Blt */
  2486. #ifdef BOGUS_8BIT
  2487. CALL_DIR_MEDGE_FILL_BLT(xFill,yFill,cxFill,cyFill,
  2488. MAKELONG(BOGUS_YUV,BOGUS_YUV),FALSE);
  2489. #else
  2490. if ( nBytesPixel == 2 )
  2491. CALL_DIR_MEDGE_FILL_BLT(xFill,yFill,cxFill,cyFill,
  2492. MAKELONG(BOGUS_YUV,BOGUS_YUV),FALSE);
  2493. else
  2494. CALL_DIR_MEDGE_FILL_BLT(xFill,yFill,cxFill,cyFill,0,FALSE);
  2495. #endif
  2496. #ifdef TRACE_STRETCH
  2497. DBG_MESSAGE((" Edge Fill(5) %d,%d %d x %d", xFill, yFill, cxFill, cyFill));
  2498. #endif
  2499. }
  2500. }
  2501. } /* DrvStretch62 */
  2502. /***************************************************************************
  2503. *
  2504. * FUNCTION: StretchColor
  2505. *
  2506. * DESCRIPTION: This is a software solution for both the 5462 and 5464
  2507. * to perform a stretch or shrink while there is a source
  2508. * color key specified.
  2509. *
  2510. ****************************************************************************/
  2511. void STRETCHCOLOR
  2512. #ifndef WINNT_VER40
  2513. LPGLOBALDATA lpDDHALData,
  2514. #endif
  2515. int xDst, int yDst, int cxDst, int cyDst,
  2516. int xSrc, int ySrc, int cxSrc, int cySrc,
  2517. DWORD ColorKey)
  2518. {
  2519. PVGAR pREG = (PVGAR) lpDDHALData->RegsAddress;
  2520. int xError, yError;
  2521. int xRun, yRun;
  2522. DD_LOG(("StretchColor - dst=%08lX dstext= %08lX src=%08lX srcext=%08lX colorkey=%08lX\r\n",
  2523. MAKELONG(xDst,yDst),MAKELONG(cxDst,cyDst),
  2524. MAKELONG(xSrc,ySrc),MAKELONG(cxSrc,cxSrc),
  2525. ColorKey));
  2526. // DD_LOG((" Beer break! - we're gonna blt every pixel one at a time\r\n"));
  2527. // Setup the hardware.
  2528. //LL32(grDRAWBLTDEF.DW, 0x101101CC);
  2529. //LL32(grOP_opBGCOLOR.DW, ColorKey);
  2530. // Initialize the error terms.
  2531. xError = ((cxSrc << 16) - 1) / cxDst + 1;
  2532. yError = ((cySrc << 16) - 1) / cyDst + 1;
  2533. // Y loop.
  2534. for (yRun = 0; cyDst--;)
  2535. {
  2536. int dst = xDst;
  2537. int src = xSrc;
  2538. int cx = cxDst;
  2539. // X loop.
  2540. for (xRun = 0; cx--;)
  2541. {
  2542. // Copy one pixel with color keying
  2543. //LL32(grOP0_opRDRAM.DW, MAKELONG(dst, yDst));
  2544. //LL32(grOP1_opRDRAM.DW, MAKELONG(src, ySrc));
  2545. //LL32(grOP2_opRDRAM.DW, MAKELONG(src, ySrc));
  2546. //LL32(grBLTEXT_EX.DW, MAKELONG(1, 1));
  2547. // this is bad but is needed for compatibility with display list
  2548. CALL_DRV_SRC_BLT(0x101101CC, // drawbltdef
  2549. MAKELONG(dst,yDst), // dst coord
  2550. MAKELONG(src,ySrc), // src coord
  2551. MAKELONG(src,ySrc), // colorkey coord
  2552. ColorKey, // colorkey
  2553. MAKELONG(1,1)); // extent
  2554. // Advance destination x.
  2555. dst++;
  2556. // Adjust x error term.
  2557. xRun += xError;
  2558. while (HIWORD(xRun))
  2559. {
  2560. // Advance source x.
  2561. src++;
  2562. xRun -= MAKELONG(0, 1);
  2563. }
  2564. }
  2565. // Advance destination y.
  2566. yDst++;
  2567. // Adjust y error term.
  2568. yRun += yError;
  2569. while (HIWORD(yRun))
  2570. {
  2571. // Advance source y.
  2572. ySrc++;
  2573. yRun -= MAKELONG(0, 1);
  2574. }
  2575. }
  2576. } /* StretchColor */
  2577. /***************************************************************************
  2578. *
  2579. * FUNCTION: TransparentStretch
  2580. *
  2581. * DESCRIPTION:
  2582. *
  2583. ****************************************************************************/
  2584. void TRANSPARENTSTRETCH
  2585. #ifndef WINNT_VER40
  2586. LPGLOBALDATA lpDDHALData,
  2587. #endif
  2588. int xDst, int yDst, int cxDst, int cyDst,
  2589. int xSrc, int ySrc, int cxSrc, int cySrc,
  2590. DWORD ColorKey)
  2591. {
  2592. const int nBytesPixel = BYTESPERPIXEL;
  2593. const int nSRAMPixels = (SRAM_SIZE / nBytesPixel) / 2;
  2594. const int nSRAMMask = nSRAMPixels - 1;
  2595. autoblt_regs SrcToScratch;
  2596. int xScratch, yScratch;
  2597. int cxScratch, cyScratch;
  2598. AXIS axis[2];
  2599. int nDst[2];
  2600. int nSrc[2];
  2601. int i;
  2602. DDAX accx;
  2603. int srcx;
  2604. int xext;
  2605. int cxTemp;
  2606. int xTemp;
  2607. #ifndef WINNT_VER40
  2608. ASSERT(cxDst >= cxSrc);
  2609. #endif
  2610. xScratch = LOWORD(lpDDHALData->ScratchBufferOrg);
  2611. yScratch = HIWORD(lpDDHALData->ScratchBufferOrg);
  2612. cxScratch = cxDst;
  2613. cyScratch = cyDst;
  2614. // initialize auto blt struct for src to scratch buffer
  2615. SrcToScratch.DRAWBLTDEF.DW = MAKELONG(ROP_OP1_copy, (BD_RES+BD_OP1)*IS_VRAM);
  2616. SrcToScratch.OP0_opRDRAM.DW = MAKELONG(LOWORD(xScratch),LOWORD(yScratch));
  2617. SrcToScratch.OP1_opRDRAM.DW = MAKELONG(LOWORD(xSrc),LOWORD(ySrc));
  2618. SrcToScratch.LNCNTL.W = lncntl[nBytesPixel-1] << LN_YUV_SHIFT;
  2619. SrcToScratch.SRCX = cxSrc * nBytesPixel;
  2620. #if ENABLE_INTERPOLATED_BLTS
  2621. // Enable interpolation unless we have a palette (8bpp)
  2622. if (1 < nBytesPixel)
  2623. SrcToScratch.LNCNTL.W |= (LN_XINTP_EN | LN_YINTP_EN);
  2624. #endif
  2625. SrcToScratch.SHRINKINC.W = 0x0000;
  2626. if (cxDst < cxSrc)
  2627. {
  2628. SrcToScratch.LNCNTL.W |= LN_XSHRINK;
  2629. SrcToScratch.LNCNTL.W &= ~LN_XINTP_EN;
  2630. SrcToScratch.SHRINKINC.pt.X = (cxSrc / cxDst);
  2631. }
  2632. if ( cyDst < cySrc )
  2633. {
  2634. SrcToScratch.LNCNTL.W |= LN_YSHRINK;
  2635. SrcToScratch.LNCNTL.W &= ~LN_YINTP_EN;
  2636. SrcToScratch.SHRINKINC.pt.Y = (cySrc / cyDst);
  2637. }
  2638. SrcToScratch.BLTEXT.DW = MAKELONG(LOWORD(cxScratch),1);
  2639. // Compute DDA terms
  2640. nDst[0] = cxScratch;
  2641. nDst[1] = cyScratch;
  2642. nSrc[0] = cxSrc;
  2643. nSrc[1] = cySrc;
  2644. for (i = 0; i < 2; i++)
  2645. {
  2646. int kDst = 1;
  2647. #if ENABLE_INTERPOLATED_BLTS
  2648. if (SrcToScratch.LNCNTL.W & ((i==0) ? LN_XINTP_EN : LN_YINTP_EN))
  2649. {
  2650. nDst[i] *= 4;
  2651. nSrc[i] *= 4;
  2652. nSrc[i] -= 3;
  2653. kDst = 0x8000 / nDst[i];
  2654. }
  2655. #endif
  2656. if (SrcToScratch.LNCNTL.W & ((i==0) ? LN_XSHRINK : LN_YSHRINK))
  2657. { /* Shrink Terms */
  2658. axis[i].maj = (short)nDst[i];
  2659. axis[i].min = - (nSrc[i] % nDst[i]);
  2660. axis[i].accum = axis[i].maj - 1
  2661. - ((nSrc[i] % nDst[i]) / (nSrc[i]/nDst[i] + 1));
  2662. }
  2663. else
  2664. { /* Stretch Terms */
  2665. axis[i].maj = kDst * nDst[i];
  2666. axis[i].min = -kDst * nSrc[i];
  2667. axis[i].accum = axis[i].maj - 1
  2668. - ((axis[i].maj % -axis[i].min) / (nDst[i]/nSrc[i] + 1));
  2669. }
  2670. }
  2671. SrcToScratch.MAJ_X = axis[0].maj;
  2672. SrcToScratch.MIN_X = axis[0].min;
  2673. SrcToScratch.ACCUM_X = axis[0].accum;
  2674. SrcToScratch.MAJ_Y = axis[1].maj;
  2675. SrcToScratch.MIN_Y = axis[1].min;
  2676. SrcToScratch.ACCUM_Y = axis[1].accum;
  2677. // loop over scanlines in dst
  2678. // do two blts for each, one from src to scratch buffer
  2679. // then one from scratch buffer to dst
  2680. while (0 < cyDst)
  2681. {
  2682. // blt one scanline high from src to scratch buffer
  2683. // set values for initial stripe
  2684. xext = nSRAMPixels;
  2685. accx = SrcToScratch.ACCUM_X;
  2686. srcx = xSrc;
  2687. // write settings that don't vary over stripes to the chip
  2688. CALL_DRV_STR_BLTY(&SrcToScratch);
  2689. cxTemp = cxScratch;
  2690. xTemp = xScratch;
  2691. while (cxTemp > xext)
  2692. {
  2693. // update auto blt struct settings
  2694. SrcToScratch.OP0_opRDRAM.pt.X = (USHORT)xTemp;
  2695. SrcToScratch.OP1_opRDRAM.pt.X = (USHORT)srcx;
  2696. SrcToScratch.BLTEXT.pt.X = (USHORT)xext;
  2697. // blt current stripe
  2698. CALL_DRV_STR_BLTX(&SrcToScratch);
  2699. // increment xDst and decrement remaining dst extent
  2700. xTemp += xext;
  2701. cxTemp -= xext;
  2702. // walk DDA to compute error term (accx) and xSrc for next stripe
  2703. for (i = 0; i < xext; i++)
  2704. {
  2705. SrcToScratch.ACCUM_X += SrcToScratch.MIN_X;
  2706. if (0 > (short)SrcToScratch.ACCUM_X)
  2707. {
  2708. SrcToScratch.ACCUM_X += SrcToScratch.MAJ_X;
  2709. srcx++;
  2710. }
  2711. }
  2712. }
  2713. // if there's some area left to blt, then do it
  2714. if (0 < cxTemp)
  2715. {
  2716. // update auto blt struct settings
  2717. SrcToScratch.OP0_opRDRAM.pt.X = (USHORT)xTemp;
  2718. SrcToScratch.OP1_opRDRAM.pt.X = (USHORT)srcx;
  2719. SrcToScratch.BLTEXT.pt.X = (USHORT)cxTemp;
  2720. // blt final stripe
  2721. CALL_DRV_STR_BLTX(&SrcToScratch);
  2722. }
  2723. // reset ACCUM_X for beginning of next scanline
  2724. SrcToScratch.ACCUM_X = accx;
  2725. // walk Y DDA for src to scratch buffer blt
  2726. SrcToScratch.ACCUM_Y += SrcToScratch.MIN_Y;
  2727. SrcToScratch.OP1_opRDRAM.pt.Y += SrcToScratch.SHRINKINC.pt.Y;
  2728. if (0 > (short)SrcToScratch.ACCUM_Y)
  2729. {
  2730. SrcToScratch.ACCUM_Y += SrcToScratch.MAJ_Y;
  2731. SrcToScratch.OP1_opRDRAM.pt.Y++;
  2732. }
  2733. // blt from scratch buffer to dst
  2734. // 1:1 in X, 1:1 in Y, uses colorkey
  2735. CALL_DRV_SRC_BLT(MAKELONG((DD_TRANS | ROP_OP1_copy),
  2736. ((BD_RES+BD_OP1+BD_OP2)*IS_VRAM)),
  2737. MAKELONG(xDst,yDst),
  2738. MAKELONG(xScratch,yScratch),
  2739. MAKELONG(xScratch,yScratch),
  2740. ColorKey,
  2741. MAKELONG(cxDst,1));
  2742. yDst++;
  2743. cyDst--;
  2744. }
  2745. }
  2746. /****************************************************************************
  2747. * FUNCTION NAME: DdBlt (NT) or Blt32 (Win95)
  2748. *
  2749. * DESCRIPTION:
  2750. ****************************************************************************/
  2751. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  2752. #ifdef WINNT_VER40 // WINNT_VER40
  2753. DWORD DdBlt(PDD_BLTDATA pbd)
  2754. {
  2755. DRIVERDATA* lpDDHALData;
  2756. PDEV* ppdev;
  2757. PVGAR pREG;
  2758. #else // ----- #elseif WINNT_VER40 -----
  2759. DWORD __stdcall Blt32(LPDDHAL_BLTDATA pbd)
  2760. {
  2761. LPGLOBALDATA lpDDHALData = GetDDHALContext( pbd->lpDD);
  2762. #endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
  2763. HRESULT ddrval;
  2764. DWORD dwFlags;
  2765. DWORD dwDstCoord;
  2766. DWORD dwDstWidth;
  2767. DWORD dwDstHeight;
  2768. DWORD dwSrcCoord;
  2769. DWORD dwSrcWidth;
  2770. DWORD dwSrcHeight;
  2771. int BaseOffset;
  2772. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  2773. #ifdef WINNT_VER40 // WINNT_VER40
  2774. PDD_SURFACE_LOCAL dstx;
  2775. PDD_SURFACE_LOCAL srcx;
  2776. PDD_SURFACE_GLOBAL dst;
  2777. PDD_SURFACE_GLOBAL src;
  2778. DISPDBG((DBGLVL, "DDraw - DdBlt\n"));
  2779. ppdev = (PDEV*) pbd->lpDD->dhpdev;
  2780. lpDDHALData = (DRIVERDATA*) &ppdev->DriverData;
  2781. pREG = (PVGAR) lpDDHALData->RegsAddress;
  2782. #else // ----- #elseif WINNT_VER40 -----
  2783. LPDDRAWI_DDRAWSURFACE_LCL dstx;
  2784. LPDDRAWI_DDRAWSURFACE_LCL srcx;
  2785. LPDDRAWI_DDRAWSURFACE_GBL dst;
  2786. LPDDRAWI_DDRAWSURFACE_GBL src;
  2787. #endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
  2788. DD_LOG(("Blt32 Entry\r\n"));
  2789. #ifdef WINNT_VER40
  2790. SYNC_W_3D(ppdev); // if 3D context(s) active, make sure 3D engine idle before continuing...
  2791. #endif
  2792. // NOTES:
  2793. // Everything you need is in lpBlt->bltFX .
  2794. // Look at lpBlt->dwFlags to determine what kind of blt you are doing,
  2795. // DDBLT_xxxx are the flags.
  2796. //
  2797. // COLORKEY NOTES:
  2798. // ColorKey ALWAYS comes in BLTFX. You don't have to look it up in
  2799. // the surface.
  2800. #ifdef WINNT_VER40 // WINNT_VER40
  2801. #else // ----- #elseif WINNT_VER40 -----
  2802. // if direct draw is NOT using display list, it must sync here
  2803. // updateFlipStatus may access the hardware!
  2804. if (!lpDDHALData->DisplayListDDraw && ((lpDDHALData->DrvSemaphore & DRVSEM_3D_BUSY) || (lpDDHALData->DrvSemaphore & DRVSEM_DISPLAY_LIST)))
  2805. {
  2806. qmRequestDirectAccess();
  2807. }
  2808. #endif // WINNT_VER40
  2809. // is a flip in progress?
  2810. #ifdef WINNT_VER40
  2811. ddrval = vUpdateFlipStatus(
  2812. &ppdev->flipRecord,
  2813. pbd->lpDDDestSurface->lpGbl->fpVidMem);
  2814. #else
  2815. #if defined(DDRAW_COMPAT_10)
  2816. ddrval = pfnUpdateFlipStatus(
  2817. pbd->lpDDDestSurface->lpData->fpVidMem
  2818. lpDDHALData);
  2819. #else
  2820. ddrval = pfnUpdateFlipStatus(
  2821. pbd->lpDDDestSurface->lpGbl->fpVidMem,
  2822. lpDDHALData);
  2823. #endif
  2824. #endif
  2825. if (ddrval != DD_OK)
  2826. {
  2827. pbd->ddRVal = ddrval;
  2828. DD_LOG(("Blt32 Exit - flip in progress, returning %08lX\r\n", ddrval));
  2829. return (DDHAL_DRIVER_HANDLED);
  2830. }
  2831. #ifndef WINNT_VER40
  2832. // if the destination surface of this blt is a texture
  2833. if (DDSCAPS_TEXTURE & pbd->lpDDDestSurface->ddsCaps.dwCaps)
  2834. {
  2835. LP_SURFACE_DATA lpSurfaceData;
  2836. lpSurfaceData = (LP_SURFACE_DATA)(pbd->lpDDDestSurface->dwReserved1);
  2837. // if the texture is a non-agp host texture (i.e. pci memory)
  2838. if (lpSurfaceData->dwFlags & SURF_HOST_BASED_TEXTURE)
  2839. {
  2840. // punt the blt to direct draw hel
  2841. pbd->ddRVal = DDERR_UNSUPPORTED;
  2842. return DDHAL_DRIVER_NOTHANDLED;
  2843. }
  2844. }
  2845. // if the source surface of this blt is non-null and is a texture
  2846. if ((NULL != pbd->lpDDSrcSurface) &&
  2847. (DDSCAPS_TEXTURE & pbd->lpDDSrcSurface->ddsCaps.dwCaps))
  2848. {
  2849. LP_SURFACE_DATA lpSurfaceData;
  2850. lpSurfaceData = (LP_SURFACE_DATA)(pbd->lpDDSrcSurface->dwReserved1);
  2851. // if the texture is a non-agp host texture (i.e. pci memory)
  2852. if (lpSurfaceData->dwFlags & SURF_HOST_BASED_TEXTURE)
  2853. {
  2854. // punt the blt to direct draw hel
  2855. pbd->ddRVal = DDERR_UNSUPPORTED;
  2856. return DDHAL_DRIVER_NOTHANDLED;
  2857. }
  2858. }
  2859. #endif
  2860. // If async, then only work if blter isn't busy.
  2861. // This should probably be a little more specific to each call !!!
  2862. dwFlags = pbd->dwFlags;
  2863. //#if 0
  2864. // if( dwFlags & DDBLT_ASYNC )
  2865. // {
  2866. // if( !ENOUGH_FIFO_FOR_BLT )
  2867. // {
  2868. //#if 0 // diagnostics for ASYNC BLT lockup
  2869. // DWORD dwROP = pbd->bltFX.dwROP;
  2870. // WORD rop = (WORD) LOBYTE( HIWORD( dwROP ) );
  2871. // PVGAR pREG = (PVGAR) lpDDHALData->RegsAddress;
  2872. // DBG_MESSAGE(("Status = %02x QFREE = %2d", pREG->grSTATUS, pREG->grQFREE));
  2873. // dstx = pbd->lpDDDestSurface;
  2874. // dst = dstx->lpData;
  2875. // dwDstCoord = cvlxy( dst->fpVidMem - lpDDHALData->ScreenAddress, BYTESPERPIXEL );
  2876. // dwDstCoord += MAKELONG( pbd->rDest.left, pbd->rDest.top );
  2877. // dwDstWidth = pbd->rDest.right - pbd->rDest.left;
  2878. // dwDstHeight = pbd->rDest.bottom - pbd->rDest.top;
  2879. // srcx = pbd->lpDDSrcSurface;
  2880. // src = srcx->lpData;
  2881. // dwSrcCoord = cvlxy( src->fpVidMem - lpDDHALData->ScreenAddress, BYTESPERPIXEL );
  2882. // dwSrcCoord += MAKELONG( pbd->rSrc.left, pbd->rSrc.top );
  2883. // dwSrcWidth = pbd->rSrc.right - pbd->rSrc.left;
  2884. // dwSrcHeight = pbd->rSrc.bottom - pbd->rSrc.top;
  2885. //
  2886. // DBG_MESSAGE(("Failed Blt32: Blt from %08X %dx%d -> %08X %dx%d rop %X",
  2887. // dwSrcCoord, dwSrcWidth, dwSrcHeight,
  2888. // dwDstCoord, dwDstWidth, dwDstHeight,
  2889. // rop));
  2890. //#endif
  2891. // DBG_MESSAGE(("ASYNC FAILED"));
  2892. // pbd->ddRVal = DDERR_WASSTILLDRAWING;
  2893. // return DDHAL_DRIVER_HANDLED;
  2894. // }
  2895. // }
  2896. //#endif
  2897. // get offset, width, and height for destination
  2898. dstx = pbd->lpDDDestSurface;
  2899. #if DDRAW_COMPAT == 10
  2900. dst = dstx->lpData;
  2901. #else
  2902. dst = dstx->lpGbl;
  2903. #endif
  2904. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  2905. #ifdef WINNT_VER40 // WINNT_VER40
  2906. dwDstCoord = cvlxy(ppdev->lDeltaScreen,
  2907. dst->fpVidMem,
  2908. BYTESPERPIXEL);
  2909. #else // ----- #elseif WINNT_VER40 -----
  2910. dwDstCoord = cvlxy( lpDDHALData,dst->fpVidMem - lpDDHALData->ScreenAddress, BYTESPERPIXEL );
  2911. #endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
  2912. dwDstCoord += MAKELONG(pbd->rDest.left, pbd->rDest.top);
  2913. dwDstWidth = pbd->rDest.right - pbd->rDest.left;
  2914. dwDstHeight = pbd->rDest.bottom - pbd->rDest.top;
  2915. /* Check for a zero extent stretchblt */
  2916. if ((dwDstWidth == 0) || (dwDstHeight == 0))
  2917. {
  2918. pbd->ddRVal = DD_OK;
  2919. return (DDHAL_DRIVER_HANDLED);
  2920. }
  2921. // If someone is running a full-screen exclusive app it is the
  2922. // responsibility of the app to take care of the cursor. We don't
  2923. // call BeginAccess or EndAccess for them.
  2924. //
  2925. // However, if someone is running a windowed app and they have
  2926. // attached a clipper object to the destination surface then they
  2927. // are more like a normal windows app and we call BeginAccess and
  2928. // EndAccess for them around a blt. That is the only circumstance
  2929. // where we currently do cursor exclusion.
  2930. //
  2931. // We do intend to add calls to BeginAccess and EndAccess around
  2932. // a rectangle lock of the primary surface. In this case, we
  2933. // would only do cursor exclusion if a lock rect is specified.
  2934. // This will be implemented with DirectDraw 2.0.
  2935. //
  2936. // I believe that you should not do automatic cursor exclusion in
  2937. // the driver because you will penalize all blts and locks.
  2938. // Grab the hardware - disable HW cursor updates.
  2939. LOCK_HW_SEMAPHORE();
  2940. // Decipher the flags.
  2941. if (dwFlags & DDBLT_ROP)
  2942. {
  2943. static const WORD mix2blt[] =
  2944. { // all ops color vram
  2945. BD_RES ,
  2946. BD_RES | BD_OP0 | BD_OP1,
  2947. BD_RES | BD_OP0 | BD_OP1,
  2948. BD_RES | BD_OP1,
  2949. BD_RES | BD_OP0 | BD_OP1,
  2950. BD_RES | BD_OP0 ,
  2951. BD_RES | BD_OP0 | BD_OP1,
  2952. BD_RES | BD_OP0 | BD_OP1,
  2953. BD_RES | BD_OP0 | BD_OP1,
  2954. BD_RES | BD_OP0 | BD_OP1,
  2955. BD_RES | BD_OP0 ,
  2956. BD_RES | BD_OP0 | BD_OP1,
  2957. BD_RES | BD_OP1,
  2958. BD_RES | BD_OP0 | BD_OP1,
  2959. BD_RES | BD_OP0 | BD_OP1,
  2960. BD_RES
  2961. }; // all ops color vram
  2962. DWORD dwROP = pbd->bltFX.dwROP;
  2963. WORD rop = (WORD) LOBYTE( HIWORD( dwROP ) );
  2964. WORD mix = rop & 0x0f;
  2965. WORD bdf = mix2blt[mix];
  2966. if (bdf & BD_OP1) // SRC rops
  2967. {
  2968. srcx = pbd->lpDDSrcSurface;
  2969. #if DDRAW_COMPAT == 10
  2970. src = srcx->lpData;
  2971. #else
  2972. src = srcx->lpGbl;
  2973. #endif
  2974. #ifdef WINNT_VER40 // YUV movement code
  2975. #else
  2976. if ((srcx->dwFlags & DDRAWISURF_HASPIXELFORMAT) &&
  2977. (src->ddpfSurface.dwFlags & DDPF_FOURCC) &&
  2978. (lpDDHALData->DrvSemaphore & DRVSEM_YUV_MOVED) )
  2979. {
  2980. BOOL fMoved = FALSE;
  2981. RECT rYUV;
  2982. LONG lDeltaX, lDeltaY, Scale;
  2983. LONG SrcWidth, SrcHeight, DstWidth, DstHeight;
  2984. SrcWidth = src->wWidth;
  2985. SrcHeight = src->wHeight;
  2986. if (lpDDHALData->DrvSemaphore & DRVSEM_YUV_RECT_VALID)
  2987. {
  2988. rYUV.left = min(lpDDHALData->YUVLeft,
  2989. pbd->rDest.left);
  2990. rYUV.top = min(lpDDHALData->YUVTop,
  2991. pbd->rDest.top);
  2992. rYUV.right = max(lpDDHALData->YUVLeft + lpDDHALData->YUVXExt,
  2993. pbd->rDest.right);
  2994. rYUV.bottom = max(lpDDHALData->YUVTop + lpDDHALData->YUVYExt,
  2995. pbd->rDest.bottom);
  2996. DstWidth = rYUV.right - rYUV.left;
  2997. DstHeight = rYUV.bottom - rYUV.top;
  2998. if (pbd->rDest.left > rYUV.left)
  2999. {
  3000. // YUV has moved to left.
  3001. lDeltaX = pbd->rDest.left - rYUV.left;
  3002. Scale = (SrcWidth - pbd->rSrc.right) * DstWidth / SrcWidth;
  3003. lDeltaX = min(lDeltaX, Scale);
  3004. pbd->rSrc.right += lDeltaX * SrcWidth / DstWidth;
  3005. pbd->rDest.left -= lDeltaX;
  3006. fMoved = TRUE;
  3007. }
  3008. if (pbd->rSrc.left > 0)
  3009. {
  3010. // YUV has moved to right.
  3011. lDeltaX = rYUV.right - pbd->rDest.right;
  3012. Scale = pbd->rSrc.left * DstWidth / SrcWidth;
  3013. lDeltaX = min(lDeltaX, Scale);
  3014. pbd->rSrc.left -= lDeltaX * SrcWidth / DstWidth;
  3015. pbd->rDest.right += lDeltaX;
  3016. fMoved = TRUE;
  3017. }
  3018. if (pbd->rDest.top > rYUV.top)
  3019. {
  3020. // YUV has moved up.
  3021. lDeltaY = pbd->rDest.top - rYUV.top;
  3022. Scale = (SrcHeight - pbd->rSrc.bottom) * DstHeight / SrcHeight;
  3023. lDeltaY = min(lDeltaY, Scale);
  3024. pbd->rSrc.bottom += lDeltaY * SrcHeight / DstHeight;
  3025. pbd->rDest.top -= lDeltaY;
  3026. fMoved = TRUE;
  3027. }
  3028. if (pbd->rSrc.top > 0)
  3029. {
  3030. // YUV has moved down.
  3031. lDeltaY = rYUV.bottom - pbd->rDest.bottom;
  3032. Scale = pbd->rSrc.top * DstHeight / SrcHeight;
  3033. lDeltaY = min(lDeltaY, Scale);
  3034. pbd->rSrc.top -= lDeltaY * SrcHeight / DstHeight;
  3035. pbd->rDest.bottom += lDeltaY;
  3036. fMoved = TRUE;
  3037. }
  3038. }
  3039. if (fMoved)
  3040. {
  3041. // Recalculate the destination parameters since they might have
  3042. // changed.
  3043. dwDstCoord = cvlxy(lpDDHALData,dst->fpVidMem - lpDDHALData->ScreenAddress,
  3044. BYTESPERPIXEL);
  3045. dwDstCoord += MAKELONG(pbd->rDest.left, pbd->rDest.top);
  3046. dwDstWidth = pbd->rDest.right - pbd->rDest.left;
  3047. dwDstHeight = pbd->rDest.bottom - pbd->rDest.top;
  3048. }
  3049. else
  3050. {
  3051. // Clear the YUV movement flag.
  3052. lpDDHALData->DrvSemaphore &= ~DRVSEM_YUV_MOVED;
  3053. }
  3054. }
  3055. #endif // YUV movement code
  3056. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  3057. #ifdef WINNT_VER40 // WINNT_VER40
  3058. dwSrcCoord = cvlxy(ppdev->lDeltaScreen,
  3059. src->fpVidMem,
  3060. BYTESPERPIXEL);
  3061. #else // ----- #elseif WINNT_VER40 -----
  3062. dwSrcCoord = cvlxy( lpDDHALData,src->fpVidMem - lpDDHALData->ScreenAddress, BYTESPERPIXEL );
  3063. #endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
  3064. dwSrcCoord += MAKELONG( pbd->rSrc.left, pbd->rSrc.top );
  3065. dwSrcWidth = pbd->rSrc.right - pbd->rSrc.left;
  3066. dwSrcHeight = pbd->rSrc.bottom - pbd->rSrc.top;
  3067. if (dwFlags & DDBLT_KEYSRCOVERRIDE) // Source Color Key
  3068. {
  3069. DWORD dwColor = CALL_DUP_COLOR(pbd->bltFX.ddckSrcColorkey.dwColorSpaceLowValue);
  3070. DD_LOG(("Src Color Key Blt\r\n"));
  3071. if ( (dwSrcWidth != dwDstWidth) || (dwSrcHeight != dwDstHeight) )
  3072. {
  3073. if ( !(srcx->dwFlags & DDRAWISURF_HASPIXELFORMAT) &&
  3074. (rop == 0x00CC) )
  3075. {
  3076. if (dwSrcWidth < dwDstWidth)
  3077. {
  3078. CALL_TRANSPARENTSTRETCH(LOWORD(dwDstCoord), HIWORD(dwDstCoord),
  3079. dwDstWidth, dwDstHeight,
  3080. LOWORD(dwSrcCoord), HIWORD(dwSrcCoord),
  3081. dwSrcWidth, dwSrcHeight,
  3082. dwColor);
  3083. goto blt_exit;
  3084. }
  3085. else
  3086. {
  3087. CALL_STRETCHCOLOR(LOWORD(dwDstCoord), HIWORD(dwDstCoord),
  3088. dwDstWidth, dwDstHeight,
  3089. LOWORD(dwSrcCoord), HIWORD(dwSrcCoord),
  3090. dwSrcWidth, dwSrcHeight,
  3091. dwColor);
  3092. goto blt_exit;
  3093. }
  3094. }
  3095. else
  3096. {
  3097. DD_LOG(("Unsupported SrcColorKey Blt -> punt\r\n"));
  3098. ddrval = DDERR_UNSUPPORTED;
  3099. goto blt_exit;
  3100. }
  3101. }
  3102. // // PATCOPY is faster if that's all we're doing.
  3103. // if (rop == 0xCC)
  3104. // {
  3105. // rop = 0xF0;
  3106. // bdf = BD_RES | BD_OP2;
  3107. // }
  3108. CALL_DRV_SRC_BLT(MAKELONG(rop|DD_TRANS, bdf | BD_OP2),
  3109. dwDstCoord,
  3110. dwSrcCoord,
  3111. dwSrcCoord, // Src transparency
  3112. dwColor, //
  3113. MAKELONG(dwDstWidth, dwDstHeight) );
  3114. } // (dwFlags & DDBLT_KEYSRCOVERRIDE) // Source Color Key
  3115. else if (dwFlags & DDBLT_KEYDESTOVERRIDE) // Destination Color Key
  3116. {
  3117. #if _WIN32_WINNT >= 0x500
  3118. // For some reason on NT 5.0 ddckDestColorkey does not work,
  3119. // but ddckSrcColorkey does...
  3120. DWORD dwColor = CALL_DUP_COLOR(pbd->bltFX.ddckSrcColorkey.dwColorSpaceLowValue);
  3121. #else
  3122. DWORD dwColor = CALL_DUP_COLOR(pbd->bltFX.ddckDestColorkey.dwColorSpaceLowValue);
  3123. #endif
  3124. DD_LOG(("Dst Color Key Blt\r\n"));
  3125. // Punt if stretch or shrink requested.
  3126. if ((dwSrcWidth != dwDstWidth) || (dwSrcHeight != dwDstHeight))
  3127. {
  3128. DD_LOG(("Unsupported DstColorKey Blt -> punt\r\n"));
  3129. ddrval = DDERR_UNSUPPORTED;
  3130. goto blt_exit;
  3131. }
  3132. CALL_DRV_SRC_BLT(MAKELONG(rop|DD_TRANS|DD_TRANSOP, bdf | BD_OP2),
  3133. dwDstCoord,
  3134. dwSrcCoord,
  3135. dwDstCoord, // Dst transparency
  3136. dwColor, //
  3137. MAKELONG(dwDstWidth, dwDstHeight) );
  3138. } // (dwFlags & DDBLT_KEYDESTOVERRIDE) // Destination Color Key
  3139. else
  3140. {
  3141. #ifdef TRACE_STRETCH
  3142. DBG_MESSAGE(("Blt32: Blt from %08X %dx%d -> %08X %dx%d rop %X",
  3143. dwSrcCoord, dwSrcWidth, dwSrcHeight,
  3144. dwDstCoord, dwDstWidth, dwDstHeight,
  3145. rop));
  3146. #endif
  3147. #ifdef TRACE_STRETCH
  3148. DBG_MESSAGE(("Blt32: BaseOffset %08X %08X",
  3149. src->fpVidMem - lpDDHALData->ScreenAddress, PITCH));
  3150. DBG_MESSAGE(("Blt32: src->w %04d %04d (%04x)",
  3151. src->wWidth, src->wHeight,
  3152. (src->fpVidMem - lpDDHALData->ScreenAddress) / PITCH ));
  3153. #endif
  3154. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  3155. #ifdef WINNT_VER40 // WINNT_VER40
  3156. BaseOffset = src->fpVidMem % ppdev->lDeltaScreen;
  3157. #else // ----- #elseif WINNT_VER40 -----
  3158. BaseOffset = (src->fpVidMem - lpDDHALData->ScreenAddress) % PITCH;
  3159. #endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
  3160. if ((dwSrcWidth != dwDstWidth) || (dwSrcHeight != dwDstHeight) ||
  3161. (srcx->dwFlags & DDRAWISURF_HASPIXELFORMAT))
  3162. {
  3163. int nBytesPixel = BYTESPERPIXEL;
  3164. int SrcType = lncntl[nBytesPixel - 1];
  3165. int SrcSize = nBytesPixel;
  3166. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  3167. #ifdef WINNT_VER40 // WINNT_VER40
  3168. int ySrcAddr = src->fpVidMem / ppdev->lDeltaScreen;
  3169. #else // ----- #elseif WINNT_VER40 -----
  3170. int ySrcAddr = (src->fpVidMem - lpDDHALData->ScreenAddress) / PITCH;
  3171. #endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
  3172. // Punt if 32bpp. The '62 and '64 don't do 32bpp stretches at all...
  3173. // KENTL - 10/4/96
  3174. if (nBytesPixel == 4)
  3175. {
  3176. DD_LOG(("Unsupported 32bpp resize blt -> punt\r\n"));
  3177. ddrval = DDERR_UNSUPPORTED;
  3178. goto blt_exit;
  3179. }
  3180. // Punt if not SRCCPY.
  3181. if (rop != 0x00CC)
  3182. {
  3183. DD_LOG(("Unsupport rop in resize blt -> punt\r\n"));
  3184. ddrval = DDERR_UNSUPPORTED;
  3185. goto blt_exit;
  3186. }
  3187. // This should only be RGB565 in 8Bit FB or YUV422 in 8 or 16.
  3188. if ( srcx->dwFlags & DDRAWISURF_HASPIXELFORMAT )
  3189. {
  3190. if ( src->ddpfSurface.dwFlags & DDPF_FOURCC )
  3191. SrcType = LN_YUV422;
  3192. else
  3193. SrcType = LN_RGB565;
  3194. SrcSize = 2;
  3195. }
  3196. if (LGDEVID == CL_GD5464)
  3197. {
  3198. if ( ! lpDDHALData->EdgeTrim )
  3199. lpDDHALData->EdgeTrim = 15; // Assign minimum trim percentage
  3200. if ((SrcType == LN_YUV422))
  3201. {
  3202. // Check for 5464 shrink workaround
  3203. if ((dwDstWidth * nBytesPixel) <=
  3204. ((dwSrcWidth * SrcSize) * (100 - lpDDHALData->EdgeTrim)/100))
  3205. {
  3206. DWORD dwTDst_X;
  3207. int iratio;
  3208. int ratio_1, ratio_2;
  3209. unsigned int excess;
  3210. if ( nBytesPixel == 1 )
  3211. dwSrcWidth *= SrcSize;
  3212. iratio = dwSrcWidth / dwDstWidth;
  3213. excess = dwSrcWidth % dwDstWidth;
  3214. ratio_1 = iratio;
  3215. // get power of 2 greater than current number
  3216. ratio_2 = 1;
  3217. do
  3218. {
  3219. ratio_2 <<= 1;
  3220. } while ( ratio_1 >>= 1 );
  3221. // Check for special cases of ratio already a perfect
  3222. // power of 2 or could be trimmed to a power of two.
  3223. if ((!excess || ((100 * excess) <= (dwSrcWidth * (100 - lpDDHALData->EdgeTrim)/100)))
  3224. && ( (ratio_2 / iratio) == 2 ) )
  3225. ratio_2 >>= 1;
  3226. if ( nBytesPixel == 1 )
  3227. { // Mixed mode frame buffer so adjust coords / sizes
  3228. // to match
  3229. //#if 0
  3230. // if ( !( OFFSCR_YUV_VAR.ratio == ratio_2 ) )
  3231. // {
  3232. // OFFSCR_YUV_VAR.ratio = ratio_2;
  3233. //
  3234. // ratio_2 /= 2;
  3235. //
  3236. // // Perform offscreen shrink to adjacent src buffer
  3237. // CALL_DRVSTRETCH64(
  3238. // OFFSCR_YUV_VAR.SrcRect.right * SrcSize,
  3239. // OFFSCR_YUV_VAR.SrcRect.top,
  3240. // (OFFSCR_YUV_VAR.SrcRect.right - OFFSCR_YUV_VAR.SrcRect.left)/ratio_2,
  3241. // OFFSCR_YUV_VAR.SrcRect.bottom - OFFSCR_YUV_VAR.SrcRect.top,
  3242. // OFFSCR_YUV_VAR.SrcRect.left,
  3243. // OFFSCR_YUV_VAR.SrcRect.top,
  3244. // OFFSCR_YUV_VAR.SrcRect.right - OFFSCR_YUV_VAR.SrcRect.left,
  3245. // OFFSCR_YUV_VAR.SrcRect.bottom - OFFSCR_YUV_VAR.SrcRect.top,
  3246. // nBytesPixel,
  3247. // SrcType,
  3248. // BaseOffset,
  3249. // FALSE);
  3250. //
  3251. // ratio_2 *= 2;
  3252. // } // endif ( !( offscr_YUV.ratio == ratio_2 ) )
  3253. //
  3254. // // Perform stretch from adjacent src buffer to
  3255. // // onscreen dst
  3256. // dwTDst_X = LOWORD(dwSrcCoord) +
  3257. // (OFFSCR_YUV_VAR.SrcRect.right - OFFSCR_YUV_VAR.SrcRect.left) *
  3258. // SrcSize;
  3259. //#else
  3260. if (!( src->dwReserved1 == (DWORD)ratio_2))
  3261. {
  3262. src->dwReserved1 = ratio_2;
  3263. ratio_2 /= 2;
  3264. DD_LOG(("YUV shrink to extra buffer (8bpp)\r\n"));
  3265. // Perform offscreen shrink to adjacent src buffer
  3266. CALL_DRVSTRETCH64(
  3267. BaseOffset+(src->wWidth * SrcSize), // X Address of DST buffer
  3268. ySrcAddr, // Y Address of DST buffer
  3269. src->wWidth / ratio_2, // Width in PIXELS of DST
  3270. src->wHeight, // Height
  3271. BaseOffset, // X Address of SRC buffer
  3272. ySrcAddr, // Y Address of SRC buffer
  3273. src->wWidth, // Width in PIXELS of SRC
  3274. src->wHeight, // Height
  3275. nBytesPixel,
  3276. SrcType,
  3277. BaseOffset,
  3278. FALSE);
  3279. ratio_2 *= 2;
  3280. }
  3281. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  3282. #ifdef WINNT_VER40 // WINNT_VER40
  3283. // Perform stretch from adjacent src buffer to onscreen dst
  3284. dwTDst_X = LOWORD(dwSrcCoord) / ratio_2 + (src->wWidth * SrcSize);
  3285. #else // ----- #elseif WINNT_VER40 -----
  3286. // Perform stretch from adjacent src buffer to onscreen dst
  3287. // Russ/Kent 10/4/96 - This fails for unknown reasons as code. The alternate coding
  3288. // seems to work better. Fixes PDR#6799
  3289. // dwTDst_X = LOWORD(dwSrcCoord) / ratio_2 + (src->wWidth * SrcSize);
  3290. dwTDst_X = BaseOffset + (LOWORD(dwSrcCoord) - BaseOffset)/ratio_2 + (src->wWidth*SrcSize);
  3291. #endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
  3292. //#endif
  3293. // dwTDst_X /= SrcSize; // Modify src X address
  3294. dwSrcWidth /= SrcSize;
  3295. DD_LOG(("YUV stretch from extra buffer (8bpp)\r\n"));
  3296. CALL_DRVSTRETCH64(
  3297. LOWORD(dwDstCoord),
  3298. HIWORD(dwDstCoord),
  3299. dwDstWidth,
  3300. dwDstHeight,
  3301. dwTDst_X,
  3302. HIWORD(dwSrcCoord),
  3303. dwSrcWidth / ratio_2,
  3304. dwSrcHeight,
  3305. nBytesPixel,
  3306. SrcType,
  3307. BaseOffset + (src->wWidth * SrcSize),
  3308. TRUE);
  3309. } // if ( nBytesPixel == 1 )
  3310. else
  3311. {
  3312. //#if 0
  3313. // if (!( OFFSCR_YUV_VAR.ratio == ratio_2))
  3314. // {
  3315. // OFFSCR_YUV_VAR.ratio = ratio_2;
  3316. //
  3317. // CALL_DRVSTRETCH64(
  3318. // lpDDHALData,
  3319. // OFFSCR_YUV_VAR.SrcRect.right,
  3320. // OFFSCR_YUV_VAR.SrcRect.top,
  3321. // (OFFSCR_YUV_VAR.SrcRect.right - OFFSCR_YUV_VAR.SrcRect.left)/ratio_2,
  3322. // OFFSCR_YUV_VAR.SrcRect.bottom - OFFSCR_YUV_VAR.SrcRect.top,
  3323. // OFFSCR_YUV_VAR.SrcRect.left,
  3324. // OFFSCR_YUV_VAR.SrcRect.top,
  3325. // OFFSCR_YUV_VAR.SrcRect.right - OFFSCR_YUV_VAR.SrcRect.left,
  3326. // OFFSCR_YUV_VAR.SrcRect.bottom - OFFSCR_YUV_VAR.SrcRect.top,
  3327. // nBytesPixel, SrcType, BaseOffset,
  3328. // FALSE);
  3329. //
  3330. // }; // endif (!(offscr_YUV.ratio == ratio_2))
  3331. //
  3332. // // Perform stretch from adjacent src buffer to onscreen dst
  3333. // dwTDst_X = (LOWORD(dwSrcCoord) / ratio_2) +
  3334. // (OFFSCR_YUV_VAR.SrcRect.right - OFFSCR_YUV_VAR.SrcRect.left);
  3335. //
  3336. //#else
  3337. if ( !( src->dwReserved1 == (DWORD)ratio_2 ) )
  3338. {
  3339. src->dwReserved1 = ratio_2;
  3340. DD_LOG(("YUV shrink to extra buffer (16bpp)\r\n"));
  3341. // Perform offscreen shrink to adjacent src buffer
  3342. CALL_DRVSTRETCH64(
  3343. BaseOffset + (src->wWidth) , // X Address of DST buffer
  3344. ySrcAddr, // Y Address of DST buffer
  3345. src->wWidth / ratio_2, // Width in PIXELS of DST
  3346. src->wHeight, // Height
  3347. BaseOffset, // X Address of SRC buffer
  3348. ySrcAddr, // Y Address of SRC buffer
  3349. src->wWidth, // Width in PIXELS of SRC
  3350. src->wHeight, // Height
  3351. nBytesPixel,
  3352. SrcType,
  3353. BaseOffset,
  3354. FALSE);
  3355. }
  3356. // Perform stretch from adjacent src buffer to onscreen dst
  3357. dwTDst_X = (LOWORD(dwSrcCoord) - BaseOffset) / ratio_2 + BaseOffset + (src->wWidth);
  3358. //#endif
  3359. DD_LOG(("YUV stretch from extra buffer (16bpp)\r\n"));
  3360. CALL_DRVSTRETCH64(
  3361. LOWORD(dwDstCoord),
  3362. HIWORD(dwDstCoord),
  3363. dwDstWidth,
  3364. dwDstHeight,
  3365. dwTDst_X,
  3366. HIWORD(dwSrcCoord),
  3367. dwSrcWidth / ratio_2,
  3368. dwSrcHeight,
  3369. nBytesPixel,
  3370. SrcType,
  3371. BaseOffset,
  3372. TRUE);
  3373. } // endif ( nBytesPixel == 1 )
  3374. }
  3375. else
  3376. {
  3377. DD_LOG(("YUV stretch\r\n"));
  3378. CALL_DRVSTRETCH64(
  3379. LOWORD(dwDstCoord),
  3380. HIWORD(dwDstCoord),
  3381. dwDstWidth,
  3382. dwDstHeight,
  3383. LOWORD(dwSrcCoord),
  3384. HIWORD(dwSrcCoord),
  3385. dwSrcWidth,
  3386. dwSrcHeight,
  3387. nBytesPixel,
  3388. SrcType,
  3389. BaseOffset,
  3390. TRUE);
  3391. }
  3392. } // if ((SrcType == LN_YUV422))
  3393. else
  3394. {
  3395. DD_LOG(("RGB resize blt\r\n"));
  3396. // handle shrinks & stretches
  3397. if ((2 == nBytesPixel) && (dwSrcWidth > dwDstWidth))
  3398. {
  3399. // handles 16bpp RGB shrinks
  3400. CALL_RGB_16SHRINKBOF64(LOWORD(dwDstCoord), HIWORD(dwDstCoord),
  3401. dwDstWidth, dwDstHeight,
  3402. LOWORD(dwSrcCoord), HIWORD(dwSrcCoord),
  3403. dwSrcWidth, dwSrcHeight);
  3404. }
  3405. else
  3406. {
  3407. // handles 16bpp RGB stretches, 8bpp stretches & 8bpp shrinks
  3408. CALL_RGB_RESIZEBOF64(LOWORD(dwDstCoord), HIWORD(dwDstCoord),
  3409. dwDstWidth, dwDstHeight,
  3410. LOWORD(dwSrcCoord), HIWORD(dwSrcCoord),
  3411. dwSrcWidth, dwSrcHeight);
  3412. }
  3413. } // endif ((SrcType == LN_YUV422))
  3414. } // if (LGDEVID == CL_GD5464)
  3415. else
  3416. {
  3417. DD_LOG(("calling DrvStretch62\r\n"));
  3418. CALL_DRVSTRETCH62(
  3419. LOWORD(dwDstCoord),
  3420. HIWORD(dwDstCoord),
  3421. dwDstWidth,
  3422. dwDstHeight,
  3423. LOWORD(dwSrcCoord),
  3424. HIWORD(dwSrcCoord),
  3425. dwSrcWidth,
  3426. dwSrcHeight,
  3427. nBytesPixel,
  3428. SrcType,
  3429. BaseOffset,
  3430. TRUE);
  3431. } // endif (LGDEVID == CL_GD5464)
  3432. }
  3433. else
  3434. {
  3435. DD_LOG(("1:1 two operand blt\r\n"));
  3436. CALL_DRV_SRC_BLT(MAKELONG(rop, bdf),
  3437. dwDstCoord,
  3438. dwSrcCoord,
  3439. 0UL, // don't care
  3440. 0UL, //
  3441. MAKELONG(dwDstWidth, dwDstHeight));
  3442. }
  3443. } // endif (dwFlags & DDBLT_KEYSRCOVERRIDE) // Source Color Key
  3444. }
  3445. else // DST ONLY rops
  3446. {
  3447. DD_LOG(("Dst Only Blt\r\n"));
  3448. CALL_DRV_DST_BLT(MAKELONG(rop, bdf),
  3449. dwDstCoord,
  3450. 0UL, // don't care
  3451. MAKELONG(dwDstWidth, dwDstHeight) );
  3452. } // endif (bdf & BD_OP1) // SRC rops
  3453. } // (dwFlags & DDBLT_ROP)
  3454. else if (dwFlags & DDBLT_COLORFILL)
  3455. {
  3456. DWORD dwColor = CALL_DUP_COLOR(pbd->bltFX.dwFillColor);
  3457. DD_LOG(("Solid Color Fill\r\n"));
  3458. CALL_DRV_DST_BLT(MAKELONG(0x00CC, BD_RES | (BD_OP1 * IS_SOLID)),
  3459. dwDstCoord,
  3460. dwColor, // fill color
  3461. MAKELONG(dwDstWidth, dwDstHeight));
  3462. }
  3463. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  3464. #ifndef WINNT_VER40 // Not WINNT_VER40
  3465. else if (bD3DInit && dwFlags & DDBLT_DEPTHFILL)
  3466. {
  3467. //JGO changed for Laguna3D integration
  3468. DWORD dwFillDepth = CALL_DUPZFILL(pbd->bltFX.dwFillDepth,
  3469. dstx->lpGbl->ddpfSurface.dwZBufferBitDepth);
  3470. DD_LOG(("Depth Fill Blt\r\n"));
  3471. // convert to byte blt
  3472. // 16 bit zbuffer in 32 bit frame buffer trashes everything to right
  3473. // of zbuffer
  3474. // Fixes PDR #9152
  3475. ((PT *)(&dwDstCoord))->X *= (WORD)(dst->ddpfSurface.dwZBufferBitDepth / 8);
  3476. dwDstWidth *= (dst->ddpfSurface.dwZBufferBitDepth / 8);
  3477. CALL_DRV_DST_MBLT(MAKELONG(0x00CC, BD_RES | (BD_OP1 * IS_SOLID)),
  3478. dwDstCoord,
  3479. dwFillDepth,
  3480. MAKELONG(dwDstWidth, dwDstHeight));
  3481. }
  3482. #endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
  3483. else
  3484. {
  3485. DD_LOG(("Unsupported blt - dwFlags = %08lX\r\n", dwFlags));
  3486. ddrval = DDERR_UNSUPPORTED;
  3487. goto blt_exit;
  3488. } // endif (dwFlags & DDBLT_ROP)
  3489. blt_exit:
  3490. // Release the hardware - enable HW cursor updates.
  3491. UNLOCK_HW_SEMAPHORE();
  3492. if (ddrval != DD_OK)
  3493. return DDHAL_DRIVER_NOTHANDLED;
  3494. pbd->ddRVal = DD_OK;
  3495. DD_LOG(("Blt32 Exit\r\n"));
  3496. return DDHAL_DRIVER_HANDLED;
  3497. } /* DdBlt */
  3498. /***************************************************************************
  3499. *
  3500. * FUNCTION: BltInit
  3501. *
  3502. * DESCRIPTION:
  3503. *
  3504. ****************************************************************************/
  3505. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  3506. #ifdef WINNT_VER40 // WINNT_VER40
  3507. void BltInit (PDEV* ppdev, BOOL bEnableDisplayListBlts )
  3508. #else // ----- #elseif WINNT_VER40-----
  3509. void BltInit ( BOOL bEnableDisplayListBlts ,LPGLOBALDATA lpDDHALData)
  3510. #endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
  3511. {
  3512. if ((CL_GD5462 == LGDEVID) || (FALSE == bEnableDisplayListBlts))
  3513. {
  3514. #ifdef WINNT_VER40
  3515. ppdev->pfnDelay9BitBlt = DIR_Delay9BitBlt;
  3516. ppdev->pfnEdgeFillBlt = DIR_EdgeFillBlt;
  3517. ppdev->pfnMEdgeFillBlt = DIR_MEdgeFillBlt;
  3518. ppdev->pfnDrvDstBlt = DIR_DrvDstBlt;
  3519. ppdev->pfnDrvDstMBlt = DIR_DrvDstMBlt;
  3520. ppdev->pfnDrvSrcBlt = DIR_DrvSrcBlt;
  3521. ppdev->pfnDrvSrcMBlt = DIR_DrvSrcMBlt;
  3522. ppdev->pfnDrvStrBlt = DIR_DrvStrBlt;
  3523. ppdev->pfnDrvStrMBlt = DIR_DrvStrMBlt;
  3524. ppdev->pfnDrvStrMBltY = DIR_DrvStrMBltY;
  3525. ppdev->pfnDrvStrMBltX = DIR_DrvStrMBltX;
  3526. ppdev->pfnDrvStrBltY = DIR_DrvStrBltY;
  3527. ppdev->pfnDrvStrBltX = DIR_DrvStrBltX;
  3528. #else
  3529. pfnDelay9BitBlt = DIR_Delay9BitBlt;
  3530. pfnEdgeFillBlt = DIR_EdgeFillBlt;
  3531. pfnMEdgeFillBlt = DIR_MEdgeFillBlt;
  3532. pfnDrvDstBlt = DIR_DrvDstBlt;
  3533. pfnDrvDstMBlt = DIR_DrvDstMBlt;
  3534. pfnDrvSrcBlt = DIR_DrvSrcBlt;
  3535. pfnDrvSrcMBlt = DIR_DrvSrcMBlt;
  3536. if (REVID_PRE65 & lpDDHALData->bRevInfoBits)
  3537. pfnDrvStrBlt = DIR_DrvStrBlt;
  3538. else
  3539. pfnDrvStrBlt = DIR_DrvStrBlt65;
  3540. pfnDrvStrMBlt = DIR_DrvStrMBlt;
  3541. pfnDrvStrMBltY = DIR_DrvStrMBltY;
  3542. pfnDrvStrMBltX = DIR_DrvStrMBltX;
  3543. pfnDrvStrBltY = DIR_DrvStrBltY;
  3544. pfnDrvStrBltX = DIR_DrvStrBltX;
  3545. #if ENABLE_CLIPPEDBLTS
  3546. if (! (REVID_PRE65 & lpDDHALData->bRevInfoBits))
  3547. {
  3548. if (CL_GD5465 == LGDEVID)
  3549. {
  3550. pfnClippedDrvDstBlt = DIR_SWClippedDrvDstBlt;
  3551. pfnClippedDrvDstMBlt = DIR_SWClippedDrvDstMBlt;
  3552. pfnClippedDrvSrcBlt = DIR_SWClippedDrvSrcBlt;
  3553. }
  3554. else
  3555. {
  3556. pfnClippedDrvDstBlt = DIR_HWClippedDrvDstBlt;
  3557. pfnClippedDrvDstMBlt = DIR_HWClippedDrvDstMBlt;
  3558. pfnClippedDrvSrcBlt = DIR_HWClippedDrvSrcBlt;
  3559. }
  3560. }
  3561. #endif
  3562. #endif
  3563. }
  3564. else
  3565. {
  3566. #ifdef WINNT_VER40
  3567. ppdev->pfnDelay9BitBlt = DL_Delay9BitBlt;
  3568. ppdev->pfnEdgeFillBlt = DL_EdgeFillBlt;
  3569. ppdev->pfnMEdgeFillBlt = DL_MEdgeFillBlt;
  3570. ppdev->pfnDrvDstBlt = DL_DrvDstBlt;
  3571. ppdev->pfnDrvDstMBlt = DL_DrvDstMBlt;
  3572. ppdev->pfnDrvSrcBlt = DL_DrvSrcBlt;
  3573. ppdev->pfnDrvSrcMBlt = DL_DrvSrcMBlt;
  3574. ppdev->pfnDrvStrBlt = DL_DrvStrBlt;
  3575. ppdev->pfnDrvStrMBlt = DL_DrvStrMBlt;
  3576. ppdev->pfnDrvStrMBltY = DL_DrvStrMBltY;
  3577. ppdev->pfnDrvStrMBltX = DL_DrvStrMBltX;
  3578. ppdev->pfnDrvStrBltY = DL_DrvStrBltY;
  3579. ppdev->pfnDrvStrBltX = DL_DrvStrBltX;
  3580. #else
  3581. pfnDelay9BitBlt = DL_Delay9BitBlt;
  3582. pfnEdgeFillBlt = DL_EdgeFillBlt;
  3583. pfnMEdgeFillBlt = DL_MEdgeFillBlt;
  3584. pfnDrvDstBlt = DL_DrvDstBlt;
  3585. pfnDrvDstMBlt = DL_DrvDstMBlt;
  3586. pfnDrvSrcBlt = DL_DrvSrcBlt;
  3587. pfnDrvSrcMBlt = DL_DrvSrcMBlt;
  3588. if (REVID_PRE65 & lpDDHALData->bRevInfoBits)
  3589. pfnDrvStrBlt = DL_DrvStrBlt;
  3590. else
  3591. pfnDrvStrBlt = DL_DrvStrBlt65;
  3592. pfnDrvStrMBlt = DL_DrvStrMBlt;
  3593. pfnDrvStrMBltY = DL_DrvStrMBltY;
  3594. pfnDrvStrMBltX = DL_DrvStrMBltX;
  3595. pfnDrvStrBltY = DL_DrvStrBltY;
  3596. pfnDrvStrBltX = DL_DrvStrBltX;
  3597. #if ENABLE_CLIPPEDBLTS
  3598. if (! (REVID_PRE65 & lpDDHALData->bRevInfoBits))
  3599. {
  3600. if (CL_GD5465 == LGDEVID)
  3601. {
  3602. pfnClippedDrvDstBlt = DL_SWClippedDrvDstBlt;
  3603. pfnClippedDrvDstMBlt = DL_SWClippedDrvDstMBlt;
  3604. pfnClippedDrvSrcBlt = DL_SWClippedDrvSrcBlt;
  3605. }
  3606. else
  3607. {
  3608. pfnClippedDrvDstBlt = DL_HWClippedDrvDstBlt;
  3609. pfnClippedDrvDstMBlt = DL_HWClippedDrvDstMBlt;
  3610. pfnClippedDrvSrcBlt = DL_HWClippedDrvSrcBlt;
  3611. }
  3612. }
  3613. #endif
  3614. #endif
  3615. }
  3616. }
  3617. #endif // WINNT_VER35