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.

4313 lines
134 KiB

  1. /**************************************************************************
  2. ***************************************************************************
  3. *
  4. * Copyright (c) 1997, Cirrus Logic, Inc.
  5. * All Rights Reserved
  6. *
  7. * FILE: 5465over.c
  8. *
  9. * DESCRIPTION:
  10. *
  11. * REVISION HISTORY:
  12. *
  13. * $Log: \\uinac\log\log\laguna\ddraw\src\5465over.c $
  14. *
  15. * Rev 1.75 19 May 1998 09:54:36 xcong
  16. * Assign GfVdFormat in ChipIOReadBWRegs() for TV-Out support.
  17. *
  18. * Rev 1.74 07 Apr 1998 17:28:58 xcong
  19. * Get CR1 and CR1E in ChipIOBWRead()
  20. *
  21. * Rev 1.73 Mar 30 1998 13:06:52 frido
  22. * Changed some parenthesis so the Codewright source parser can find the
  23. * functions.
  24. *
  25. * Rev 1.72 08 Jan 1998 10:45:28 xcong
  26. * Don't pass lpDDHALData in ComputeVWPositionData() for NT.
  27. *
  28. * Rev 1.71 07 Jan 1998 17:55:32 xcong
  29. * Delete *lpDDHALData in SetPostion() for NT only.
  30. * 
  31. *
  32. * Rev 1.70 06 Jan 1998 14:43:54 xcong
  33. * Pass lpDDHALData in CurrentVLine().
  34. *
  35. * Rev 1.69 06 Jan 1998 11:42:06 xcong
  36. * Change pDriverData into local lpDDHALData for multi-monitor support.
  37. *
  38. * Rev 1.68 Dec 11 1997 14:03:28 frido
  39. * PDR#11011: A workaround has been added to convert a "dummy"
  40. * update into a SHOW update when certain criteria are met.
  41. *
  42. * Rev 1.67 Dec 10 1997 13:41:32 frido
  43. * Merged from 1.62 branch.
  44. *
  45. * Rev 1.63.2.0 Dec 03 1997 14:44:54 frido
  46. * PDR#11017. The hardware is broken when shrinking videos horizontally with
  47. * RGB32 format. A software workaround has been added to disable overlay in
  48. * this case.
  49. *
  50. * Rev 1.66 Dec 10 1997 13:32:08 frido
  51. * Merged from 1.62 branch.
  52. *
  53. * Rev 1.65 14 Nov 1997 13:04:18 XCONG
  54. * Undo the modification for dwOverlayOffset for NT.
  55. *
  56. * Rev 1.64 06 Nov 1997 15:46:14 XCONG
  57. * When update dwOverlayOffset, update this variable for all the attached surf
  58. * too.
  59. *
  60. * Rev 1.63.2.0 Dec 03 1997 14:44:54 frido
  61. * PDR#11017. The hardware is broken when shrinking videos horizontally with
  62. * RGB32 format. A software workaround has been added to disable overlay in
  63. * this case.
  64. *
  65. * Rev 1.63 04 Nov 1997 13:41:34 RUSSL
  66. * Fix for PDR #10815
  67. *
  68. * Rev 1.62 04 Nov 1997 12:57:02 RUSSL
  69. * Removed forcing of min stretch in 24bpp to start at 1000 (for new bweq code)
  70. *
  71. * Rev 1.61 30 Oct 1997 14:34:18 RUSSL
  72. * Mods to support new interface to bweqn code
  73. * Moved KillOverlay function here from 5465bw.c
  74. * ChipIOReadBWRegs reads additional regs that are new to the BWREGS struct
  75. * Added code in ChipIOReadBWRegs to clear bits 4 & 7 (the 256 byte fetch
  76. * related bits) of the BWREGS Control2 value. The bweqn should use
  77. * 256 byte fetch off values, since we are disabling 256 byte fetch
  78. * when overlay or videoport surfaces are created.
  79. *
  80. * Rev 1.60 08 Oct 1997 11:15:02 RUSSL
  81. * Fix for NT40 build without overlay support
  82. *
  83. * Rev 1.59 25 Sep 1997 17:33:40 RUSSL
  84. * Modified HeapAlloc calls to use HEAP_ALLOC macro
  85. * and HeapFree calls to use HEAP_FREE macro
  86. *
  87. * Rev 1.58 19 Sep 1997 14:35:04 bennyn
  88. * Fixed NT4.0 5462/64 build problem
  89. *
  90. * Rev 1.57 17 Sep 1997 16:27:20 RUSSL
  91. * Looks like setting the HardwareOwner is FlipOverlayStatus is an NT only
  92. * thing.
  93. *
  94. * Rev 1.56 16 Sep 1997 15:28:38 bennyn
  95. * Modified for NT DD overlay
  96. *
  97. * Rev 1.55 04 Sep 1997 09:43:26 RUSSL
  98. * Fixed up Xing's changes so they compile for NT
  99. *
  100. * Rev 1.54 04 Sep 1997 10:07:52 XCONG
  101. * Delete f256Fetch, since the code to disable 256 byte fetch is moved to
  102. * surface.c, nobody use this variable anymore.
  103. *
  104. * Rev 1.53 03 Sep 1997 18:40:12 XCONG
  105. * Disable overlay in 640*480*32 at 85Hz by calling KillOverlay().
  106. * This is temporary fix for PDR#10381.
  107. *
  108. * Rev 1.52 03 Sep 1997 16:35:02 RUSSL
  109. *
  110. * Rev 1.51 02 Sep 1997 12:35:48 RUSSL
  111. * Added GET_SURFACE_DATA_PTR macro and modified relevant code to get ptr
  112. * using macro. This will minimize the remaining changes needed for NT.
  113. *
  114. * Rev 1.50 29 Aug 1997 16:47:26 RUSSL
  115. * Added support for NT
  116. * It's not quite complete, we need to allocate a LP_SURFACE_DATA structure
  117. * for each overlay surface and store it somewhere in the DD_SURFACE_LOCAL
  118. * structure (this needs to be done by CreateSurface). And then add code
  119. * in here to get access to that struct when necessary. #pragma message's
  120. * indicate where.
  121. * Removed code to disable 256 byte fetch, its done by CreateSurface32
  122. *
  123. * Rev 1.49 15 Aug 1997 16:38:30 XCONG
  124. * Put overlay source alignment back to 1. This is screen alignment instead o
  125. *
  126. * Rev 1.48 14 Aug 1997 16:47:42 XCONG
  127. * If overlay window is created, disable 256 byte fetch.
  128. * Move gwNormalDTTR initialization into CreateSurface function.
  129. *
  130. * Rev 1.47 29 Jul 1997 15:29:14 XCONG
  131. * For autoflip overlay make sure dwNumAutoFlip == 2
  132. *
  133. * Rev 1.46 28 Jul 1997 09:19:46 RUSSL
  134. * Modified GetOverlayFlipStatus to check arm bit in hw rather than determine
  135. * elapsed time since previous flip
  136. * Added video window index argument to GetOverlayFlipStatus function
  137. * Made dwNumVideoWindows a global var rather than static
  138. * Moved GetVideoWindowIndex inline function to overlay.h
  139. *
  140. * Rev 1.45 24 Jul 1997 17:50:14 RUSSL
  141. * modified src alignment values reported in ddhalinfo
  142. * fixed error with disabling dst colorkey at 24bpp, I was turning off
  143. * src colorkey related caps bits
  144. *
  145. * Rev 1.44 16 Jul 1997 17:15:32 XCONG
  146. * Add and use dwOverlayOffset and more in SURFACE_DATA structure in order
  147. * to eliminate global variables.
  148. *
  149. * Rev 1.43 14 Jul 1997 13:11:50 RUSSL
  150. * added ChipIOReadBWRegs (moved here from 5465bw.c)
  151. *
  152. * Rev 1.42 11 Jul 1997 11:57:26 XCONG
  153. * Fix ptich problem in FlipOverlay for interleaved surface.
  154. *
  155. * Rev 1.41 11 Jul 1997 08:57:02 RUSSL
  156. * Fixed y clipping of CLPL surfaces in FlipOverlaySurface and
  157. * ComputeVWPositionData
  158. *
  159. * Rev 1.40 09 Jul 1997 15:27:44 RUSSL
  160. * Implemented CLPL lobotomy mode
  161. * allocates a block of system memory for the app to write the UV data to,
  162. * when the app locks the surface the system memory addresses are returned
  163. * so the app writes to system memory, and when the app unlocks the surface,
  164. * the data is copied into the frame buffer. The copy is done from left to
  165. * right a scanline at a time. There appears to be a hw bug when writing
  166. * to aperture 3 from right to left. Roughly every other 4 dwords is
  167. * dropped. This bug showed up when allowing the Compcore MPEG player to
  168. * write directly to aperture 3. (also see comments in SysToFBCopy)
  169. * Added GetUserSettings to read user controllable options from registry
  170. * Current user controllable settings are:
  171. * OverlayBW - enables/disables use of bandwidth equation (default=enabled)
  172. * OverlayCLPL - enables/disables support for CLPL format (default=enabled)
  173. * OverlayCLPLLobotomyMode - enables/disables above described CLPL
  174. * lobotomy mode (default=enabled)
  175. * For forward compatibility, assume future chips have one video window
  176. *
  177. * Rev 1.39 30 Jun 1997 10:37:20 RUSSL
  178. * Added global var to control whether or not CLPL is supported
  179. * CLPL support is based on a registry key "OverlayCLPL", set to "on" to
  180. * enable CLPL, default is "off"
  181. *
  182. * Rev 1.38 23 Jun 1997 10:50:10 RUSSL
  183. * Modified for reduced size of CLPL surfaces
  184. *
  185. * Rev 1.37 20 Jun 1997 13:47:44 RUSSL
  186. * Enabled CLPL overlay surface support (aka YUV420 & YUVPLANAR)
  187. * Enabled 32 bit overlay surface support
  188. * Removed REQUIREs and HW_(UN)LOCK_SEMAPHOREs (they didn't do anything anyway)
  189. * CreateSurface now returns an HRESULT
  190. *
  191. * Rev 1.36 09 Jun 1997 13:46:22 XCONG
  192. * In FlipOverlaySurface(), Update VW_CONTROL0 too for DDFLIP_EVEN.
  193. *
  194. * Rev 1.35 03 Jun 1997 09:52:50 RUSSL
  195. * Added setting of VWEnable bit in CONTROL0 register in SetPosition and
  196. * FlipOverlaySurface functions
  197. *
  198. * Rev 1.34 22 May 1997 16:27:46 RUSSL
  199. * Disable overlay shrink at 24bpp
  200. *
  201. * Rev 1.33 15 May 1997 17:36:38 RUSSL
  202. * Set ddCaps.dwAlignStrideAlign to bytes per pixel in Init5465Overlay
  203. * Set bNoOverlayInThisMode to TRUE if in interlaced mode
  204. *
  205. * Rev 1.32 15 May 1997 15:48:20 XCONG
  206. * Change all the BWE flags back (in bw.h).
  207. *
  208. * Rev 1.31 15 May 1997 10:56:54 RUSSL
  209. * Changed IsFormatValid to return an HRESULT rather than a BOOL so
  210. * CanCreateSurface32 can return a reasonable error code if the surface
  211. * can't be created
  212. *
  213. * Rev 1.30 13 May 1997 09:53:04 RUSSL
  214. * Removed code in Init5465Info that was initializing the VW0_TEST0 register
  215. *
  216. * Rev 1.29 12 May 1997 17:22:32 XCONG
  217. * Change wVPortCreated in VideoPortEx into wNotify
  218. *
  219. * Rev 1.28 10 May 1997 12:51:02 EDWINW
  220. * Fix PDR 9574. DestroySurface trashes tile size when trying to restore the
  221. * DTTR's FIFO threshold.
  222. *
  223. * Rev 1.27 09 May 1997 16:26:36 XCONG
  224. * Only check VPE_ON and OVERLAY_ON flags in DX5
  225. *
  226. * Rev 1.26 09 May 1997 11:10:22 XCONG
  227. * Uses the flags in overlay.h for BWE flags. Befor save and restore
  228. * gwNormIDTTR check VPE is still running or not, because VPE will do the same
  229. * thing.
  230. *
  231. * Rev 1.25 08 May 1997 17:57:40 XCONG
  232. * Make the BWE variables global. Set uDispDepth as the same as
  233. * sourc depth instead of graphic depth.
  234. *
  235. * Rev 1.24 24 Apr 1997 14:36:46 XCONG
  236. * For SW playback only use smooth-interlaced mode when BOB and INTERLEAVE
  237. * flags are both set.
  238. *
  239. * Rev 1.23 24 Apr 1997 12:02:54 RUSSL
  240. * Reenabled writing 0x52 to TEST0 reg on 5465AC if bw eqn is in use.
  241. * 800x600x16 @ 85Hz looks like it's running on the hairy edge of
  242. * stability with this. All other modes (at all resolutions, colordepths
  243. * and refresh rates) with sufficient bandwidth to use overlay looked
  244. * stable although there is still some static in some modes.
  245. *
  246. * Rev 1.22 17 Apr 1997 09:38:22 RUSSL
  247. * Fix for PDR #9339, disable destination colorkeying support at 24bpp.
  248. * This looks like its a HWBUG. This code can be disabled by defining
  249. * HWBUG_24BPP_DST_COLORKEY as zero.
  250. * Write DTTR FIFO value returned by ChipIsEnoughBandwidth, original DTTR
  251. * setting is saved in a global var which is restored when final overlay
  252. * surface is destroyed
  253. *
  254. * Rev 1.21 16 Apr 1997 10:19:28 RUSSL
  255. * Had to update list of parms passed to GetBooleanSetting
  256. *
  257. * Rev 1.20 15 Apr 1997 17:46:46 RUSSL
  258. * Added use of PDC's bandwidth equation
  259. * Added use of registry key/system.ini entry to disable use of BWEqn
  260. * Removed IsSufficientBandwidth functions
  261. * Modified Init5465Info to determine min & max zoom factors in current
  262. * mode by calling BWEqn
  263. * ComputeVWFifoThreshold sets VW fifo threshold to value returned previously
  264. * by bandwidth equation (or it uses 8 if use of BWEqn is disabled)
  265. *
  266. * Rev 1.19 04 Apr 1997 16:11:56 XCONG
  267. * Add support for SW double-buffer and BOB palyback. Change the way to
  268. * calculate VACCUM_STP for interleaved BOB.
  269. *
  270. * Rev 1.18 03 Apr 1997 09:58:42 RUSSL
  271. * Disable writing 0x42 or 0x52 to TEST0 reg, it's more grief than it's worth
  272. * Wait until we get a real bandwidth equation
  273. * Made IsFormatValid always return FALSE when we're in an interlaced mode,
  274. * this essentially disables use of overlay in interlaced modes
  275. *
  276. * Rev 1.17 28 Mar 1997 14:57:26 RUSSL
  277. * Need to write 0x42 to TEST0 in 24bpp modes
  278. * Display driver now puts 32bit linear address of pDevice in
  279. * pDriverData->lpPDevice, so don't need to call MapSLFix
  280. *
  281. * Rev 1.16 24 Mar 1997 22:54:58 XCONG
  282. * Add auto-flip overlay support. Include SSD_STRT_ADDR in tagVWDATA for
  283. * all the version of DDRAW.
  284. *
  285. * Rev 1.15 24 Mar 1997 16:44:56 RUSSL
  286. * Changed CreateSurface so that CreateSurface32 fills in the blocksize, etc.
  287. *
  288. * Rev 1.14 24 Mar 1997 12:12:40 RUSSL
  289. * Added write of 0x52 to TEST0 reg on 5465AC, this enables some hw fixes
  290. *
  291. * Rev 1.13 19 Mar 1997 11:47:40 cjl
  292. * Simply added line to include new ddshared.h file.
  293. *
  294. * Rev 1.12 12 Mar 1997 14:59:00 RUSSL
  295. * replaced a block of includes with include of precomp.h for
  296. * precompiled headers
  297. * Removed unneeded pragma message related to mapping in YUY2 aperture
  298. *
  299. * Rev 1.11 07 Mar 1997 12:43:22 RUSSL
  300. * Modified DDRAW_COMPAT usage
  301. * Merged in PDC's VPE code for DX5
  302. * Made IsSufficientBandwidth5465 global rather than static
  303. *
  304. * Rev 1.10 24 Feb 1997 13:49:52 RUSSL
  305. * Enabled YUY2 format
  306. * Added RBGtoYCbCr function
  307. * Modified DetermineVWColorKeyData to handle source color keying of UYVY
  308. * and YUY2 surfaces
  309. *
  310. * Rev 1.9 14 Feb 1997 10:01:14 RUSSL
  311. * Added more conditional compilation flags to enable/disable horizontal
  312. * mirroring, use of REQUIRE for qfree checking and use of HW_IN_USE
  313. * driver semaphore.
  314. * If building debug version, change inline functions to not be inline.
  315. * WINICE can't deal with inline functions, so source code doesn't line
  316. * up correctly.
  317. * Added ASSERT to make sure post immediately bit is clear in TEST0 reg
  318. * before updating video window registers
  319. * Ignore DDOVER_DDFX flag in UpdateSurface because Microsoft's WHQL Overfly
  320. * test program sets this flag but fills overlayFX.dwDDFX with junk.
  321. * In some cases they set the DDOVERFX_MIRRORLEFTRIGHT bit even though
  322. * we don't even say we support that capability! In order to get Overfly
  323. * to work, we need to ignore the overlayFX.dwDDFX flags that we don't
  324. * support (which is currently all of them) This fixes BPR #8528
  325. *
  326. * Rev 1.8 04 Feb 1997 14:15:48 RUSSL
  327. * Added check in IsFormatValid to see if VPM is using the hardware
  328. * Added SaveRectangles to reduce duplicate code in UpdateSurface
  329. * Adjusted zoom code calculation for x shrink so don't go past end of src
  330. *
  331. * Rev 1.7 31 Jan 1997 08:59:30 RUSSL
  332. * Added better video window support checking based on chip id in
  333. * Init5465Overlay
  334. * Adjusted init code alignment requirements reported to ddraw
  335. * Addressed most of pragma message statements
  336. * Fixed bug in FlipOverlaySurface when surface is clipped
  337. * Enabled overlay shrink caps and added shrink zoom code calculations
  338. *
  339. * Rev 1.6 29 Jan 1997 18:00:30 RUSSL
  340. * Added use of require macro before register writes
  341. * Modified zoom code calculations
  342. *
  343. * Rev 1.5 28 Jan 1997 17:34:58 RUSSL
  344. * VEND is the last line shown by the overlay
  345. * Karl and I figured out how to make source color key work (at least at 16bpp)
  346. * hopefully the code matches what we did manually. We need an app
  347. * that uses source color keying to really test it.
  348. *
  349. * Rev 1.4 28 Jan 1997 15:29:42 RUSSL
  350. * destination color keying is actually done using the hardware CLRKEY
  351. * registers and setting OCCLUDE in CONTROL0 to 1 (the documentation
  352. * appears to have the source color key settings & the destination color
  353. * key settings swapped)
  354. * source color keying doesn't appear to work
  355. *
  356. * Rev 1.3 27 Jan 1997 19:10:26 RUSSL
  357. * Use a variable dwNumVideoWindows rather than a hardcoded define
  358. * Added WaitForArmToClear, Set5465FlipDuration & PanOverlay1_Init
  359. * Made IsFormatValid return TRUE only for UYVY overlay surfaces for now
  360. * Made CreateSurface use rectangular allocation, specify block size for
  361. * rgb surfaces if we are managing surface creation, let CreateSurface
  362. * return NOTHANDLED so DDraw will fill in the surface ptr
  363. * Added error checking for dwReserved1 of local surface struct in case
  364. * it's NULL
  365. * Added additional debug output
  366. * Put code in ComputeVWZoomCodes, ComputeVWPosData, DetermineColorKeyData,
  367. * ComputeVWFifoThreshold
  368. * Added programming of the hw registers in RegInitVideoVW & RegMoveVideoVW
  369. *
  370. * Rev 1.2 21 Jan 1997 15:44:40 RUSSL
  371. * Okay this didn't compile and link last time
  372. *
  373. * Rev 1.1 21 Jan 1997 14:55:14 RUSSL
  374. * Port of 5480 overlay code from CirrusMM driver to 5465
  375. *
  376. * Rev 1.0 15 Jan 1997 10:36:22 RUSSL
  377. * Initial revision.
  378. *
  379. ***************************************************************************
  380. ***************************************************************************/
  381. /***************************************************************************
  382. * I N C L U D E S
  383. ****************************************************************************/
  384. #include "precomp.h"
  385. #if defined WINNT_VER35 // WINNT_VER35
  386. // If WinNT 3.5 skip all the source code
  387. #elif defined (NTDRIVER_546x)
  388. // If WinNT 4.0 and 5462/64 build skip all the source code
  389. #elif defined(WINNT_VER40) && !defined(OVERLAY)
  390. // if nt40 without overlay, skip all the source code
  391. #else
  392. #ifndef WINNT_VER40
  393. #include "ddshared.h"
  394. #include "flip.h"
  395. #include "surface.h"
  396. #include "blt.h"
  397. #include "overlay.h"
  398. #if DDRAW_COMPAT >= 50
  399. #include "vp.h"
  400. #endif
  401. #include "settings.h"
  402. #include "5465bw.h"
  403. #include "swat.inc"
  404. #endif
  405. /***************************************************************************
  406. * D E F I N E S
  407. ****************************************************************************/
  408. #ifdef WINNT_VER40
  409. #define ENABLE_YUY2 0
  410. #define ENABLE_YUVPLANAR 0
  411. #define DISABLE_MOST_MODES 0
  412. #else
  413. #define ENABLE_YUY2 1
  414. #define ENABLE_YUVPLANAR 1
  415. #define DISABLE_MOST_MODES 0
  416. #endif
  417. #define ENABLE_SD_RGB32 1
  418. #define ENABLE_MIRRORING 0
  419. #define HWBUG_24BPP_DST_COLORKEY 1
  420. #ifdef DEBUG
  421. #define INLINE
  422. #else
  423. #define INLINE __inline
  424. #endif
  425. // VW_CAP0 bits
  426. #define VWCAP_VW_PRESENT 0x00000001
  427. // VW_CONTROL1 bits
  428. #define VW_ByPassClrSpc 0x00000002
  429. #define VW_YShrinkEn 0x00000001
  430. // VW_CONTROL0 bits
  431. #define VW_XShrinkBy2 0x80000000
  432. #define VW_ClkMode2x 0x40000000
  433. #define VW_FIFO_THRSH_EN 0x20000000
  434. #define VW_ALPHA_KEYCMP_EN 0x10000000
  435. #define VW_DB_VPORT_ID_MASK 0x0F000000
  436. #define VW_DB_VSM_ID_MASK 0x00F00000
  437. #define VW_DB_CTL_MASK 0x000F0000
  438. #define VW_SD_FRMT_MASK 0x0000FF00
  439. #define VW_OCCLUDE_MASK 0x000000F0
  440. #define VW_SMTH_INT 0x00000008
  441. #define VW_HMIRR_EN 0x00000004
  442. #define VW_VWE 0x00000002
  443. #define VW_ARM 0x00000001
  444. // Source Data Formats for SD_FRMT
  445. #define SD_YUV422 0x00 // ITU 601 compliant YUV data
  446. #define SD_YUV420 0x03 // ITU 601 compliant YUV data
  447. #define SD_YUV422_FS 0x04 // Full Scale YUV data
  448. #define SD_YVU420_FS 0x07 // Full Scale YUV data
  449. #define SD_RGB16_555 0x08 // 5:5:5
  450. #define SD_RGB16_565 0x09 // 5:6:5
  451. #define SD_RGB32 0x0B // ARGB
  452. #define SD_FRMT_SHIFT 8
  453. // Occlude types for OCCLUDE
  454. #define NO_OCCLUSION 0 // video window always displayed
  455. #define COLOR_KEY 1 // destination color keying
  456. #define CHROMA_KEY 2 // source color keying
  457. #define OCCLUDE_SHIFT 4
  458. // VW_TEST0 bits
  459. #define VW_PostImed 1
  460. #define VWVRepEnable 0x4
  461. // defines used in Init5465Info()
  462. #define SRC_WIDTH 160
  463. #define SRC_HEIGHT 120
  464. #define MAX_ZOOM 8000
  465. #define MIN_ZOOM 500
  466. #define ZOOM_STEP 100
  467. #ifdef WINNT_VER40
  468. #define lpDDHALData ((DRIVERDATA *)(&(ppdev->DriverData)))
  469. #define ASSERT(x)
  470. #define DRAW_ENGINE_BUSY DrawEngineBusy(lpDDHALData)
  471. #endif
  472. #ifdef WINNT_VER40
  473. #define GET_SURFACE_DATA_PTR(lpSurface) (LP_SURFACE_DATA)((lpSurface)->dwReserved1)
  474. #else
  475. #define GET_SURFACE_DATA_PTR(lpSurface) (LP_SURFACE_DATA)((lpSurface)->dwReserved1)
  476. #endif
  477. #if ENABLE_256_BYTE_FETCH
  478. // bit defs for PERFORMANCE register
  479. #define ECO_256_BYTES_FIX_EN 0x4000
  480. // bit defs for CONTROL2 register
  481. #define MONO_SAFETY_256 0x0080
  482. #define BYTE_REQ_256 0x0010
  483. #endif
  484. /***************************************************************************
  485. * T Y P E D E F S
  486. ****************************************************************************/
  487. typedef struct tagVWDATA
  488. {
  489. WORD HSTRT;
  490. WORD HSDSZ;
  491. WORD HEND;
  492. DWORD HACCUM_STP;
  493. DWORD HACCUM_SD;
  494. WORD VSTRT;
  495. WORD VEND;
  496. DWORD VACCUM_STP;
  497. DWORD VACCUM_SDA;
  498. DWORD VACCUM_SDB;
  499. DWORD PSD_STRT_ADDR;
  500. DWORD SSD_STRT_ADDR;
  501. #if ENABLE_YUVPLANAR
  502. DWORD PSD_UVSTRT_ADDR;
  503. DWORD SSD_UVSTRT_ADDR;
  504. #endif
  505. WORD SD_PITCH;
  506. DWORD CLRKEY_MIN;
  507. DWORD CLRKEY_MAX;
  508. DWORD CHRMKEY_MIN;
  509. DWORD CHRMKEY_MAX;
  510. // WORD BRIGHT_ADJ;
  511. // BYTE Z_ORDER;
  512. WORD FIFO_THRSH;
  513. DWORD CONTROL1;
  514. DWORD CONTROL0;
  515. // DWORD CAP1;
  516. // DWORD CAP0;
  517. // DWORD TEST0;
  518. } VWDATA;
  519. typedef struct tagUSERSETTINGS
  520. {
  521. BOOL *pVar;
  522. char *pRegKey;
  523. BOOL defaultVal;
  524. } USERSETTINGS;
  525. #if ENABLE_YUVPLANAR
  526. // structure for CLPL (YUV planar) surface
  527. typedef struct tagCLPLInfo
  528. {
  529. LPVOID fpYSurface; // Y data in first aperture
  530. LPVOID fpUSurface; // U data in 0-2M of fourth aperture
  531. LPVOID fpVSurface; // V data in 2-4M of fourth aperture
  532. // pointers for CLPLLobotomyMode
  533. LPVOID fpUSystemSurface;
  534. LPVOID fpVSystemSurface;
  535. LPVOID fpRealUSurface; // U data in 0-2M of fourth aperture
  536. LPVOID fpRealVSurface; // V data in 2-4M of fourth aperture
  537. } CLPLInfo;
  538. typedef CLPLInfo *LPCLPLSURFACE;
  539. #endif
  540. /***************************************************************************
  541. * E X T E R N A L V A R I A B L E S
  542. ****************************************************************************/
  543. #ifndef WINNT_VER40
  544. #if DDRAW_COMPAT >= 50
  545. extern WORD gwNotify; //#xc
  546. #endif
  547. #endif
  548. /***************************************************************************
  549. * S T A T I C V A R I A B L E S
  550. ****************************************************************************/
  551. #ifdef WINNT_VER40
  552. // For NT these are in ppdev->DriverData
  553. #define bUseBWEqn ppdev->DriverData.bUseBWEqn
  554. #define bNoOverlayInThisMode ppdev->DriverData.bNoOverlayInThisMode
  555. #define lpHardwareOwner ppdev->DriverData.lpHardwareOwner
  556. #define lpColorSurfaceVW ppdev->DriverData.lpColorSurfaceVW
  557. #define lpSrcColorSurfaceVW ppdev->DriverData.lpSrcColorSurfaceVW
  558. #define grOverlaySrc ppdev->DriverData.grOverlaySrc
  559. #define grOverlayDest ppdev->DriverData.grOverlayDest
  560. #define gdwFourccVW ppdev->DriverData.gdwFourccVW
  561. #if ENABLE_MIRRORING
  562. #define bIsVWMirrored ppdev->DriverData.bIsVWMirrored
  563. #endif
  564. #define gdwAvailVW ppdev->DriverData.gdwAvailVW // Next available video window
  565. //#define gwZOrder ppdev->DriverData.gwZOrder // default primary on top.
  566. #define gdwColorKey ppdev->DriverData.gdwColorKey
  567. #define gdwSrcColorKeyLow ppdev->DriverData.gdwSrcColorKeyLow
  568. #define gdwSrcColorKeyHigh ppdev->DriverData.gdwSrcColorKeyHigh
  569. #define gdwDestColorKeyOwnerVW ppdev->DriverData.gdwDestColorKeyOwnerVW // DstColorKey owner (NULL or FLG_VWX)
  570. #define gdwSrcColorKeyOwnerVW ppdev->DriverData.gdwSrcColorKeyOwnerVW // SrcColorKey owner (NULL or FLG_VWX)
  571. #define giOvlyCnt ppdev->DriverData.giOvlyCnt
  572. #if ENABLE_YUVPLANAR // YUV Planar surfaces cannot exist
  573. #define giPlanarCnt ppdev->DriverData.giPlanarCnt // with other overlay surfaces
  574. #define bCLPLLobotomyMode ppdev->DriverData.bCLPLLobotomyMode
  575. #endif
  576. //#define gbDoubleClock ppdev->DriverData.gbDoubleClock
  577. #if DISABLE_MOST_MODES
  578. #define bDisableMostModes ppdev->DriverData.bDisableMostModes
  579. #endif
  580. #else // Win95
  581. ASSERTFILE("5465over.c");
  582. STATIC DIBENGINE *pPDevice;
  583. STATIC BOOL bUseBWEqn;
  584. STATIC BOOL bNoOverlayInThisMode;
  585. STATIC LPDDRAWI_DDRAWSURFACE_LCL lpHardwareOwner[MAX_VIDEO_WINDOWS];
  586. STATIC LPDDRAWI_DDRAWSURFACE_LCL lpColorSurfaceVW[MAX_VIDEO_WINDOWS];
  587. STATIC LPDDRAWI_DDRAWSURFACE_LCL lpSrcColorSurfaceVW[MAX_VIDEO_WINDOWS];
  588. STATIC RECTL grOverlaySrc[MAX_VIDEO_WINDOWS];
  589. STATIC RECTL grOverlayDest[MAX_VIDEO_WINDOWS];
  590. STATIC DWORD gdwFourccVW[MAX_VIDEO_WINDOWS];
  591. #if ENABLE_MIRRORING
  592. STATIC BOOL bIsVWMirrored[MAX_VIDEO_WINDOWS];
  593. #endif
  594. STATIC DWORD gdwAvailVW; // Next available video window
  595. //STATIC WORD gwZOrder = OVERLAYZ_PRIMARY_ON_TOP; // default primary on top.
  596. STATIC DWORD gdwColorKey;
  597. STATIC DWORD gdwSrcColorKeyLow;
  598. STATIC DWORD gdwSrcColorKeyHigh;
  599. STATIC DWORD gdwDestColorKeyOwnerVW = 0; // DstColorKey owner (NULL or FLG_VWX)
  600. STATIC DWORD gdwSrcColorKeyOwnerVW = 0; // SrcColorKey owner (NULL or FLG_VWX)
  601. STATIC int giOvlyCnt[MAX_VIDEO_WINDOWS];
  602. #if ENABLE_YUVPLANAR // YUV Planar surfaces cannot exist
  603. STATIC int giPlanarCnt = 0; // with other overlay surfaces
  604. STATIC BOOL bCLPLLobotomyMode;
  605. #endif
  606. //STATIC BOOL gbDoubleClock;
  607. #if DISABLE_MOST_MODES
  608. STATIC BOOL bDisableMostModes;
  609. #endif
  610. #endif
  611. /***************************************************************************
  612. * G L O B A L V A R I A B L E S
  613. ****************************************************************************/
  614. #ifdef WINNT_VER40
  615. // For NT these are in ppdev->DriverData
  616. #define gsOverlayFlip ppdev->DriverData.gsOverlayFlip
  617. #define gsProgRegs ppdev->DriverData.gsProgRegs
  618. #define gvidConfig ppdev->DriverData.gvidConfig
  619. #define gwNormalDTTR ppdev->DriverData.gwNormalDTTR
  620. #define dwNumVideoWindows ppdev->DriverData.dwNumVideoWindows
  621. #if ENABLE_YUVPLANAR
  622. #define bEnableCLPL ppdev->DriverData.bEnableCLPL
  623. #endif
  624. #else
  625. OVERLAYFLIPRECORD gsOverlayFlip;
  626. PROGREGS gsProgRegs = {0}; //Make them global so VPE can use the same ones
  627. VIDCONFIG gvidConfig = {0};
  628. WORD gwNormalDTTR;
  629. DWORD dwNumVideoWindows;
  630. #if ENABLE_YUVPLANAR
  631. BOOL bEnableCLPL;
  632. #endif
  633. #endif
  634. /***************************************************************************
  635. * S T A T I C F U N C T I O N P R O T O T Y P E S
  636. ****************************************************************************/
  637. #ifdef WINNT_VER40
  638. static void GetUserSettings ( PDEV * );
  639. STATIC HRESULT IsFormatValid ( PDEV*, DWORD, DWORD );
  640. STATIC HRESULT CreateOverlaySurface ( PDEV*, PDD_SURFACE_LOCAL, DWORD );
  641. STATIC VOID DestroyOverlaySurface( PDEV*, PDD_DESTROYSURFACEDATA );
  642. STATIC DWORD FlipOverlaySurface ( PDEV*, PDD_FLIPDATA );
  643. STATIC DWORD LockSurface ( PDEV*, PDD_LOCKDATA );
  644. STATIC VOID UnlockSurface ( PDEV*, PDD_UNLOCKDATA );
  645. STATIC VOID SetColorKey ( PDEV*, PDD_SETCOLORKEYDATA );
  646. STATIC DWORD UpdateSurface ( PDEV*, PDD_UPDATEOVERLAYDATA );
  647. STATIC DWORD SetPosition ( PDEV*, PDD_SETOVERLAYPOSITIONDATA );
  648. STATIC DWORD GetOverlayFlipStatus ( PDEV*, FLATPTR, DWORD );
  649. STATIC BOOL RegInitVideoVW ( PDEV*, DWORD, PDD_SURFACE_LOCAL );
  650. STATIC VOID RegMoveVideoVW ( PDEV*, DWORD, PDD_SURFACE_LOCAL );
  651. #else
  652. static void GetUserSettings ( void );
  653. STATIC HRESULT IsFormatValid ( LPGLOBALDATA, DWORD, DWORD );
  654. STATIC HRESULT CreateSurface ( LPDDRAWI_DDRAWSURFACE_LCL, DWORD,LPGLOBALDATA );
  655. STATIC VOID DestroySurface ( LPDDHAL_DESTROYSURFACEDATA );
  656. STATIC DWORD FlipOverlaySurface ( LPDDHAL_FLIPDATA );
  657. STATIC DWORD LockSurface ( LPDDHAL_LOCKDATA );
  658. STATIC VOID UnlockSurface ( LPDDHAL_UNLOCKDATA );
  659. STATIC VOID SetColorKey ( LPDDHAL_SETCOLORKEYDATA);
  660. STATIC DWORD UpdateSurface ( LPDDHAL_UPDATEOVERLAYDATA );
  661. STATIC DWORD SetPosition ( LPDDHAL_SETOVERLAYPOSITIONDATA );
  662. STATIC DWORD GetOverlayFlipStatus (LPGLOBALDATA, FLATPTR, DWORD );
  663. STATIC BOOL RegInitVideoVW ( DWORD, LPDDRAWI_DDRAWSURFACE_LCL,LPGLOBALDATA );
  664. STATIC VOID RegMoveVideoVW ( DWORD, LPDDRAWI_DDRAWSURFACE_LCL,LPGLOBALDATA );
  665. #endif
  666. /***************************************************************************
  667. * E X T E R N A L F U N C T I O N P R O T O T Y P E S
  668. ****************************************************************************/
  669. #if WINNT_VER40
  670. extern int CurrentVLine (PDEV *);
  671. extern VOID GetFormatInfo (LPDDPIXELFORMAT, LPDWORD, LPDWORD);
  672. #endif
  673. #ifdef USE_OLD_BWEQ
  674. extern BOOL KillOverlay
  675. (
  676. #ifdef WINNT_VER40
  677. PDEV *ppdev,
  678. #endif
  679. WORD wScreenX,
  680. UINT uScreenDepth
  681. ); //fix PDR#10381
  682. #endif
  683. BOOL ChipIOReadBWRegs
  684. (
  685. #ifdef WINNT_VER40
  686. PDEV *ppdev,
  687. #else
  688. LPGLOBALDATA lpDDHALData,
  689. #endif
  690. LPBWREGS pBWRegs
  691. );
  692. /***************************************************************************
  693. *
  694. * FUNCTION: MakeVideoWindowFlag
  695. *
  696. * DESCRIPTION:
  697. *
  698. ****************************************************************************/
  699. static INLINE DWORD
  700. MakeVideoWindowFlag ( DWORD dwVWIndex )
  701. {
  702. ASSERT(dwNumVideoWindows > dwVWIndex);
  703. return ((1 << dwVWIndex) << FLG_VW_SHIFT);
  704. }
  705. #if 0
  706. /***************************************************************************
  707. *
  708. * FUNCTION: GetDoubleClockStatus
  709. *
  710. * DESCRIPTION:
  711. *
  712. ****************************************************************************/
  713. static INLINE DWORD
  714. GetDoubleClockStatus ( VOID )
  715. {
  716. #pragma message("GetDoubleClockStatus not implemented!")
  717. return FALSE;
  718. }
  719. #endif
  720. /***************************************************************************
  721. *
  722. * FUNCTION: GetDDHALContext
  723. *
  724. * DESCRIPTION:
  725. * Get shared data structure (SDATA) pointer
  726. ****************************************************************************/
  727. #ifndef WINNT_VER40
  728. INLINE LPGLOBALDATA GetDDHALContext( LPDDRAWI_DIRECTDRAW_GBL lpGb )
  729. {
  730. #if (DDRAW_COMPAT >= 50)
  731. if(lpGb->dwReserved3) //the SDATA pointer is passed by dwReserved3
  732. //for DX50
  733. return (LPGLOBALDATA)lpGb->dwReserved3;
  734. else
  735. #endif
  736. return pDriverData;
  737. }
  738. #endif
  739. /***************************************************************************
  740. *
  741. * FUNCTION: IsHardwareInUseVW
  742. *
  743. * DESCRIPTION:
  744. *
  745. ****************************************************************************/
  746. static INLINE BOOL IsVWHardwareInUse
  747. (
  748. #ifdef WINNT_VER40
  749. PDEV *ppdev,
  750. #else
  751. LPGLOBALDATA lpDDHALData,
  752. #endif
  753. DWORD dwVWIndex
  754. )
  755. {
  756. ASSERT(dwNumVideoWindows > dwVWIndex);
  757. if (VW_VWE & ((PVGAR)lpDDHALData->RegsAddress)->VideoWindow[dwVWIndex].grVW_CONTROL0)
  758. return TRUE;
  759. return FALSE;
  760. }
  761. /***************************************************************************
  762. *
  763. * FUNCTION: WaitForArmToClear
  764. *
  765. * DESCRIPTION:
  766. *
  767. ****************************************************************************/
  768. static INLINE VOID WaitForVWArmToClear
  769. (
  770. #ifdef WINNT_VER40
  771. PDEV *ppdev,
  772. #else
  773. LPGLOBALDATA lpDDHALData,
  774. #endif
  775. DWORD dwVWIndex
  776. )
  777. {
  778. // wait for previous register writes to post
  779. // the hardware clears the ARM bit at that time
  780. ASSERT(dwNumVideoWindows > dwVWIndex);
  781. while (((PVGAR)lpDDHALData->RegsAddress)->VideoWindow[dwVWIndex].grVW_CONTROL0 & VW_ARM)
  782. ;
  783. }
  784. /***************************************************************************
  785. *
  786. * FUNCTION: EnableOverlay
  787. *
  788. * DESCRIPTION:
  789. *
  790. ****************************************************************************/
  791. static INLINE VOID EnableOverlay
  792. (
  793. #ifdef WINNT_VER40
  794. PDEV *ppdev,
  795. #else
  796. LPGLOBALDATA lpDDHALData,
  797. #endif
  798. DWORD dwVWIndex
  799. )
  800. {
  801. ASSERT(dwNumVideoWindows > dwVWIndex);
  802. #ifdef WINNT_VER40
  803. WaitForVWArmToClear(ppdev,dwVWIndex);
  804. #else
  805. WaitForVWArmToClear(lpDDHALData,dwVWIndex);
  806. #endif
  807. ((PVGAR)lpDDHALData->RegsAddress)->VideoWindow[dwVWIndex].grVW_CONTROL0 |= (VW_VWE | VW_ARM);
  808. }
  809. /***************************************************************************
  810. *
  811. * FUNCTION: DisableOverlay
  812. *
  813. * DESCRIPTION:
  814. *
  815. ****************************************************************************/
  816. static INLINE VOID DisableOverlay
  817. (
  818. #ifdef WINNT_VER40
  819. PDEV *ppdev,
  820. #else
  821. LPGLOBALDATA lpDDHALData,
  822. #endif
  823. DWORD dwVWIndex
  824. )
  825. {
  826. ASSERT(dwNumVideoWindows > dwVWIndex);
  827. #ifdef WINNT_VER40
  828. WaitForVWArmToClear(ppdev,dwVWIndex);
  829. #else
  830. WaitForVWArmToClear(lpDDHALData,dwVWIndex);
  831. #endif
  832. ((PVGAR)lpDDHALData->RegsAddress)->VideoWindow[dwVWIndex].grVW_CONTROL0 &=
  833. ~(VW_FIFO_THRSH_EN | VW_VWE);
  834. ((PVGAR)lpDDHALData->RegsAddress)->VideoWindow[dwVWIndex].grVW_CONTROL0 |= VW_ARM;
  835. }
  836. /***************************************************************************
  837. *
  838. * FUNCTION: Set5465FlipDuration
  839. *
  840. * DESCRIPTION:
  841. *
  842. ****************************************************************************/
  843. VOID Set5465FlipDuration
  844. (
  845. #ifdef WINNT_VER40
  846. PDEV *ppdev,
  847. #endif
  848. DWORD dwFlipDuration
  849. )
  850. {
  851. gsOverlayFlip.dwFlipDuration = dwFlipDuration;
  852. }
  853. /***************************************************************************
  854. *
  855. * FUNCTION: GetUserSettings
  856. *
  857. * DESCRIPTION:
  858. *
  859. ****************************************************************************/
  860. VOID GetUserSettings
  861. (
  862. #ifdef WINNT_VER40
  863. PDEV *ppdev
  864. #else
  865. VOID
  866. #endif
  867. )
  868. {
  869. #ifdef WINNT_VER40
  870. #pragma message("GetUserSettings: Where are laguna settings stored in the NT registry?")
  871. bUseBWEqn = TRUE;
  872. #if ENABLE_YUVPLANAR
  873. bEnableCLPL = TRUE;
  874. bCLPLLobotomyMode = TRUE;
  875. #endif
  876. #else // else Win95
  877. static const USERSETTINGS UserSettings[] =
  878. {
  879. { &bUseBWEqn, "OverlayBW", TRUE },
  880. #if ENABLE_YUVPLANAR
  881. { &bEnableCLPL, "OverlayCLPL", TRUE },
  882. { &bCLPLLobotomyMode, "OverlayCLPLLobotomyMode", TRUE },
  883. #endif
  884. #if DISABLE_MOST_MODES
  885. { &bDisableMostModes, "OverlayBWHack", TRUE },
  886. #endif
  887. };
  888. const USERSETTINGS *pUserSetting;
  889. for (pUserSetting = &UserSettings[0];
  890. pUserSetting < &UserSettings[sizeof(UserSettings)/sizeof(UserSettings[0])];
  891. pUserSetting++)
  892. {
  893. *(pUserSetting->pVar) = pUserSetting->defaultVal;
  894. GetBooleanSetting(pUserSetting->pRegKey,
  895. pUserSetting->pVar,
  896. LOCATION_OF_3D_PERFORMANCE);
  897. }
  898. #endif
  899. }
  900. /***************************************************************************
  901. *
  902. * FUNCTION: Init5465Overlay
  903. *
  904. * DESCRIPTION:
  905. *
  906. ****************************************************************************/
  907. VOID Init5465Overlay
  908. (
  909. #ifdef WINNT_VER40
  910. PDEV *ppdev,
  911. DWORD dwChipType,
  912. PDD_HALINFO pDDHALInfo,
  913. LPOVERLAYTABLE pOverlayTable
  914. #else
  915. DWORD dwChipType,
  916. LPDDHALINFO pDDHALInfo,
  917. LPOVERLAYTABLE pOverlayTable,
  918. LPGLOBALDATA lpDDHALData
  919. #endif
  920. )
  921. {
  922. DWORD dwNumFourCCs;
  923. #ifdef WINNT_VER40
  924. GetUserSettings(ppdev);
  925. #else
  926. GetUserSettings();
  927. #endif
  928. if (! bUseBWEqn)
  929. gsProgRegs.VW0_FIFO_THRSH = 8;
  930. // We should check the capabilities register on the chip
  931. // but it's busted
  932. #ifdef WINNT_VER40
  933. if (CL_GD5465 == dwChipType)
  934. #else
  935. if (GD5465_PCI_DEVICE_ID == dwChipType)
  936. #endif
  937. dwNumVideoWindows = 1;
  938. else
  939. {
  940. #if 1
  941. dwNumVideoWindows = 1;
  942. #else
  943. int i;
  944. PVGAR pREG = (PVGAR)lpDDHALData->RegsAddress;
  945. dwNumVideoWindows = 0;
  946. for (i = 0; i < MAX_VIDEO_WINDOWS; i++)
  947. {
  948. if (VWCAP_VW_PRESENT & pREG->VideoWindow[i].grVW_CAP0)
  949. dwNumVideoWindows++;
  950. }
  951. #endif
  952. }
  953. #ifdef WINNT_VER40
  954. if (NULL != pDDHALInfo)
  955. #endif
  956. {
  957. pDDHALInfo->ddCaps.dwMaxVisibleOverlays = dwNumVideoWindows;
  958. pDDHALInfo->ddCaps.dwCurrVisibleOverlays = 0;
  959. #ifndef WINNT_VER40
  960. pPDevice = (DIBENGINE *)lpDDHALData->lpPDevice;
  961. #endif
  962. // Fill in the caps
  963. pDDHALInfo->ddCaps.dwCaps |= DDCAPS_OVERLAY
  964. | DDCAPS_OVERLAYFOURCC
  965. | DDCAPS_OVERLAYSTRETCH
  966. | DDCAPS_ALIGNSTRIDE
  967. | DDCAPS_OVERLAYCANTCLIP
  968. ;
  969. pDDHALInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_OVERLAY
  970. ;
  971. pDDHALInfo->ddCaps.dwFXCaps |= DDFXCAPS_OVERLAYARITHSTRETCHY
  972. | DDFXCAPS_OVERLAYSTRETCHX
  973. | DDFXCAPS_OVERLAYSTRETCHY
  974. | DDFXCAPS_OVERLAYSHRINKX
  975. | DDFXCAPS_OVERLAYSHRINKY
  976. #if ENABLE_MIRRORING
  977. | DDFXCAPS_OVERLAYMIRRORLEFTRIGHT
  978. #endif
  979. ;
  980. }
  981. /* FOURCCs supported */
  982. #if (MAX_FOURCCS < 3)
  983. #error dwFourCC array too small
  984. #endif
  985. dwNumFourCCs = 0;
  986. lpDDHALData->dwFourCC[dwNumFourCCs++] = FOURCC_UYVY;
  987. #if ENABLE_YUY2
  988. lpDDHALData->dwFourCC[dwNumFourCCs++] = FOURCC_YUY2;
  989. #endif
  990. #if ENABLE_YUVPLANAR
  991. // add CLPL fourcc if registry key set to "on"
  992. if (bEnableCLPL)
  993. lpDDHALData->dwFourCC[dwNumFourCCs++] = FOURCC_YUVPLANAR;
  994. #endif
  995. #ifdef WINNT_VER40
  996. if (NULL != pDDHALInfo)
  997. #endif
  998. {
  999. pDDHALInfo->ddCaps.dwNumFourCCCodes = dwNumFourCCs;
  1000. // say we can handle byte alignment and any byte width
  1001. pDDHALInfo->ddCaps.dwAlignBoundarySrc = 1; // src rect x byte alignment
  1002. pDDHALInfo->ddCaps.dwAlignSizeSrc = 1; // src rect x byte size
  1003. pDDHALInfo->ddCaps.dwAlignBoundaryDest = 1; // dst rect x byte alignment
  1004. pDDHALInfo->ddCaps.dwAlignSizeDest = 1; // dst rect x byte size
  1005. // stride alignment
  1006. #ifdef WINNT_VER40
  1007. pDDHALInfo->ddCaps.dwAlignStrideAlign = ppdev->cxMemory;
  1008. #else
  1009. pDDHALInfo->ddCaps.dwAlignStrideAlign = pPDevice->deWidthBytes;
  1010. #endif
  1011. pDDHALInfo->ddCaps.dwMinOverlayStretch = 500; // min stretch is 0.5:1
  1012. pDDHALInfo->ddCaps.dwMaxOverlayStretch = 8000; // max stretch is 8:1
  1013. #ifdef WINNT_VER40
  1014. ppdev->DriverData.dwMinOverlayStretch = 500;
  1015. ppdev->DriverData.dwMaxOverlayStretch = 8000;
  1016. #endif
  1017. pDDHALInfo->vmiData.dwOverlayAlign = 8 * 8; // qword alignment in bits
  1018. }
  1019. // Initialize OverlayTable function pointers
  1020. pOverlayTable->pfnCanCreateSurface = IsFormatValid;
  1021. #ifdef WINNT_VER40
  1022. pOverlayTable->pfnCreateSurface = CreateOverlaySurface;
  1023. pOverlayTable->pfnDestroySurface = DestroyOverlaySurface;
  1024. #else
  1025. pOverlayTable->pfnCreateSurface = CreateSurface;
  1026. pOverlayTable->pfnDestroySurface = DestroySurface;
  1027. #endif
  1028. pOverlayTable->pfnLock = LockSurface;
  1029. pOverlayTable->pfnUnlock = UnlockSurface;
  1030. pOverlayTable->pfnSetColorKey = SetColorKey;
  1031. pOverlayTable->pfnFlip = FlipOverlaySurface;
  1032. pOverlayTable->pfnUpdateOverlay = UpdateSurface;
  1033. pOverlayTable->pfnSetOverlayPos = SetPosition;
  1034. pOverlayTable->pfnGetFlipStatus = GetOverlayFlipStatus;
  1035. // do mode specific initialization
  1036. #ifdef WINNT_VER40
  1037. if (NULL != pDDHALInfo)
  1038. Init5465Info(ppdev, pDDHALInfo);
  1039. #else
  1040. Init5465Info(pDDHALInfo, lpDDHALData);
  1041. #endif
  1042. }
  1043. /***************************************************************************
  1044. *
  1045. * FUNCTION: Init5465Info
  1046. *
  1047. * DESCRIPTION:
  1048. *
  1049. ****************************************************************************/
  1050. VOID Init5465Info
  1051. (
  1052. #ifdef WINNT_VER40
  1053. PDEV *ppdev,
  1054. PDD_HALINFO pDDHALInfo
  1055. #else
  1056. LPDDHALINFO pDDHALInfo,
  1057. LPGLOBALDATA lpDDHALData
  1058. #endif
  1059. )
  1060. {
  1061. // assume we can use overlay in this mode
  1062. bNoOverlayInThisMode = FALSE;
  1063. if (! bUseBWEqn)
  1064. gsProgRegs.DispThrsTiming =
  1065. ((PVGAR)lpDDHALData->RegsAddress)->grDisplay_Threshold_and_Tiling & 0x3F;
  1066. // Are we double clocked?
  1067. // gbDoubleClock = GetDoubleClockStatus();
  1068. // re-init these on mode change, we might tweak them below
  1069. pDDHALInfo->ddCaps.dwAlignBoundaryDest = 1;
  1070. pDDHALInfo->ddCaps.dwAlignSizeDest = 1;
  1071. pDDHALInfo->ddCaps.dwMinOverlayStretch = 500;
  1072. pDDHALInfo->ddCaps.dwMaxOverlayStretch = 8000;
  1073. #ifdef WINNT_VER40
  1074. ppdev->DriverData.dwMinOverlayStretch = 500;
  1075. ppdev->DriverData.dwMaxOverlayStretch = 8000;
  1076. #endif
  1077. // tell ddraw we can do colorkeying
  1078. // we might undo this below
  1079. pDDHALInfo->ddCaps.dwCKeyCaps |= DDCKEYCAPS_DESTOVERLAY
  1080. | DDCKEYCAPS_DESTOVERLAYYUV
  1081. | DDCKEYCAPS_DESTOVERLAYONEACTIVE
  1082. | DDCKEYCAPS_SRCOVERLAY
  1083. | DDCKEYCAPS_SRCOVERLAYYUV
  1084. | DDCKEYCAPS_SRCOVERLAYONEACTIVE
  1085. | DDCKEYCAPS_SRCOVERLAYCLRSPACE
  1086. | DDCKEYCAPS_SRCOVERLAYCLRSPACEYUV
  1087. ;
  1088. if (bUseBWEqn)
  1089. {
  1090. DWORD dwZoom;
  1091. VIDCONFIG vidConfig;
  1092. BWREGS bwregs;
  1093. // initialize vidConfig
  1094. memset(&vidConfig, 0, sizeof(vidConfig));
  1095. vidConfig.uSrcDepth = 16;
  1096. #ifdef WINNT_VER40
  1097. vidConfig.uDispDepth = ppdev->ulBitCount;
  1098. vidConfig.uGfxDepth = ppdev->ulBitCount;
  1099. #else
  1100. vidConfig.uDispDepth = pPDevice->deBitsPixel;
  1101. vidConfig.uGfxDepth = pPDevice->deBitsPixel;
  1102. #endif
  1103. vidConfig.dwFlags = VCFLG_COLORKEY | VCFLG_DISP;
  1104. vidConfig.sizSrc.cx = SRC_WIDTH;
  1105. vidConfig.sizSrc.cy = SRC_HEIGHT;
  1106. if(gvidConfig.dwFlags & VCFLG_CAP)
  1107. {
  1108. //if video port is on, includes it for BWE
  1109. vidConfig.dwFlags |= VCFLG_CAP;
  1110. vidConfig.sizXfer = gvidConfig.sizXfer;
  1111. vidConfig.sizCap = gvidConfig.sizCap;
  1112. vidConfig.sizXfer = gvidConfig.sizXfer;
  1113. vidConfig.dwXferRate = gvidConfig.dwXferRate;
  1114. vidConfig.uXferDepth = gvidConfig.uXferDepth;
  1115. vidConfig.uCapDepth = gvidConfig.uCapDepth;
  1116. vidConfig.uSrcDepth = gvidConfig.uSrcDepth;
  1117. }
  1118. #ifdef WINNT_VER40
  1119. ChipIOReadBWRegs(ppdev, &bwregs);
  1120. #else
  1121. ChipIOReadBWRegs(lpDDHALData, &bwregs);
  1122. #endif
  1123. #ifdef USE_OLD_BWEQ
  1124. //Kill overlay for some modes
  1125. #ifdef WINNT_VER40
  1126. if(KillOverlay(ppdev, (WORD)ppdev->cxScreen, (UINT)ppdev->ulBitCount))
  1127. #else
  1128. if(KillOverlay( pPDevice->deWidth,pPDevice->deBitsPixel))
  1129. #endif
  1130. bNoOverlayInThisMode = TRUE;
  1131. else
  1132. #endif
  1133. {
  1134. // stupid linear search for min & max zoom factors
  1135. // Check bandwidth to find the maximum zoom factor of 16 bit data
  1136. // with colorkey
  1137. dwZoom = MAX_ZOOM;
  1138. do
  1139. {
  1140. vidConfig.sizDisp.cx = (SRC_WIDTH * dwZoom) / 1000;
  1141. vidConfig.sizDisp.cy = (SRC_HEIGHT * dwZoom) / 1000;
  1142. if (ChipIsEnoughBandwidth(&gsProgRegs, &vidConfig, &bwregs))
  1143. {
  1144. #ifndef WINNT_VER40
  1145. DBG_MESSAGE(("Maximum zoom factor: %d", dwZoom));
  1146. #endif
  1147. pDDHALInfo->ddCaps.dwMaxOverlayStretch = dwZoom;
  1148. #ifdef WINNT_VER40
  1149. ppdev->DriverData.dwMaxOverlayStretch = dwZoom;
  1150. #endif
  1151. break;
  1152. }
  1153. dwZoom -= ZOOM_STEP;
  1154. } while (dwZoom > 4000);
  1155. if (dwZoom != pDDHALInfo->ddCaps.dwMaxOverlayStretch)
  1156. bNoOverlayInThisMode = TRUE;
  1157. // Check bandwidth to find the minimum zoom factor of 16 bit data
  1158. // with colorkey
  1159. dwZoom = MIN_ZOOM;
  1160. #ifdef USE_OLD_BWEQ
  1161. // disable overlay shrink in 24bpp modes
  1162. #ifdef WINNT_VER40
  1163. if (24 == ppdev->ulBitCount)
  1164. #else
  1165. if (24 == pPDevice->deBitsPixel)
  1166. #endif
  1167. dwZoom = 1000;
  1168. #endif
  1169. do
  1170. {
  1171. vidConfig.sizDisp.cx = (SRC_WIDTH * dwZoom) / 1000;
  1172. vidConfig.sizDisp.cy = (SRC_HEIGHT * dwZoom) / 1000;
  1173. if (ChipIsEnoughBandwidth(&gsProgRegs, &vidConfig, &bwregs))
  1174. {
  1175. #ifndef WINNT_VER40
  1176. DBG_MESSAGE(("Minimum zoom factor: %d", dwZoom));
  1177. #endif
  1178. pDDHALInfo->ddCaps.dwMinOverlayStretch = dwZoom;
  1179. #ifdef WINNT_VER40
  1180. ppdev->DriverData.dwMinOverlayStretch = dwZoom;
  1181. #endif
  1182. break;
  1183. }
  1184. dwZoom += ZOOM_STEP;
  1185. } while (dwZoom < 4000);
  1186. if (dwZoom != pDDHALInfo->ddCaps.dwMinOverlayStretch)
  1187. bNoOverlayInThisMode = TRUE;
  1188. }
  1189. // I'll leave this code in here but so far I have only seen that if
  1190. // we don't have enough bandwidth to use overlay with colorkey then
  1191. // we don't have enough bandwidth period
  1192. // try to see if there's enough bandwidth to use overlay without colorkey
  1193. if (TRUE == bNoOverlayInThisMode)
  1194. {
  1195. // reset this in case we find enough bandwidth to use overlay
  1196. // without colorkey
  1197. bNoOverlayInThisMode = FALSE;
  1198. // retry without colorkey available
  1199. // tell ddraw we don't do colorkeying
  1200. pDDHALInfo->ddCaps.dwCKeyCaps &= ~(DDCKEYCAPS_DESTOVERLAY
  1201. | DDCKEYCAPS_DESTOVERLAYYUV
  1202. | DDCKEYCAPS_DESTOVERLAYONEACTIVE
  1203. | DDCKEYCAPS_SRCOVERLAY
  1204. | DDCKEYCAPS_SRCOVERLAYYUV
  1205. | DDCKEYCAPS_SRCOVERLAYONEACTIVE
  1206. | DDCKEYCAPS_SRCOVERLAYCLRSPACE
  1207. | DDCKEYCAPS_SRCOVERLAYCLRSPACEYUV)
  1208. ;
  1209. #ifdef USE_OLD_BWEQ
  1210. #ifdef WINNT_VER40
  1211. if(KillOverlay(ppdev, (WORD)ppdev->cxScreen, (UINT)ppdev->ulBitCount))
  1212. #else
  1213. if(KillOverlay( pPDevice->deWidth,pPDevice->deBitsPixel))
  1214. #endif
  1215. bNoOverlayInThisMode = TRUE;
  1216. else
  1217. #endif
  1218. {
  1219. // Check bandwidth to find the maximum zoom factor of 16 bit data
  1220. dwZoom = MAX_ZOOM;
  1221. do
  1222. {
  1223. vidConfig.sizDisp.cx = (SRC_WIDTH * dwZoom) / 1000;
  1224. vidConfig.sizDisp.cy = (SRC_HEIGHT * dwZoom) / 1000;
  1225. if (ChipIsEnoughBandwidth(&gsProgRegs, &vidConfig, &bwregs))
  1226. {
  1227. #ifndef WINNT_VER40
  1228. DBG_MESSAGE(("Maximum zoom factor: %d", dwZoom));
  1229. #endif
  1230. pDDHALInfo->ddCaps.dwMaxOverlayStretch = dwZoom;
  1231. #ifdef WINNT_VER40
  1232. ppdev->DriverData.dwMaxOverlayStretch = dwZoom;
  1233. #endif
  1234. break;
  1235. }
  1236. dwZoom -= ZOOM_STEP;
  1237. } while (dwZoom > 4000);
  1238. if (dwZoom != pDDHALInfo->ddCaps.dwMaxOverlayStretch)
  1239. bNoOverlayInThisMode = TRUE;
  1240. // Check bandwidth to find the minimum zoom factor of 16 bit data
  1241. dwZoom = MIN_ZOOM;
  1242. // disable overlay shrink in 24bpp modes
  1243. #ifdef WINNT_VER40
  1244. if (24 == ppdev->ulBitCount)
  1245. #else
  1246. if (24 == pPDevice->deBitsPixel)
  1247. #endif
  1248. dwZoom = 1000;
  1249. do
  1250. {
  1251. vidConfig.sizDisp.cx = (SRC_WIDTH * dwZoom) / 1000;
  1252. vidConfig.sizDisp.cy = (SRC_HEIGHT * dwZoom) / 1000;
  1253. if (ChipIsEnoughBandwidth(&gsProgRegs, &vidConfig, &bwregs))
  1254. {
  1255. #ifndef WINNT_VER40
  1256. DBG_MESSAGE(("Minimum zoom factor: %d", dwZoom));
  1257. #endif
  1258. pDDHALInfo->ddCaps.dwMinOverlayStretch = dwZoom;
  1259. #ifdef WINNT_VER40
  1260. ppdev->DriverData.dwMinOverlayStretch = dwZoom;
  1261. #endif
  1262. break;
  1263. }
  1264. dwZoom += ZOOM_STEP;
  1265. } while (dwZoom < 4000);
  1266. if (dwZoom != pDDHALInfo->ddCaps.dwMinOverlayStretch)
  1267. bNoOverlayInThisMode = TRUE;
  1268. }
  1269. #ifdef DEBUG
  1270. if (bNoOverlayInThisMode)
  1271. {
  1272. ERRORLOG((" overlay disabled in %ldx%ldx%ld",
  1273. (DWORD)pPDevice->deWidth,
  1274. (DWORD)pPDevice->deHeight,
  1275. (DWORD)pPDevice->deBitsPixel));
  1276. }
  1277. else
  1278. {
  1279. ERRORLOG((" overlay colorkey not supported in %ldx%ldx%ld",
  1280. (DWORD)pPDevice->deWidth,
  1281. (DWORD)pPDevice->deHeight,
  1282. (DWORD)pPDevice->deBitsPixel));
  1283. }
  1284. #endif
  1285. }
  1286. // see if we're in interlaced mode, if so disable overlay
  1287. if (1 & ((PVGAR)lpDDHALData->RegsAddress)->grCR1A)
  1288. bNoOverlayInThisMode = TRUE;
  1289. #if DISABLE_MOST_MODES
  1290. if (bDisableMostModes)
  1291. {
  1292. PVGAR pREG = (PVGAR)lpDDHALData->RegsAddress;
  1293. // disable overlay support for 1024x768 and above
  1294. if ((1024 <= pPDevice->deWidth) && ( 768 <= pPDevice->deHeight))
  1295. bNoOverlayInThisMode = TRUE;
  1296. // disable overlay support for 640x480x32@85Hz
  1297. if ((640 == pPDevice->deWidth) &&
  1298. (480 == pPDevice->deHeight) &&
  1299. ( 32 == pPDevice->deBitsPixel) &&
  1300. (0x33 == pREG->grSRE) &&
  1301. (0x7E == pREG->grSR1E))
  1302. bNoOverlayInThisMode = TRUE;
  1303. // disable overlay support for 800x600x32@85Hz
  1304. if ((800 == pPDevice->deWidth) &&
  1305. (600 == pPDevice->deHeight) &&
  1306. ( 32 == pPDevice->deBitsPixel) &&
  1307. (0x1C == pREG->grSRE) &&
  1308. (0x37 == pREG->grSR1E))
  1309. bNoOverlayInThisMode = TRUE;
  1310. }
  1311. #endif
  1312. #if 0
  1313. // TDDRAW.EXE error return from UpdateOverlay in to following cases
  1314. if (ppdev->ulBitCount == 8 && ppdev->cxScreen == 1280)
  1315. {
  1316. if ( (ppdev->cyScreen == 1024 && ppdev->ulFreq >= 72) ||
  1317. (ppdev->cyScreen == 960 && ppdev->ulFreq >= 85) )
  1318. bNoOverlayInThisMode = TRUE;
  1319. }
  1320. if ( ppdev->cxScreen == 640 &&
  1321. ppdev->cyScreen == 350 )
  1322. bNoOverlayInThisMode = TRUE;
  1323. #endif// 0
  1324. // if no overlay in this mode set min & max overlay stretch to 0
  1325. if (TRUE == bNoOverlayInThisMode)
  1326. {
  1327. pDDHALInfo->ddCaps.dwMinOverlayStretch = 0;
  1328. pDDHALInfo->ddCaps.dwMaxOverlayStretch = 0;
  1329. #ifdef WINNT_VER40
  1330. ppdev->DriverData.dwMinOverlayStretch = 0;
  1331. ppdev->DriverData.dwMaxOverlayStretch = 0;
  1332. #endif
  1333. }
  1334. }
  1335. #if HWBUG_24BPP_DST_COLORKEY
  1336. #ifdef WINNT_VER40
  1337. if (24 == ppdev->ulBitCount)
  1338. #else
  1339. if (24 == pPDevice->deBitsPixel)
  1340. #endif
  1341. {
  1342. // disable destination colorkey support at 24bpp
  1343. // the hardware appears to be busted
  1344. pDDHALInfo->ddCaps.dwCKeyCaps &= ~( DDCKEYCAPS_DESTOVERLAY
  1345. | DDCKEYCAPS_DESTOVERLAYYUV
  1346. | DDCKEYCAPS_DESTOVERLAYONEACTIVE);
  1347. }
  1348. #endif
  1349. #if 0
  1350. // When double clocking (i.e. 1280x1024), the minimum
  1351. // zoom is 2X.
  1352. if ((gbDoubleClock) && (pDDHALInfo->ddCaps.dwMinOverlayStretch < 2000))
  1353. {
  1354. pDDHALInfo->ddCaps.dwMinOverlayStretch = 2000;
  1355. }
  1356. // don't use overlay in the 1X case.
  1357. if (pDDHALInfo->ddCaps.dwMinOverlayStretch < 1500)
  1358. {
  1359. pDDHALInfo->ddCaps.dwMinOverlayStretch = 1500;
  1360. }
  1361. // Specify destination requirements.
  1362. if ((BITSPERPIXEL == 24) || gbDoubleClock)
  1363. {
  1364. pDDHALInfo->ddCaps.dwCaps |= DDCAPS_ALIGNBOUNDARYDEST
  1365. | DDCAPS_ALIGNSIZEDEST
  1366. ;
  1367. pDDHALInfo->ddCaps.dwAlignBoundaryDest = 4;
  1368. pDDHALInfo->ddCaps.dwAlignSizeDest = 4;
  1369. }
  1370. #endif
  1371. }
  1372. /***************************************************************************
  1373. *
  1374. * FUNCTION: IsFormatValid
  1375. *
  1376. * DESCRIPTION: This function verifies that the overlay hardware can
  1377. * support the specified format.
  1378. *
  1379. ****************************************************************************/
  1380. STATIC HRESULT IsFormatValid
  1381. (
  1382. #ifdef WINNT_VER40
  1383. PDEV *ppdev,
  1384. #else
  1385. LPGLOBALDATA lpDDHALData,
  1386. #endif
  1387. DWORD dwFourcc,
  1388. DWORD dwBitCount
  1389. )
  1390. {
  1391. DWORD i;
  1392. #ifndef WINNT_VER40
  1393. DBG_MESSAGE(("IsFormatValid (dwFourcc = 0x%08lX, dwBitCount = 0x%08lX)",
  1394. dwFourcc, dwBitCount));
  1395. #endif
  1396. // see if we're in interlaced mode
  1397. // if so then don't allow overlay surface to be created
  1398. // also if there isn't enough bandwidth then fail all
  1399. // overlay surface CanCreate requests
  1400. if (bNoOverlayInThisMode || (1 & ((PVGAR)lpDDHALData->RegsAddress)->grCR1A))
  1401. return DDERR_CURRENTLYNOTAVAIL;
  1402. for (i = 0; i < dwNumVideoWindows; i++)
  1403. {
  1404. // see if ddraw thinks the video window is available
  1405. // and make sure VPM isn't using it
  1406. if ((0 == giOvlyCnt[i]) &&
  1407. #ifdef WINNT_VER40
  1408. (! IsVWHardwareInUse(ppdev,i))
  1409. #else
  1410. (! IsVWHardwareInUse(lpDDHALData,i))
  1411. #endif
  1412. )
  1413. {
  1414. #ifndef WINNT_VER40
  1415. DBG_MESSAGE(("Video Window %d available", i));
  1416. #endif
  1417. // I'll say YUCK again!
  1418. // I hate this, what if VPM sneaks in between a CanCreateSurface
  1419. // call and a CreateSurface call and grabs this video window
  1420. // Guess we'll just say the creation succeeded but then fail all use
  1421. // of the video window
  1422. gdwAvailVW = MakeVideoWindowFlag(i);
  1423. break;
  1424. }
  1425. }
  1426. if (dwNumVideoWindows == i)
  1427. {
  1428. DBG_MESSAGE(("All video windows in use, returning FALSE"));
  1429. return DDERR_CURRENTLYNOTAVAIL;
  1430. }
  1431. // only support 5:5:5, 5:6:5 and UYVY overlay surfaces
  1432. if ( ((dwFourcc != BI_RGB) || (dwBitCount != 16))
  1433. #if ENABLE_SD_RGB32
  1434. && ((dwFourcc != BI_RGB) || (dwBitCount != 32))
  1435. #endif
  1436. && (dwFourcc != BI_BITFIELDS)
  1437. && (dwFourcc != FOURCC_UYVY)
  1438. #if ENABLE_YUY2
  1439. && (dwFourcc != FOURCC_YUY2)
  1440. #endif
  1441. #if ENABLE_YUVPLANAR
  1442. && (dwFourcc != FOURCC_YUVPLANAR)
  1443. #endif
  1444. )
  1445. {
  1446. #ifndef WINNT_VER40
  1447. DBG_MESSAGE(("IsFormatValid5465: returning FALSE, FourCC = %08lX", dwFourcc));
  1448. #endif
  1449. return DDERR_INVALIDPIXELFORMAT;
  1450. }
  1451. #ifndef WINNT_VER40
  1452. DBG_MESSAGE(("IsFormatValid5465: returning TRUE, FourCC = %08lX", dwFourcc));
  1453. #endif
  1454. return DD_OK;
  1455. }
  1456. /***************************************************************************
  1457. *
  1458. * FUNCTION: CreateSurface
  1459. *
  1460. * DESCRIPTION: This function sets various flags depending on what
  1461. * is happening.
  1462. *
  1463. ****************************************************************************/
  1464. #ifdef WINNT_VER40
  1465. STATIC HRESULT CreateOverlaySurface(
  1466. #else
  1467. STATIC HRESULT CreateSurface(
  1468. #endif
  1469. #ifdef WINNT_VER40
  1470. PDEV *ppdev,
  1471. PDD_SURFACE_LOCAL lpSurface,
  1472. DWORD dwFourcc
  1473. #else
  1474. LPDDRAWI_DDRAWSURFACE_LCL lpSurface,
  1475. DWORD dwFourcc,
  1476. LPGLOBALDATA lpDDHALData
  1477. #endif
  1478. )
  1479. {
  1480. LP_SURFACE_DATA lpSurfaceData = GET_SURFACE_DATA_PTR(lpSurface);
  1481. DWORD dwVWIndex;
  1482. // For non-RGB surfaces, we must always specify the block size.
  1483. #ifndef WINNT_VER40
  1484. DBG_MESSAGE(("Overlay CreateSurface (lpSurface = %08lX, dwFourcc = %08lX)",
  1485. lpSurface, dwFourcc));
  1486. #endif
  1487. lpSurfaceData->dwOverlayFlags |= FLG_OVERLAY;
  1488. #ifdef WINNT_VER40
  1489. if (gdwAvailVW == 0)
  1490. {
  1491. UINT i;
  1492. for (i = 0; i < dwNumVideoWindows; i++)
  1493. {
  1494. // see if ddraw thinks the video window is available
  1495. // and make sure VPM isn't using it
  1496. if ( (giOvlyCnt[i] == 0) && ! IsVWHardwareInUse(ppdev,i) )
  1497. {
  1498. gdwAvailVW = MakeVideoWindowFlag(i);
  1499. break;
  1500. }
  1501. }
  1502. if (i == dwNumVideoWindows)
  1503. {
  1504. DBG_MESSAGE(("All video windows in use, returning FALSE"));
  1505. return DDERR_CURRENTLYNOTAVAIL;
  1506. }
  1507. }
  1508. #endif
  1509. dwVWIndex = GetVideoWindowIndex(gdwAvailVW);
  1510. ASSERT(dwNumVideoWindows > dwVWIndex);
  1511. lpSurfaceData->dwOverlayFlags |= gdwAvailVW;
  1512. gdwFourccVW[dwVWIndex] = dwFourcc;
  1513. if ( (dwFourcc == FOURCC_UYVY)
  1514. #if ENABLE_YUY2
  1515. || (dwFourcc == FOURCC_YUY2)
  1516. #endif
  1517. #if ENABLE_YUVPLANAR
  1518. || (dwFourcc == FOURCC_YUVPLANAR)
  1519. #endif
  1520. )
  1521. {
  1522. lpSurface->lpGbl->ddpfSurface.dwYUVBitCount = 16;
  1523. lpSurface->lpGbl->ddpfSurface.dwYBitMask = (DWORD) -1;
  1524. lpSurface->lpGbl->ddpfSurface.dwUBitMask = (DWORD) -1;
  1525. lpSurface->lpGbl->ddpfSurface.dwVBitMask = (DWORD) -1;
  1526. if (dwFourcc == FOURCC_UYVY)
  1527. {
  1528. lpSurfaceData->dwOverlayFlags |= FLG_UYVY;
  1529. }
  1530. #if ENABLE_YUY2
  1531. else if (dwFourcc == FOURCC_YUY2)
  1532. {
  1533. lpSurfaceData->dwOverlayFlags |= FLG_YUY2;
  1534. }
  1535. #endif
  1536. #if ENABLE_YUVPLANAR
  1537. else // if (dwFourcc == FOURCC_YUVPLANAR)
  1538. {
  1539. lpSurfaceData->dwOverlayFlags |= FLG_YUVPLANAR;
  1540. giPlanarCnt++;
  1541. lpSurface->lpGbl->ddpfSurface.dwYUVBitCount = 12;
  1542. //allocate a CLPLInfo structure
  1543. lpSurfaceData->lpCLPLData = HEAP_ALLOC(hSharedHeap,
  1544. HEAP_ZERO_MEMORY,
  1545. sizeof(CLPLInfo),
  1546. OWNER_OVERLAY,
  1547. (DWORD)lpSurface);
  1548. if (0 == lpSurfaceData->lpCLPLData)
  1549. {
  1550. return DDERR_OUTOFMEMORY;
  1551. }
  1552. if (bCLPLLobotomyMode)
  1553. {
  1554. LPCLPLSURFACE lpCLPL = lpSurfaceData->lpCLPLData;
  1555. DWORD dwSize;
  1556. dwSize = (lpSurface->lpGbl->wWidth * lpSurface->lpGbl->wHeight) / 2;
  1557. lpCLPL->fpUSystemSurface = HEAP_ALLOC(hSharedHeap,
  1558. HEAP_ZERO_MEMORY,
  1559. dwSize,
  1560. OWNER_OVERLAY,
  1561. (DWORD)lpSurface);
  1562. if (0 == lpCLPL->fpUSystemSurface)
  1563. {
  1564. HEAP_FREE(hSharedHeap, 0, (LPVOID)lpSurfaceData->lpCLPLData);
  1565. lpSurfaceData->lpCLPLData = NULL;
  1566. return DDERR_OUTOFMEMORY;
  1567. }
  1568. lpCLPL->fpVSystemSurface = (LPVOID)((DWORD)(lpCLPL->fpUSystemSurface) + dwSize / 2);
  1569. DBG_MESSAGE(("CLPL lobotomy mode addrs: USys=%08lX, VSys=%08lX, size=%08lX",
  1570. lpCLPL->fpUSystemSurface, lpCLPL->fpVSystemSurface, dwSize));
  1571. }
  1572. }
  1573. #endif
  1574. }
  1575. if(giOvlyCnt[dwVWIndex] == 0 )
  1576. {
  1577. // save copy of current DTTR value
  1578. #if DDRAW_COMPAT >= 50
  1579. gwNotify |= OVERLAY_ON;
  1580. //if VPE is created this variable is already initialized
  1581. if(!(gwNotify & VPE_ON))
  1582. #endif
  1583. {
  1584. gwNormalDTTR = ((PVGAR)lpDDHALData->RegsAddress)->grDisplay_Threshold_and_Tiling;
  1585. }
  1586. }
  1587. giOvlyCnt[dwVWIndex]++;
  1588. // CreateSurface32 fills in block size
  1589. return DD_OK;
  1590. }
  1591. /***************************************************************************
  1592. *
  1593. * FUNCTION: DestroySurface
  1594. *
  1595. * DESCRIPTION: This does misc things when an overlay surface is
  1596. * destroyed.
  1597. *
  1598. ****************************************************************************/
  1599. #ifdef WINNT_VER40
  1600. STATIC VOID DestroyOverlaySurface(
  1601. #else
  1602. STATIC VOID DestroySurface(
  1603. #endif
  1604. #ifdef WINNT_VER40
  1605. PDEV *ppdev,
  1606. PDD_DESTROYSURFACEDATA lpInput
  1607. #else
  1608. LPDDHAL_DESTROYSURFACEDATA lpInput
  1609. #endif
  1610. )
  1611. {
  1612. #ifndef WINNT_VER40
  1613. LPGLOBALDATA lpDDHALData = GetDDHALContext( lpInput->lpDD);
  1614. #endif
  1615. LP_SURFACE_DATA lpSurfaceData;
  1616. PVGAR pREG = (PVGAR)lpDDHALData->RegsAddress;
  1617. DWORD dwVWIndex;
  1618. #ifndef WINNT_VER40
  1619. DBG_MESSAGE(("Overlay DestroySurface (lpInput = 0x%08lX)", lpInput));
  1620. #endif
  1621. if (0 == lpInput->lpDDSurface->dwReserved1)
  1622. {
  1623. lpInput->ddRVal = DDERR_NOTAOVERLAYSURFACE;
  1624. return;
  1625. }
  1626. lpSurfaceData = GET_SURFACE_DATA_PTR(lpInput->lpDDSurface);
  1627. dwVWIndex = GetVideoWindowIndex(lpSurfaceData->dwOverlayFlags);
  1628. ASSERT(dwNumVideoWindows > dwVWIndex);
  1629. if (lpSurfaceData->dwOverlayFlags & FLG_ENABLED)
  1630. {
  1631. // Turn the video off
  1632. #ifndef WINNT_VER40
  1633. DBG_MESSAGE(("Turning off VW %ld in DestroySurface", dwVWIndex));
  1634. #endif
  1635. #ifdef WINNT_VER40
  1636. DisableOverlay(ppdev, dwVWIndex);
  1637. #else
  1638. DisableOverlay(lpDDHALData, dwVWIndex);
  1639. #endif
  1640. lpHardwareOwner[dwVWIndex] = NULL;
  1641. // clear show bit if panning of desktop enabled
  1642. }
  1643. #if ENABLE_YUVPLANAR
  1644. if (lpSurfaceData->dwOverlayFlags & FLG_YUVPLANAR)
  1645. {
  1646. if (giPlanarCnt > 0)
  1647. {
  1648. LPCLPLSURFACE lpCLPL = lpSurfaceData->lpCLPLData;
  1649. giPlanarCnt--;
  1650. if (0 != lpCLPL)
  1651. {
  1652. if ((bCLPLLobotomyMode) && (0 != lpCLPL->fpUSystemSurface))
  1653. HEAP_FREE(hSharedHeap, 0, (LPVOID)lpCLPL->fpUSystemSurface);
  1654. // Free up the memory for the CLPLInfo structure
  1655. HEAP_FREE(hSharedHeap, 0, (LPVOID)lpCLPL);
  1656. }
  1657. }
  1658. }
  1659. #endif
  1660. if (lpSurfaceData->dwOverlayFlags & FLG_VW_MASK)
  1661. {
  1662. if (giOvlyCnt[dwVWIndex] > 0)
  1663. {
  1664. if (0 == --giOvlyCnt[dwVWIndex])
  1665. {
  1666. // get current DTTR, mask off FIFO threshold
  1667. WORD CurrentDTTR = pREG->grDisplay_Threshold_and_Tiling & 0xFFC0;
  1668. #if DDRAW_COMPAT >= 50
  1669. gvidConfig.dwFlags &= ~(VCFLG_COLORKEY | VCFLG_CHROMAKEY |
  1670. VCFLG_DISP | VCFLG_420);
  1671. gwNotify &= ~OVERLAY_ON;
  1672. if(!(gwNotify & VPE_ON))
  1673. #endif
  1674. {
  1675. // Fix PDR 9574: Restore FIFO threshold value when overlay surface
  1676. // is destroyed, do not restore the tile size.
  1677. // If tile size has changed, we are likely in the middle of changing
  1678. // video mode. No need to resotre FIFO in this case.
  1679. if ( CurrentDTTR == (gwNormalDTTR & 0xFFC0) ) { // check tile size
  1680. pREG->grDisplay_Threshold_and_Tiling =
  1681. CurrentDTTR | (gwNormalDTTR & 0x003F); // reset FIFO Threshold
  1682. }
  1683. }
  1684. }
  1685. }
  1686. }
  1687. // Clear up the ownership of Dest ColorKey.
  1688. gdwDestColorKeyOwnerVW &= ~(lpSurfaceData->dwOverlayFlags & FLG_VW_MASK);
  1689. // Clear up the ownership of Src ColorKey.
  1690. gdwSrcColorKeyOwnerVW &= ~(lpSurfaceData->dwOverlayFlags & FLG_VW_MASK);
  1691. #if 0
  1692. if (lpInput->lpDDSurface->ddsCaps.dwCaps & DDSCAPS_LIVEVIDEO)
  1693. {
  1694. // Disable Video Capture.
  1695. #pragma message("Destroy Surface")
  1696. #pragma message(" Who turned on video capture?")
  1697. #pragma message(" Shouldn't they shut it off?")
  1698. #pragma message(" How do I disable video capture on this fraggin' thing?")
  1699. }
  1700. #endif
  1701. }
  1702. /***************************************************************************
  1703. *
  1704. * FUNCTION: FlipOverlaySurface
  1705. *
  1706. * DESCRIPTION: This function is called by DDDRV when it wants to flip the
  1707. * overlay surface.
  1708. *
  1709. ****************************************************************************/
  1710. STATIC DWORD FlipOverlaySurface
  1711. (
  1712. #ifdef WINNT_VER40
  1713. PDEV *ppdev,
  1714. PDD_FLIPDATA lpFlipData
  1715. #else
  1716. LPDDHAL_FLIPDATA lpFlipData
  1717. #endif
  1718. )
  1719. {
  1720. #ifndef WINNT_VER40
  1721. LPGLOBALDATA lpDDHALData = GetDDHALContext( lpFlipData->lpDD);
  1722. #endif
  1723. DWORD dwOffset,dwOffset2;
  1724. LP_SURFACE_DATA lpSurfaceData;
  1725. DWORD dwFourcc;
  1726. DWORD dwBitCount;
  1727. PVGAR pREG = (PVGAR)lpDDHALData->RegsAddress;
  1728. DWORD dwVWIndex;
  1729. #if DDRAW_COMPAT >= 50
  1730. DWORD dwControl0;
  1731. DWORD dwSrfFlags = FALSE;
  1732. #endif
  1733. DWORD dwSurfBase, dwSurfOffset;
  1734. #ifndef WINNT_VER40
  1735. DBG_MESSAGE(("FlipOverlaySurface (lpFlipData = 0x%08lX)", lpFlipData));
  1736. #endif
  1737. if (0 == lpFlipData->lpSurfCurr->dwReserved1)
  1738. {
  1739. lpFlipData->ddRVal = DDERR_NOTAOVERLAYSURFACE;
  1740. return DDHAL_DRIVER_HANDLED;
  1741. }
  1742. lpSurfaceData = GET_SURFACE_DATA_PTR(lpFlipData->lpSurfCurr);
  1743. dwVWIndex = GetVideoWindowIndex(lpSurfaceData->dwOverlayFlags);
  1744. ASSERT(dwNumVideoWindows > dwVWIndex);
  1745. // When TVTap/VPM is used with DirectDraw, things got more twisted.
  1746. // VPM doesn't call UpdateSurface, so lpHardwareOwner
  1747. // won't be set, nevertheless, the HW is grabbed by VPM.
  1748. // In that case, should fail the Flip call to prevent bad VPM.
  1749. // YUCK!!!
  1750. // The VWE bit in the hardware seems to be the semaphore for sharing the
  1751. // overlay with VPM
  1752. if ((lpHardwareOwner[dwVWIndex] == NULL) &&
  1753. #ifdef WINNT_VER40
  1754. IsVWHardwareInUse(ppdev, dwVWIndex)
  1755. #else
  1756. IsVWHardwareInUse(lpDDHALData,dwVWIndex)
  1757. #endif
  1758. )
  1759. {
  1760. #ifndef WINNT_VER40
  1761. DBG_MESSAGE(("VW %ld already in use, Out of Caps!", dwVWIndex));
  1762. #endif
  1763. lpFlipData->ddRVal = DDERR_OUTOFCAPS;
  1764. return (DDHAL_DRIVER_HANDLED);
  1765. }
  1766. #ifdef WINNT_VER40
  1767. if(GetOverlayFlipStatus(ppdev, 0, dwVWIndex) != DD_OK || DRAW_ENGINE_BUSY || IN_VBLANK)
  1768. #else
  1769. if(GetOverlayFlipStatus(lpDDHALData,0, dwVWIndex) != DD_OK || DRAW_ENGINE_BUSY || IN_VBLANK)
  1770. #endif
  1771. {
  1772. lpFlipData->ddRVal = DDERR_WASSTILLDRAWING;
  1773. return DDHAL_DRIVER_HANDLED;
  1774. }
  1775. // Determine the format of the video data
  1776. if (lpFlipData->lpSurfTarg->dwFlags & DDRAWISURF_HASPIXELFORMAT)
  1777. {
  1778. GetFormatInfo (&(lpFlipData->lpSurfTarg->lpGbl->ddpfSurface),
  1779. &dwFourcc,
  1780. &dwBitCount);
  1781. }
  1782. else
  1783. {
  1784. dwBitCount = BITSPERPIXEL;
  1785. }
  1786. // Determine the offset to the new area.
  1787. #ifdef WINNT_VER40
  1788. dwSurfBase = lpFlipData->lpSurfTarg->lpGbl->fpVidMem;
  1789. #else
  1790. dwSurfBase = (lpFlipData->lpSurfTarg->lpGbl->fpVidMem - lpDDHALData->ScreenAddress);
  1791. #endif
  1792. dwSurfOffset = lpSurfaceData->dwOverlayOffset;
  1793. dwOffset = dwSurfBase + dwSurfOffset;
  1794. #if ENABLE_MIRRORING
  1795. // Flip the overlay surface by changing PSD_STRT_ADDR
  1796. if (bIsVWMirrored[dwVWIndex])
  1797. {
  1798. // for mirroring
  1799. // point to the last byte of the last pixel on the right edge of the source
  1800. dwOffset += (DWORD)(grOverlaySrc[dwVWIndex].right -
  1801. grOverlaySrc[dwVWIndex].left - 1);
  1802. }
  1803. #endif
  1804. dwOffset2 = 0;
  1805. #if DDRAW_COMPAT >= 50
  1806. dwControl0 = pREG->VideoWindow[dwVWIndex].grVW_CONTROL0;
  1807. if(lpFlipData->lpSurfTarg->lpSurfMore->lpVideoPort != NULL)
  1808. {
  1809. if(( lpFlipData->lpSurfTarg->lpSurfMore->dwOverlayFlags & DDOVER_AUTOFLIP)
  1810. &&(lpFlipData->lpSurfTarg->lpSurfMore->lpVideoPort->ddvpInfo.dwVPFlags
  1811. &DDVP_AUTOFLIP)
  1812. && (lpFlipData->lpSurfTarg->lpAttachListFrom != NULL)
  1813. && (lpFlipData->lpSurfTarg->lpAttachListFrom->lpAttached != NULL))
  1814. {
  1815. dwSrfFlags = DDOVER_AUTOFLIP;
  1816. }
  1817. else if(( lpFlipData->lpSurfTarg->lpSurfMore->dwOverlayFlags & DDOVER_BOB)
  1818. &&(lpFlipData->lpSurfTarg->lpSurfMore->lpVideoPort->ddvpInfo.dwVPFlags
  1819. & DDVP_INTERLEAVE))
  1820. {
  1821. dwSrfFlags = DDOVER_BOB;
  1822. //Smooth interlace
  1823. dwOffset2 = dwOffset +
  1824. lpFlipData->lpSurfTarg->lpGbl->lPitch; //point to the next line
  1825. }
  1826. }
  1827. if(dwSrfFlags & DDOVER_BOB)
  1828. {
  1829. //Smooth interlace
  1830. dwOffset2 = dwOffset +
  1831. lpFlipData->lpSurfTarg->lpGbl->lPitch; //point to the next line
  1832. }
  1833. else if(dwSrfFlags & DDOVER_AUTOFLIP)
  1834. {
  1835. //Auto Flip Overlay
  1836. dwOffset2 = lpSurfaceData->dwAutoBaseAddr2 + dwSurfOffset;
  1837. if(dwOffset2 == dwOffset)
  1838. {
  1839. dwOffset = lpSurfaceData->dwAutoBaseAddr1 + dwSurfOffset;
  1840. }
  1841. //For non-smooth-interlaced auto-flip these two address need
  1842. // to be switched. HW BUG
  1843. if(!(lpFlipData->lpSurfTarg->lpSurfMore->dwOverlayFlags & DDOVER_BOB))
  1844. {
  1845. DWORD dwTmp = dwOffset;
  1846. dwOffset = dwOffset2;
  1847. dwOffset2 = dwTmp;
  1848. }
  1849. }
  1850. else if( lpFlipData->lpSurfTarg->lpSurfMore->dwOverlayFlags & DDOVER_INTERLEAVED)
  1851. {
  1852. dwControl0 &= ~0x30000;
  1853. if(lpFlipData->dwFlags & DDFLIP_ODD) //SW flip
  1854. {
  1855. dwOffset2 = dwOffset +
  1856. lpFlipData->lpSurfTarg->lpGbl->lPitch ; //point to the next line
  1857. dwControl0 |= 0x10000; //use VW_SDD
  1858. }
  1859. }
  1860. else if(lpFlipData->dwFlags & DDFLIP_ODD) //SW flip
  1861. {
  1862. dwOffset2 = dwOffset;
  1863. dwControl0 &= ~0x30000;
  1864. dwControl0 |= 0x10000; //use VW_SDD
  1865. }
  1866. #endif
  1867. // write new start address to hardware
  1868. #ifdef WINNT_VER40
  1869. WaitForVWArmToClear(ppdev,dwVWIndex);
  1870. #else
  1871. WaitForVWArmToClear(lpDDHALData,dwVWIndex);
  1872. #endif
  1873. ASSERT(! (pREG->VideoWindow[dwVWIndex].grVW_TEST0 & VW_PostImed));
  1874. LL32(VideoWindow[dwVWIndex].grVW_PSD_STRT_ADDR, dwOffset);
  1875. LL32(VideoWindow[dwVWIndex].grVW_SSD_STRT_ADDR, dwOffset2);
  1876. #if ENABLE_YUVPLANAR
  1877. if (lpSurfaceData->dwOverlayFlags & FLG_YUVPLANAR)
  1878. {
  1879. // PSD_STRT_ADDR has been set to the start of the Y data in aperture0
  1880. // set PSD_UVSTRT_ADDR to start of UV interleaved data in aperture 0
  1881. // UV data is only half the height of Y data
  1882. LL32(VideoWindow[dwVWIndex].grVW_PSD_UVSTRT_ADDR,
  1883. dwSurfBase +
  1884. (((lpFlipData->lpSurfTarg->lpGbl->wHeight * lpFlipData->lpSurfTarg->lpGbl->lPitch) + 7) & ~7) +
  1885. (dwSurfOffset / 2));
  1886. LL32(VideoWindow[dwVWIndex].grVW_SSD_UVSTRT_ADDR, dwOffset2);
  1887. }
  1888. #endif
  1889. #if DDRAW_COMPAT >= 50
  1890. if (lpSurfaceData->dwOverlayFlags & FLG_ENABLED)
  1891. pREG->VideoWindow[dwVWIndex].grVW_CONTROL0 = (dwControl0 |VW_VWE | VW_ARM);
  1892. else
  1893. pREG->VideoWindow[dwVWIndex].grVW_CONTROL0 = dwControl0 | VW_ARM;
  1894. #else
  1895. if (lpSurfaceData->dwOverlayFlags & FLG_ENABLED)
  1896. pREG->VideoWindow[dwVWIndex].grVW_CONTROL0 |= (VW_VWE | VW_ARM);
  1897. else
  1898. pREG->VideoWindow[dwVWIndex].grVW_CONTROL0 |= VW_ARM;
  1899. #endif
  1900. #ifdef WINNT_VER40
  1901. // Update the hardware owner
  1902. lpHardwareOwner[dwVWIndex] = lpFlipData->lpSurfTarg;
  1903. #endif
  1904. // remember where/when we were when we did the flip
  1905. #ifdef WINNT_VER40
  1906. EngQueryPerformanceCounter(&gsOverlayFlip.liFlipTime);
  1907. #else
  1908. QueryPerformanceCounter((LARGE_INTEGER *)&gsOverlayFlip.liFlipTime);
  1909. #endif
  1910. #ifdef WINNT_VER40
  1911. gsOverlayFlip.dwFlipScanline = CurrentVLine(ppdev);
  1912. #else
  1913. gsOverlayFlip.dwFlipScanline = CurrentVLine(lpDDHALData);
  1914. #endif
  1915. gsOverlayFlip.bFlipFlag = TRUE;
  1916. gsOverlayFlip.fpFlipFrom = lpFlipData->lpSurfCurr->lpGbl->fpVidMem;
  1917. gsOverlayFlip.bHaveEverCrossedVBlank = FALSE;
  1918. if (IN_VBLANK)
  1919. {
  1920. gsOverlayFlip.bWasEverInDisplay = FALSE;
  1921. }
  1922. else
  1923. {
  1924. gsOverlayFlip.bWasEverInDisplay = TRUE;
  1925. }
  1926. lpFlipData->ddRVal = DD_OK;
  1927. return DDHAL_DRIVER_HANDLED;
  1928. }
  1929. /***************************************************************************
  1930. *
  1931. * FUNCTION: LockSurface
  1932. *
  1933. * DESCRIPTION: Checks for flipping before allowing access to the surface.
  1934. *
  1935. ****************************************************************************/
  1936. STATIC DWORD LockSurface
  1937. (
  1938. #ifdef WINNT_VER40
  1939. PDEV *ppdev,
  1940. PDD_LOCKDATA lpInput
  1941. #else
  1942. LPDDHAL_LOCKDATA lpInput
  1943. #endif
  1944. )
  1945. {
  1946. #if ENABLE_YUVPLANAR
  1947. LPCLPLSURFACE lpCLPL; // pointer to our YUV planar
  1948. DWORD dwUVOffset;
  1949. #endif
  1950. LP_SURFACE_DATA lpSurfaceData;
  1951. DWORD dwVWIndex;
  1952. #ifndef WINNT_VER40
  1953. LPGLOBALDATA lpDDHALData = GetDDHALContext( lpInput->lpDD);
  1954. #endif
  1955. #ifndef WINNT_VER40
  1956. DBG_MESSAGE(("Overlay LockSurface (lpInput = 0x%08lX)", lpInput));
  1957. #endif
  1958. if (0 == lpInput->lpDDSurface->dwReserved1)
  1959. {
  1960. lpInput->ddRVal = DDERR_NOTAOVERLAYSURFACE;
  1961. return DDHAL_DRIVER_HANDLED;
  1962. }
  1963. lpSurfaceData = GET_SURFACE_DATA_PTR(lpInput->lpDDSurface);
  1964. dwVWIndex = GetVideoWindowIndex(lpSurfaceData->dwOverlayFlags);
  1965. ASSERT(dwNumVideoWindows > dwVWIndex);
  1966. // Check for flipping
  1967. if ((gsOverlayFlip.bFlipFlag) &&
  1968. (
  1969. #ifdef WINNT_VER40
  1970. GetOverlayFlipStatus(ppdev, lpInput->lpDDSurface->lpGbl->fpVidMem, dwVWIndex)
  1971. #else
  1972. GetOverlayFlipStatus(lpDDHALData,lpInput->lpDDSurface->lpGbl->fpVidMem, dwVWIndex)
  1973. #endif
  1974. == DDERR_WASSTILLDRAWING))
  1975. {
  1976. lpInput->ddRVal = DDERR_WASSTILLDRAWING;
  1977. return DDHAL_DRIVER_HANDLED;
  1978. }
  1979. #if ENABLE_YUVPLANAR
  1980. if (lpSurfaceData->dwOverlayFlags & FLG_YUVPLANAR)
  1981. {
  1982. // make sure CLPL aperture is mapped in
  1983. if (! lpDDHALData->dwCLPLAperture)
  1984. {
  1985. lpInput->ddRVal = DD_OK;
  1986. return DDHAL_DRIVER_NOTHANDLED;
  1987. }
  1988. // here's how this YUV420/YUVPLANAR/CLPL stuff works:
  1989. // the CLPL surface consists of all the Y data followed by a region of
  1990. // UV interleaved data. We are currently supporting only linear surfaces
  1991. // for CLPL so there will be wHeight lines of Y data followed by wHeight/2
  1992. // lines of UV interleaved data. CreateSurface32 has padded the surface
  1993. // allocation such that the UV interleaved data will start on the first
  1994. // quadword boundary following the Y data.
  1995. //
  1996. // We pass back a pointer to a structure containing the address of a Y
  1997. // region, a U region and a V region to the app. The app writes to the
  1998. // U and V regions as if they are linear and the hardware converts this
  1999. // data into the UV interleaved data in aperture 0.
  2000. //
  2001. // For the U ptr we give the app an address pointing somewhere in the
  2002. // first four meg of aperture 3 and for the V ptr we give the app an
  2003. // address pointing to the same somewhere but in the second four meg
  2004. // of aperture 3. When the app writes to these addresses, the data
  2005. // shows up in aperture 0 such that:
  2006. // the U data is at ap0_offset = ap3_offset * 2
  2007. // the V data is at ap0_offset = (ap3_offset - 4MB) * 2 + 1
  2008. //
  2009. // what we need to do then is give the app the folloing ptrs:
  2010. // Y ptr = ap0_offset of the Y region (the beginning of the surface)
  2011. // U ptr = ap3_offset for U data = U_ap0_offset / 2
  2012. // V ptr = ap3_offset for V data = (V_ap0_offset - 1) / 2 + 4MB
  2013. // where U_ap0_offset = offset we want the U data to start
  2014. // and V_ap0_offset = offset we want the V data to start
  2015. // we also need V_ap0_offset = U_ap0_offset + 1
  2016. // Compute Y and UV aperture in frame buffer
  2017. lpCLPL = (LPCLPLSURFACE)lpSurfaceData->lpCLPLData;
  2018. lpInput->lpSurfData = (LPVOID)lpCLPL;
  2019. // Y data starts at beginning of surface in aperture0
  2020. lpCLPL->fpYSurface = (LPVOID)lpInput->lpDDSurface->lpGbl->fpVidMem;
  2021. DBG_MESSAGE(("Aperture0 Y offset = %08lX",
  2022. (lpInput->lpDDSurface->lpGbl->fpVidMem - lpDDHALData->ScreenAddress)));
  2023. DBG_MESSAGE((" surface height = %08lX, pitch = %08lX",
  2024. lpInput->lpDDSurface->lpGbl->wHeight,
  2025. lpInput->lpDDSurface->lpGbl->lPitch));
  2026. // determine offset of UV data in aperture 0 (and make it qword aligned)
  2027. dwUVOffset = (lpInput->lpDDSurface->lpGbl->fpVidMem - lpDDHALData->ScreenAddress) +
  2028. (((lpInput->lpDDSurface->lpGbl->wHeight * lpInput->lpDDSurface->lpGbl->lPitch) + 7) & ~7);
  2029. DBG_MESSAGE(("Aperture0 UV offset = %08lX", dwUVOffset));
  2030. // convert UV aperture0 offset to aperture3 offset
  2031. DBG_MESSAGE(("Aperture3 UV offset = %08lX", dwUVOffset / 2));
  2032. dwUVOffset = lpDDHALData->dwCLPLAperture + dwUVOffset / 2;
  2033. if (bCLPLLobotomyMode)
  2034. {
  2035. lpCLPL->fpRealUSurface = (LPVOID)(dwUVOffset);
  2036. lpCLPL->fpRealVSurface = (LPVOID)(dwUVOffset + 0x400000);
  2037. DBG_MESSAGE(("CLPL lobotomy mode addrs: RealU=%08lX, RealV=%08lX",
  2038. lpCLPL->fpRealUSurface, lpCLPL->fpRealVSurface));
  2039. lpCLPL->fpUSurface = lpCLPL->fpUSystemSurface;
  2040. lpCLPL->fpVSurface = lpCLPL->fpVSystemSurface;
  2041. }
  2042. else
  2043. {
  2044. lpCLPL->fpUSurface = (LPVOID)(dwUVOffset);
  2045. lpCLPL->fpVSurface = (LPVOID)(dwUVOffset + 0x400000);
  2046. }
  2047. DBG_MESSAGE(("CLPL addrs: Y=%08lX, U=%08lX, V=%08lX",
  2048. lpCLPL->fpYSurface, lpCLPL->fpUSurface, lpCLPL->fpVSurface));
  2049. lpInput->ddRVal = DD_OK;
  2050. return DDHAL_DRIVER_HANDLED;
  2051. }
  2052. #endif
  2053. #if ENABLE_YUY2
  2054. // Force them to use the byte swap aperture
  2055. if (lpSurfaceData->dwOverlayFlags & FLG_YUY2)
  2056. {
  2057. // make sure the YUY2 aperture is mapped in
  2058. if (! lpDDHALData->dwYUY2Aperture)
  2059. {
  2060. lpInput->ddRVal = DD_OK;
  2061. return DDHAL_DRIVER_NOTHANDLED;
  2062. }
  2063. lpInput->lpSurfData = (LPVOID) ((lpInput->lpDDSurface->lpGbl->fpVidMem -
  2064. lpDDHALData->ScreenAddress) +
  2065. lpDDHALData->dwYUY2Aperture);
  2066. lpInput->ddRVal = DD_OK;
  2067. return DDHAL_DRIVER_HANDLED;
  2068. }
  2069. #endif
  2070. lpInput->ddRVal = DD_OK;
  2071. return DDHAL_DRIVER_NOTHANDLED;
  2072. }
  2073. #if ENABLE_YUVPLANAR
  2074. /***************************************************************************
  2075. *
  2076. * FUNCTION: SysToFBCopy()
  2077. *
  2078. * DESCRIPTION:
  2079. *
  2080. ****************************************************************************/
  2081. #if 1
  2082. static INLINE VOID
  2083. SysToFBCopy ( BYTE *dst, LONG dstPitch, BYTE *src, LONG srcPitch, REG32 ext, LONG bpp )
  2084. {
  2085. int yext = ext.pt.Y;
  2086. int xext = ext.pt.X * bpp;
  2087. while (0 < yext--)
  2088. {
  2089. memcpy(dst,src,xext);
  2090. dst += dstPitch;
  2091. src += srcPitch;
  2092. }
  2093. }
  2094. #else
  2095. // writing the scanline from right to left shows the hwbug where roughly
  2096. // every other 4 dwords written to aperture3 is dropped
  2097. // and the video is generally display with a lovely flourescent green
  2098. // checkerboard pattern
  2099. //
  2100. // This duplicates the problem seen by allowing the Compcore MPEG player
  2101. // write directly to aperture3
  2102. #pragma optimize("", off)
  2103. // the compiler ignores __inline because of the inline assembly
  2104. static INLINE VOID
  2105. SysToFBCopy ( BYTE *dst, LONG dstPitch, BYTE *src, LONG srcPitch, REG32 ext, LONG bpp )
  2106. {
  2107. int yext = ext.pt.Y;
  2108. int xext = ext.pt.X * bpp;
  2109. _asm std
  2110. dst += dstPitch - sizeof(DWORD);
  2111. src += srcPitch - sizeof(DWORD);
  2112. while (0 < yext--)
  2113. {
  2114. _asm
  2115. {
  2116. mov eax,xext
  2117. mov edi,dst
  2118. mov esi,src
  2119. mov ecx,eax
  2120. shr ecx,2
  2121. rep movsd
  2122. mov ecx,eax
  2123. and ecx,3
  2124. rep movsb
  2125. }
  2126. dst += dstPitch;
  2127. src += srcPitch;
  2128. }
  2129. _asm cld
  2130. }
  2131. #pragma optimize("", on)
  2132. #endif
  2133. #endif
  2134. /***************************************************************************
  2135. *
  2136. * FUNCTION: UnlockSurface
  2137. *
  2138. * DESCRIPTION: This function is called by DDHAL when it is finished accessing
  2139. * the frame buffer.
  2140. *
  2141. ****************************************************************************/
  2142. STATIC VOID UnlockSurface
  2143. (
  2144. #ifdef WINNT_VER40
  2145. PDEV *ppdev,
  2146. PDD_UNLOCKDATA lpInput
  2147. #else
  2148. LPDDHAL_UNLOCKDATA lpInput
  2149. #endif
  2150. )
  2151. {
  2152. #if ENABLE_YUVPLANAR
  2153. LPCLPLSURFACE lpCLPL; // pointer to our YUV planar
  2154. #endif
  2155. LP_SURFACE_DATA lpSurfaceData;
  2156. #ifndef WINNT_VER40
  2157. DBG_MESSAGE(("Overlay UnlockSurface (lpInput = 0x%08lX)", lpInput));
  2158. #endif
  2159. if (0 == lpInput->lpDDSurface->dwReserved1)
  2160. {
  2161. lpInput->ddRVal = DDERR_NOTAOVERLAYSURFACE;
  2162. return;
  2163. }
  2164. lpSurfaceData = GET_SURFACE_DATA_PTR(lpInput->lpDDSurface);
  2165. #if ENABLE_YUVPLANAR
  2166. if ((lpSurfaceData->dwOverlayFlags & FLG_YUVPLANAR) && bCLPLLobotomyMode)
  2167. {
  2168. REG32 ext;
  2169. LONG pitch;
  2170. lpCLPL = (LPCLPLSURFACE)lpSurfaceData->lpCLPLData;
  2171. ext.pt.X = lpInput->lpDDSurface->lpGbl->wWidth / 2;
  2172. ext.pt.Y = lpInput->lpDDSurface->lpGbl->wHeight / 2;
  2173. pitch = lpInput->lpDDSurface->lpGbl->lPitch / 2;
  2174. SysToFBCopy(lpCLPL->fpRealUSurface, pitch, lpCLPL->fpUSystemSurface, pitch, ext, 1);
  2175. SysToFBCopy(lpCLPL->fpRealVSurface, pitch, lpCLPL->fpVSystemSurface, pitch, ext, 1);
  2176. }
  2177. #endif
  2178. }
  2179. /***************************************************************************
  2180. *
  2181. * FUNCTION: SetColorKey
  2182. *
  2183. * DESCRIPTION: Looks at the color key for changes in the while
  2184. * overlay is active.
  2185. *
  2186. ****************************************************************************/
  2187. STATIC VOID SetColorKey
  2188. (
  2189. #ifdef WINNT_VER40
  2190. PDEV *ppdev,
  2191. PDD_SETCOLORKEYDATA lpInput
  2192. #else
  2193. LPDDHAL_SETCOLORKEYDATA lpInput
  2194. #endif
  2195. )
  2196. {
  2197. LP_SURFACE_DATA lpSurfaceData;
  2198. LP_SURFACE_DATA lpHWOwnerData;
  2199. DWORD dwVWIndex;
  2200. #ifndef WINNT_VER40
  2201. LPGLOBALDATA lpDDHALData = GetDDHALContext( lpInput->lpDD);
  2202. #endif
  2203. #ifndef WINNT_VER40
  2204. DBG_MESSAGE(("Overlay SetColorKey (lpInput = 0x%08lX)", lpInput));
  2205. #endif
  2206. if (0 == lpInput->lpDDSurface->dwReserved1)
  2207. {
  2208. lpInput->ddRVal = DDERR_NOTAOVERLAYSURFACE;
  2209. return;
  2210. }
  2211. lpSurfaceData = GET_SURFACE_DATA_PTR(lpInput->lpDDSurface);
  2212. dwVWIndex = GetVideoWindowIndex(lpSurfaceData->dwOverlayFlags);
  2213. ASSERT(dwNumVideoWindows > dwVWIndex);
  2214. if ((lpInput->dwFlags & DDCKEY_DESTOVERLAY) &&
  2215. (lpInput->lpDDSurface == lpColorSurfaceVW[dwVWIndex]))
  2216. {
  2217. // See if someone else is already using the colorkey.
  2218. if ((gdwDestColorKeyOwnerVW & FLG_VW_MASK) &&
  2219. (lpInput->lpDDSurface != lpColorSurfaceVW[dwVWIndex]))
  2220. {
  2221. // ColorKey already being used.
  2222. lpInput->ddRVal = DDERR_OUTOFCAPS;
  2223. return;
  2224. }
  2225. // You get here only when the call is issued AFTER UpdateOverlay.
  2226. gdwColorKey = lpInput->ckNew.dwColorSpaceLowValue;
  2227. if (0 == lpHardwareOwner[dwVWIndex]->dwReserved1)
  2228. {
  2229. lpInput->ddRVal = DDERR_NOTAOVERLAYSURFACE;
  2230. return;
  2231. }
  2232. lpHWOwnerData = GET_SURFACE_DATA_PTR(lpHardwareOwner[dwVWIndex]);
  2233. if ((lpInput->lpDDSurface == lpColorSurfaceVW[dwVWIndex]) &&
  2234. (lpHardwareOwner[dwVWIndex]) &&
  2235. (lpHWOwnerData->dwOverlayFlags & FLG_ENABLED))
  2236. {
  2237. gdwDestColorKeyOwnerVW = MakeVideoWindowFlag(dwVWIndex);
  2238. lpHWOwnerData->dwOverlayFlags |= FLG_COLOR_KEY;
  2239. #ifdef WINNT_VER40
  2240. RegInitVideoVW(ppdev, dwVWIndex, lpHardwareOwner[dwVWIndex]);
  2241. #else
  2242. RegInitVideoVW(dwVWIndex, lpHardwareOwner[dwVWIndex],lpDDHALData);
  2243. #endif
  2244. }
  2245. }
  2246. else if ((lpInput->dwFlags & DDCKEY_SRCOVERLAY) &&
  2247. (lpInput->lpDDSurface == lpSrcColorSurfaceVW[dwVWIndex]))
  2248. {
  2249. // See if someone else already uses the colorkey.
  2250. if ((gdwSrcColorKeyOwnerVW != 0 ) &&
  2251. !(gdwSrcColorKeyOwnerVW & lpSurfaceData->dwOverlayFlags))
  2252. {
  2253. // ColorKey already been used.
  2254. lpInput->ddRVal = DDERR_OUTOFCAPS;
  2255. return;
  2256. }
  2257. gdwSrcColorKeyLow = lpInput->ckNew.dwColorSpaceLowValue;
  2258. gdwSrcColorKeyHigh = lpInput->ckNew.dwColorSpaceHighValue;
  2259. if (gdwSrcColorKeyLow > gdwSrcColorKeyHigh)
  2260. {
  2261. gdwSrcColorKeyHigh = gdwSrcColorKeyLow;
  2262. }
  2263. if (0 == lpHardwareOwner[dwVWIndex]->dwReserved1)
  2264. {
  2265. lpInput->ddRVal = DDERR_NOTAOVERLAYSURFACE;
  2266. return;
  2267. }
  2268. lpHWOwnerData = GET_SURFACE_DATA_PTR(lpHardwareOwner[dwVWIndex]);
  2269. if ((lpSurfaceData->dwOverlayFlags & FLG_VW_MASK) &&
  2270. (lpHardwareOwner[dwVWIndex]) &&
  2271. (lpHWOwnerData->dwOverlayFlags & FLG_ENABLED))
  2272. {
  2273. gdwSrcColorKeyOwnerVW = MakeVideoWindowFlag(dwVWIndex);
  2274. lpHWOwnerData->dwOverlayFlags |= FLG_SRC_COLOR_KEY;
  2275. #ifdef WINNT_VER40
  2276. RegInitVideoVW(ppdev, dwVWIndex, lpHardwareOwner[dwVWIndex]);
  2277. #else
  2278. RegInitVideoVW(dwVWIndex, lpHardwareOwner[dwVWIndex],lpDDHALData);
  2279. #endif
  2280. }
  2281. }
  2282. }
  2283. /***************************************************************************
  2284. *
  2285. * FUNCTION: SaveRectangles
  2286. *
  2287. * DESCRIPTION:
  2288. *
  2289. ****************************************************************************/
  2290. static INLINE BOOL SaveRectangles
  2291. (
  2292. #ifdef WINNT_VER40
  2293. PDEV *ppdev,
  2294. #endif
  2295. DWORD dwVWIndex,
  2296. BOOL bCheckBandwidth,
  2297. DWORD dwBitCount,
  2298. #ifdef WINNT_VER40
  2299. PDD_UPDATEOVERLAYDATA lpInput
  2300. #else
  2301. LPDDHAL_UPDATEOVERLAYDATA lpInput,
  2302. LPGLOBALDATA lpDDHALData
  2303. #endif
  2304. )
  2305. {
  2306. SIZEL Dst;
  2307. SIZEL Src;
  2308. BWREGS bwregs;
  2309. // Is there sufficient bandwidth to work?
  2310. gvidConfig.sizSrc.cx = lpInput->rSrc.right - lpInput->rSrc.left;
  2311. gvidConfig.sizSrc.cy = lpInput->rSrc.bottom - lpInput->rSrc.top;
  2312. gvidConfig.sizDisp.cx = lpInput->rDest.right - lpInput->rDest.left;
  2313. gvidConfig.sizDisp.cy = lpInput->rDest.bottom - lpInput->rDest.top;
  2314. gvidConfig.uSrcDepth = dwBitCount;
  2315. gvidConfig.uDispDepth = dwBitCount; //video window has the same as source
  2316. gvidConfig.uGfxDepth = BITSPERPIXEL;
  2317. gvidConfig.dwFlags |= VCFLG_DISP;
  2318. #ifdef WINNT_VER40
  2319. ChipIOReadBWRegs(ppdev, &bwregs);
  2320. #else
  2321. ChipIOReadBWRegs(lpDDHALData, &bwregs);
  2322. #endif
  2323. if (bCheckBandwidth && bUseBWEqn &&
  2324. !ChipIsEnoughBandwidth(&gsProgRegs, &gvidConfig, &bwregs)
  2325. )
  2326. {
  2327. gvidConfig.dwFlags &= ~VCFLG_DISP;
  2328. lpInput->ddRVal = DDERR_OUTOFCAPS;
  2329. return FALSE;
  2330. }
  2331. // Save the rectangles
  2332. #ifndef WINNT_VER40
  2333. DBG_MESSAGE(("rSrc = %lX,%lX %lX,%lX",
  2334. lpInput->rSrc.left,lpInput->rSrc.top,
  2335. lpInput->rSrc.right,lpInput->rSrc.bottom));
  2336. DBG_MESSAGE(("rcOverlaySrc = %lX,%lX %lX,%lX",
  2337. lpInput->lpDDSrcSurface->rcOverlaySrc.left,
  2338. lpInput->lpDDSrcSurface->rcOverlaySrc.top,
  2339. lpInput->lpDDSrcSurface->rcOverlaySrc.right,
  2340. lpInput->lpDDSrcSurface->rcOverlaySrc.bottom));
  2341. #endif
  2342. grOverlaySrc[dwVWIndex].left = (int)lpInput->rSrc.left;
  2343. grOverlaySrc[dwVWIndex].right = (int)lpInput->rSrc.right;
  2344. grOverlaySrc[dwVWIndex].top = (int)lpInput->rSrc.top;
  2345. grOverlaySrc[dwVWIndex].bottom = (int)lpInput->rSrc.bottom;
  2346. #ifndef WINNT_VER40
  2347. DBG_MESSAGE(("rDest = %lX,%lX %lX,%lX",
  2348. lpInput->rDest.left,lpInput->rDest.top,
  2349. lpInput->rDest.right,lpInput->rDest.bottom));
  2350. DBG_MESSAGE(("rcOverlayDest = %lX,%lX %lX,%lX",
  2351. lpInput->lpDDSrcSurface->rcOverlayDest.left,
  2352. lpInput->lpDDSrcSurface->rcOverlayDest.top,
  2353. lpInput->lpDDSrcSurface->rcOverlayDest.right,
  2354. lpInput->lpDDSrcSurface->rcOverlayDest.bottom));
  2355. #endif
  2356. grOverlayDest[dwVWIndex].left = (int)lpInput->rDest.left;
  2357. grOverlayDest[dwVWIndex].right = (int)lpInput->rDest.right;
  2358. grOverlayDest[dwVWIndex].top = (int)lpInput->rDest.top;
  2359. grOverlayDest[dwVWIndex].bottom = (int)lpInput->rDest.bottom;
  2360. // make sure resize is within hw capabilities
  2361. // x can shrink down to 1/2 and stretch up to 8x
  2362. // y can stretch up to 8x
  2363. Dst.cx = grOverlayDest[dwVWIndex].right - grOverlayDest[dwVWIndex].left;
  2364. Dst.cy = grOverlayDest[dwVWIndex].bottom - grOverlayDest[dwVWIndex].top;
  2365. Src.cx = grOverlaySrc[dwVWIndex].right - grOverlaySrc[dwVWIndex].left;
  2366. Src.cy = grOverlaySrc[dwVWIndex].bottom - grOverlaySrc[dwVWIndex].top;
  2367. #ifdef WINNT_VER40
  2368. if (Dst.cx > (LONG)(lpDDHALData->dwMaxOverlayStretch * Src.cx / 1000))
  2369. #else
  2370. if (Dst.cx > (LONG)(lpDDHALData->HALInfo.ddCaps.dwMaxOverlayStretch * Src.cx / 1000))
  2371. #endif
  2372. {
  2373. lpInput->ddRVal = DDERR_TOOBIGWIDTH;
  2374. return FALSE;
  2375. }
  2376. #ifdef WINNT_VER40
  2377. else if (Dst.cy > (LONG)(lpDDHALData->dwMaxOverlayStretch * Src.cy / 1000))
  2378. #else
  2379. else if (Dst.cy > (LONG)(lpDDHALData->HALInfo.ddCaps.dwMaxOverlayStretch * Src.cy / 1000))
  2380. #endif
  2381. {
  2382. lpInput->ddRVal = DDERR_TOOBIGHEIGHT;
  2383. return FALSE;
  2384. }
  2385. #ifdef WINNT_VER40
  2386. else if (Dst.cx < (LONG)(lpDDHALData->dwMinOverlayStretch * Src.cx / 1000))
  2387. #else
  2388. else if (Dst.cx < (LONG)(lpDDHALData->HALInfo.ddCaps.dwMinOverlayStretch * Src.cx / 1000))
  2389. #endif
  2390. {
  2391. lpInput->ddRVal = DDERR_UNSUPPORTED; // too small width
  2392. return FALSE;
  2393. }
  2394. if (MIN_OLAY_WIDTH >= Src.cx)
  2395. {
  2396. lpInput->ddRVal = DDERR_OUTOFCAPS;
  2397. return FALSE;
  2398. }
  2399. return TRUE;
  2400. }
  2401. /***************************************************************************
  2402. *
  2403. * FUNCTION: UpdateSurface
  2404. *
  2405. * DESCRIPTION:
  2406. *
  2407. ****************************************************************************/
  2408. STATIC DWORD UpdateSurface
  2409. (
  2410. #ifdef WINNT_VER40
  2411. PDEV *ppdev,
  2412. PDD_UPDATEOVERLAYDATA lpInput
  2413. #else
  2414. LPDDHAL_UPDATEOVERLAYDATA lpInput
  2415. #endif
  2416. )
  2417. {
  2418. DWORD dwOldStatus;
  2419. DWORD dwFourcc;
  2420. BOOL bCheckBandwidth;
  2421. DWORD dwBitCount;
  2422. DWORD dwDestColorKey;
  2423. LP_SURFACE_DATA lpSrcSurfaceData;
  2424. DWORD dwVWIndex;
  2425. DWORD dwVWFlag;
  2426. BWREGS bwregs;
  2427. BOOL bShowOverlay = FALSE;
  2428. #ifndef WINNT_VER40
  2429. LPGLOBALDATA lpDDHALData = GetDDHALContext( lpInput->lpDD);
  2430. #endif
  2431. #ifndef WINNT_VER40
  2432. DBG_MESSAGE(("Overlay UpdateSurface (lpInput = 0x%08lX)", lpInput));
  2433. #endif
  2434. if (0 == lpInput->lpDDSrcSurface->dwReserved1)
  2435. {
  2436. lpInput->ddRVal = DDERR_NOTAOVERLAYSURFACE;
  2437. return DDHAL_DRIVER_HANDLED;
  2438. }
  2439. lpSrcSurfaceData = GET_SURFACE_DATA_PTR(lpInput->lpDDSrcSurface);
  2440. if (lpInput->lpDDSrcSurface->dwFlags & DDRAWISURF_HASPIXELFORMAT)
  2441. {
  2442. GetFormatInfo(&(lpInput->lpDDSrcSurface->lpGbl->ddpfSurface),
  2443. &dwFourcc, &dwBitCount);
  2444. }
  2445. else
  2446. {
  2447. dwBitCount = BITSPERPIXEL;
  2448. if (16 == dwBitCount)
  2449. dwFourcc = BI_BITFIELDS; // 5:6:5
  2450. else
  2451. dwFourcc = BI_RGB; // 8bpp, 5:5:5, 24bpp & 32bpp
  2452. }
  2453. gvidConfig.dwFlags &= ~(VCFLG_COLORKEY | VCFLG_CHROMAKEY |
  2454. VCFLG_DISP | VCFLG_420);
  2455. #if ENABLE_YUVPLANAR
  2456. if (lpSrcSurfaceData->dwOverlayFlags & FLG_YUVPLANAR)
  2457. gvidConfig.dwFlags |= VCFLG_420;
  2458. #endif
  2459. // Are we color keying?
  2460. bCheckBandwidth = TRUE;
  2461. dwOldStatus = lpSrcSurfaceData->dwOverlayFlags;
  2462. dwVWIndex = GetVideoWindowIndex(dwOldStatus);
  2463. ASSERT(dwNumVideoWindows > dwVWIndex);
  2464. dwVWFlag = MakeVideoWindowFlag(dwVWIndex);
  2465. lpColorSurfaceVW[dwVWIndex] = lpSrcColorSurfaceVW[dwVWIndex] = NULL;
  2466. #if ENABLE_MIRRORING
  2467. bIsVWMirrored[dwVWIndex] = FALSE;
  2468. #endif
  2469. if ((lpInput->dwFlags & (DDOVER_KEYDEST | DDOVER_KEYDESTOVERRIDE)) &&
  2470. (lpInput->dwFlags & (DDOVER_KEYSRC | DDOVER_KEYSRCOVERRIDE)))
  2471. {
  2472. // Cannot perform src colorkey and dest colorkey at the same time
  2473. lpInput->ddRVal = DDERR_NOCOLORKEYHW;
  2474. return DDHAL_DRIVER_HANDLED;
  2475. }
  2476. #if HWBUG_24BPP_DST_COLORKEY
  2477. if (
  2478. #ifdef WINNT_VER40
  2479. (24 == ppdev->ulBitCount) &&
  2480. #else
  2481. (24 == pPDevice->deBitsPixel) &&
  2482. #endif
  2483. (lpInput->dwFlags & (DDOVER_KEYDEST | DDOVER_KEYDESTOVERRIDE)))
  2484. {
  2485. // destination colorkeying at 24bpp is busted in hardware
  2486. lpInput->ddRVal = DDERR_NOCOLORKEYHW;
  2487. return DDHAL_DRIVER_HANDLED;
  2488. }
  2489. #endif
  2490. #ifdef WINNT_VER40
  2491. ChipIOReadBWRegs(ppdev, &bwregs);
  2492. #else
  2493. ChipIOReadBWRegs(lpDDHALData, &bwregs);
  2494. #endif
  2495. lpSrcSurfaceData->dwOverlayFlags &= ~(FLG_COLOR_KEY|FLG_SRC_COLOR_KEY);
  2496. #ifndef WINNT_VER40
  2497. if ( (lpInput->dwFlags == 0)
  2498. && (lpHardwareOwner[dwVWIndex] == NULL)
  2499. && (lpSrcSurfaceData->dwOverlayFlags & FLG_OVERLAY) )
  2500. {
  2501. bShowOverlay = TRUE;
  2502. }
  2503. #endif
  2504. if (lpInput->dwFlags & (DDOVER_KEYDEST | DDOVER_KEYDESTOVERRIDE))
  2505. {
  2506. dwDestColorKey = (lpInput->dwFlags & DDOVER_KEYDEST)
  2507. ? lpInput->lpDDDestSurface->ddckCKDestOverlay.dwColorSpaceLowValue
  2508. : lpInput->overlayFX.dckDestColorkey.dwColorSpaceLowValue;
  2509. // Allow colorkey override only when it's the original
  2510. // colorkey owner, or no one owns the colorkey so far.
  2511. if (gdwDestColorKeyOwnerVW == 0)
  2512. {
  2513. gdwDestColorKeyOwnerVW = dwVWFlag;
  2514. }
  2515. else if ((dwDestColorKey != gdwColorKey) &&
  2516. (dwOldStatus & dwVWFlag) &&
  2517. !(gdwDestColorKeyOwnerVW & dwVWFlag))
  2518. {
  2519. // ColorKey already been used by someone else.
  2520. // It's not the original colorkey owner,
  2521. // and the key color is not the same as the other one.
  2522. lpInput->ddRVal = DDERR_OUTOFCAPS;
  2523. return DDHAL_DRIVER_HANDLED;
  2524. }
  2525. // Is there sufficient bandwidth to work?
  2526. gvidConfig.sizSrc.cx = lpInput->rSrc.right - lpInput->rSrc.left;
  2527. gvidConfig.sizSrc.cy = lpInput->rSrc.bottom - lpInput->rSrc.top;
  2528. gvidConfig.sizDisp.cx = lpInput->rDest.right - lpInput->rDest.left;
  2529. gvidConfig.sizDisp.cy = lpInput->rDest.bottom - lpInput->rDest.top;
  2530. gvidConfig.uSrcDepth = dwBitCount;
  2531. gvidConfig.uDispDepth = dwBitCount; //video window has the same depth as
  2532. //the source
  2533. gvidConfig.uGfxDepth = BITSPERPIXEL;
  2534. gvidConfig.dwFlags |= VCFLG_COLORKEY | VCFLG_DISP;
  2535. if (!bUseBWEqn ||
  2536. ChipIsEnoughBandwidth(&gsProgRegs, &gvidConfig, &bwregs)
  2537. )
  2538. {
  2539. bCheckBandwidth = FALSE;
  2540. lpSrcSurfaceData->dwOverlayFlags |= FLG_COLOR_KEY;
  2541. if (lpInput->dwFlags & DDOVER_KEYDEST)
  2542. {
  2543. gdwColorKey = lpInput->lpDDDestSurface->ddckCKDestOverlay.dwColorSpaceLowValue;
  2544. lpColorSurfaceVW[dwVWIndex] = lpInput->lpDDDestSurface;
  2545. }
  2546. else
  2547. {
  2548. gdwColorKey = lpInput->overlayFX.dckDestColorkey.dwColorSpaceLowValue;
  2549. }
  2550. }
  2551. else
  2552. {
  2553. gvidConfig.dwFlags &= ~(VCFLG_COLORKEY | VCFLG_DISP);
  2554. lpInput->ddRVal = DDERR_NOCOLORKEYHW;
  2555. return DDHAL_DRIVER_HANDLED;
  2556. }
  2557. }
  2558. else if (lpInput->dwFlags & (DDOVER_KEYSRC | DDOVER_KEYSRCOVERRIDE))
  2559. {
  2560. // Allow SrcColorKey override only when it's the original
  2561. // colorkey owner, or no one owns the colorkey so far.
  2562. if (gdwSrcColorKeyOwnerVW == 0)
  2563. {
  2564. gdwSrcColorKeyOwnerVW = dwVWFlag;
  2565. }
  2566. else if (!(dwOldStatus & gdwSrcColorKeyOwnerVW))
  2567. {
  2568. // It's not the original colorkey owner
  2569. lpInput->ddRVal = DDERR_OUTOFCAPS;
  2570. return DDHAL_DRIVER_HANDLED;
  2571. }
  2572. // Is there sufficient bandwidth to work?
  2573. gvidConfig.sizSrc.cx = lpInput->rSrc.right - lpInput->rSrc.left;
  2574. gvidConfig.sizSrc.cy = lpInput->rSrc.bottom - lpInput->rSrc.top;
  2575. gvidConfig.sizDisp.cx = lpInput->rDest.right - lpInput->rDest.left;
  2576. gvidConfig.sizDisp.cy = lpInput->rDest.bottom - lpInput->rDest.top;
  2577. gvidConfig.uSrcDepth = dwBitCount;
  2578. gvidConfig.uDispDepth = dwBitCount; //video window has the same as source
  2579. gvidConfig.uGfxDepth = BITSPERPIXEL;
  2580. gvidConfig.dwFlags |= VCFLG_CHROMAKEY | VCFLG_DISP;
  2581. if (!bUseBWEqn ||
  2582. ChipIsEnoughBandwidth(&gsProgRegs, &gvidConfig, &bwregs)
  2583. )
  2584. {
  2585. bCheckBandwidth = FALSE;
  2586. lpSrcSurfaceData->dwOverlayFlags |= FLG_SRC_COLOR_KEY;
  2587. lpSrcColorSurfaceVW[dwVWIndex] = lpInput->lpDDSrcSurface;
  2588. if (lpInput->dwFlags & DDOVER_KEYSRC)
  2589. {
  2590. gdwSrcColorKeyLow = lpInput->lpDDSrcSurface->ddckCKSrcOverlay.dwColorSpaceLowValue;
  2591. gdwSrcColorKeyHigh = lpInput->lpDDSrcSurface->ddckCKSrcOverlay.dwColorSpaceHighValue;
  2592. }
  2593. else
  2594. {
  2595. gdwSrcColorKeyLow = lpInput->overlayFX.dckSrcColorkey.dwColorSpaceLowValue;
  2596. gdwSrcColorKeyHigh = lpInput->overlayFX.dckSrcColorkey.dwColorSpaceHighValue;
  2597. }
  2598. if (gdwSrcColorKeyHigh < gdwSrcColorKeyHigh)
  2599. {
  2600. gdwSrcColorKeyHigh = gdwSrcColorKeyLow;
  2601. }
  2602. }
  2603. else
  2604. {
  2605. gvidConfig.dwFlags &= ~(VCFLG_CHROMAKEY | VCFLG_DISP);
  2606. lpInput->ddRVal = DDERR_NOCOLORKEYHW;
  2607. return DDHAL_DRIVER_HANDLED;
  2608. }
  2609. }
  2610. #ifdef WINNT_VER40
  2611. #if 0
  2612. // The hardware is broken when using RGB32 data and ShrinkXBy2.
  2613. if ( (dwFourcc == BI_RGB) && (dwBitCount == 32)
  2614. && (gvidConfig.sizSrc.cx > gvidConfig.sizDisp.cx)
  2615. && (lpSrcSurfaceData->dwOverlayFlags & (FLG_ENABLED | 0x02000000)) )
  2616. {
  2617. if (lpSrcSurfaceData->dwOverlayFlags & FLG_ENABLED)
  2618. {
  2619. // Turn the video off.
  2620. DisableOverlay(ppdev, dwVWIndex);
  2621. lpHardwareOwner[dwVWIndex] = NULL;
  2622. lpSrcSurfaceData->dwOverlayFlags &= ~FLG_ENABLED;
  2623. lpSrcSurfaceData->dwOverlayFlags |= 0x02000000;
  2624. }
  2625. if (lpSrcSurfaceData->dwOverlayFlags & FLG_VW_MASK)
  2626. {
  2627. PVGAR pREG = (PVGAR) lpDDHALData->RegsAddress;
  2628. if (giOvlyCnt[dwVWIndex] > 0)
  2629. {
  2630. if (--giOvlyCnt[dwVWIndex] == 0)
  2631. {
  2632. // Get current DTTR, mask off FIFO threshold.
  2633. WORD CurrentDTTR = pREG->grDisplay_Threshold_and_Tiling
  2634. & 0xFFC0;
  2635. // Fix PDR 9574: Restore FIFO threshold value when overlay
  2636. // surface is destroyed, do not restore the tile size. If
  2637. // tile size has changed, we are likely in the middle of
  2638. // changing video mode. No need to restore FIFO in this
  2639. // case.
  2640. if ( CurrentDTTR == (gwNormalDTTR & 0xFFC0) )
  2641. {
  2642. pREG->grDisplay_Threshold_and_Tiling = CurrentDTTR
  2643. | (gwNormalDTTR & 0x003F);
  2644. }
  2645. }
  2646. }
  2647. }
  2648. else if (giOvlyCnt[dwVWIndex] > 0)
  2649. {
  2650. giOvlyCnt[dwVWIndex]--;
  2651. }
  2652. // Clear up the ownership of Dest ColorKey.
  2653. gdwDestColorKeyOwnerVW &= ~(lpSrcSurfaceData->dwOverlayFlags
  2654. & FLG_VW_MASK);
  2655. // Clear up the ownership of Src ColorKey.
  2656. gdwSrcColorKeyOwnerVW &= ~(lpSrcSurfaceData->dwOverlayFlags
  2657. & FLG_VW_MASK);
  2658. lpInput->ddRVal = DDERR_OUTOFCAPS;
  2659. return(DDHAL_DRIVER_HANDLED);
  2660. }
  2661. #else
  2662. // The hardware is broken when using RGB32 data and ShrinkXBy2.
  2663. if ( (dwFourcc == BI_RGB) && (dwBitCount == 32)
  2664. && (gvidConfig.sizSrc.cx > gvidConfig.sizDisp.cx)
  2665. && (lpSrcSurfaceData->dwOverlayFlags & FLG_ENABLED) )
  2666. {
  2667. // Turn the video off.
  2668. DisableOverlay(ppdev, dwVWIndex);
  2669. lpHardwareOwner[dwVWIndex] = NULL;
  2670. lpSrcSurfaceData->dwOverlayFlags &= ~FLG_ENABLED;
  2671. lpSrcSurfaceData->dwOverlayFlags |= 0x02000000;
  2672. if (lpSrcSurfaceData->dwOverlayFlags & FLG_VW_MASK)
  2673. {
  2674. PVGAR pREG = (PVGAR) lpDDHALData->RegsAddress;
  2675. if (giOvlyCnt[dwVWIndex] > 0)
  2676. {
  2677. if (--giOvlyCnt[dwVWIndex] == 0)
  2678. {
  2679. // Get current DTTR, mask off FIFO threshold.
  2680. WORD CurrentDTTR = pREG->grDisplay_Threshold_and_Tiling
  2681. & 0xFFC0;
  2682. // Fix PDR 9574: Restore FIFO threshold value when overlay
  2683. // surface is destroyed, do not restore the tile size. If
  2684. // tile size has changed, we are likely in the middle of
  2685. // changing video mode. No need to restore FIFO in this
  2686. // case.
  2687. if ( CurrentDTTR == (gwNormalDTTR & 0xFFC0) )
  2688. {
  2689. pREG->grDisplay_Threshold_and_Tiling = CurrentDTTR
  2690. | (gwNormalDTTR & 0x003F);
  2691. }
  2692. }
  2693. }
  2694. }
  2695. else if (giOvlyCnt[dwVWIndex] > 0)
  2696. {
  2697. giOvlyCnt[dwVWIndex]--;
  2698. }
  2699. // Clear up the ownership of Dest ColorKey.
  2700. gdwDestColorKeyOwnerVW &= ~(lpSrcSurfaceData->dwOverlayFlags
  2701. & FLG_VW_MASK);
  2702. // Clear up the ownership of Src ColorKey.
  2703. gdwSrcColorKeyOwnerVW &= ~(lpSrcSurfaceData->dwOverlayFlags
  2704. & FLG_VW_MASK);
  2705. lpInput->ddRVal = DDERR_OUTOFCAPS;
  2706. return(DDHAL_DRIVER_HANDLED);
  2707. }
  2708. else if (lpSrcSurfaceData->dwOverlayFlags & 0x02000000)
  2709. {
  2710. if (gvidConfig.sizSrc.cx > gvidConfig.sizDisp.cx)
  2711. {
  2712. lpInput->ddRVal = DDERR_OUTOFCAPS;
  2713. return(DDHAL_DRIVER_HANDLED);
  2714. }
  2715. lpSrcSurfaceData->dwOverlayFlags &= ~0x02000000;
  2716. }
  2717. #endif
  2718. #endif /* WINNT_VER40 */
  2719. // Because of Microsoft's Overfly bug we must ignore DDOVER_DDFX completely
  2720. // or Overfly reports DDERR_UNSUPPORTED at least in 1024x768x16
  2721. // So these guys can't even write a test app for WHQL that abides by their
  2722. // own rules?
  2723. if (lpInput->dwFlags & DDOVER_DDFX)
  2724. {
  2725. #ifndef WINNT_VER40
  2726. DBG_MESSAGE((" overlayFX.dwFlags = %08lX", lpInput->overlayFX.dwFlags));
  2727. DBG_MESSAGE((" overlayFX.dwDDFX = %08lX", lpInput->overlayFX.dwDDFX));
  2728. #endif
  2729. #if ENABLE_MIRRORING
  2730. if (lpInput->overlayFX.dwDDFX & DDOVERFX_MIRRORLEFTRIGHT)
  2731. {
  2732. bIsVWMirrored[dwVWIndex] = TRUE;
  2733. }
  2734. // For some bizarre reason, Microsoft's WHQL Overfly app sets the
  2735. // DDOVER_DDFX flag but sets overlayFX.dwDDFX with complete junk
  2736. // overlayFX.dwFlags also has junk
  2737. // so we must ignore dwDDFX flags we don't support rather than return an
  2738. // error. Gee that sound like good practice!
  2739. #if 0
  2740. else
  2741. {
  2742. lpInput->ddRVal = DDERR_UNSUPPORTED;
  2743. return DDHAL_DRIVER_HANDLED;
  2744. }
  2745. #endif
  2746. #endif
  2747. }
  2748. #if DDRAW_COMPAT >= 50
  2749. if( lpInput->dwFlags & DDOVER_AUTOFLIP)
  2750. {
  2751. if(lpInput->lpDDSrcSurface->lpSurfMore->lpVideoPort)
  2752. {
  2753. if(lpInput->lpDDSrcSurface->lpSurfMore->lpVideoPort->dwNumAutoflip
  2754. != 2)
  2755. {
  2756. //Hardware only support autoflip between 2 surfaces
  2757. lpInput->ddRVal = DDERR_GENERIC;
  2758. return (DDHAL_DRIVER_HANDLED);
  2759. }
  2760. }
  2761. else
  2762. {
  2763. //Autoflip must use vport
  2764. lpInput->ddRVal = DDERR_INVALIDPARAMS;
  2765. return (DDHAL_DRIVER_HANDLED);
  2766. }
  2767. }
  2768. #endif
  2769. if ( (lpInput->dwFlags & DDOVER_SHOW) || bShowOverlay)
  2770. {
  2771. // Is somebody else using our hardware?
  2772. if (((lpHardwareOwner[dwVWIndex] != NULL) &&
  2773. (lpHardwareOwner[dwVWIndex] != lpInput->lpDDSrcSurface)) ||
  2774. ((lpHardwareOwner[dwVWIndex] == NULL) &&
  2775. #ifdef WINNT_VER40
  2776. IsVWHardwareInUse(ppdev, dwVWIndex)
  2777. #else
  2778. IsVWHardwareInUse(lpDDHALData,dwVWIndex)
  2779. #endif
  2780. ))
  2781. {
  2782. lpInput->ddRVal = DDERR_OUTOFCAPS;
  2783. return DDHAL_DRIVER_HANDLED;
  2784. }
  2785. // Is a valid destination surface specified?
  2786. if (!(lpInput->lpDDDestSurface->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
  2787. {
  2788. lpInput->ddRVal = DDERR_INVALIDPARAMS;
  2789. return DDHAL_DRIVER_HANDLED;
  2790. }
  2791. // Save the rectangles
  2792. #ifdef WINNT_VER40
  2793. if (! SaveRectangles(ppdev, dwVWIndex, bCheckBandwidth, dwBitCount, lpInput))
  2794. #else
  2795. if (! SaveRectangles(dwVWIndex, bCheckBandwidth, dwBitCount,lpInput,lpDDHALData))
  2796. #endif
  2797. {
  2798. // SaveRectangles sets lpInput->ddRVal on error
  2799. return DDHAL_DRIVER_HANDLED;
  2800. }
  2801. #if DDRAW_COMPAT >= 50
  2802. lpInput->lpDDSrcSurface->lpSurfMore->dwOverlayFlags = lpInput->dwFlags;
  2803. #endif
  2804. lpHardwareOwner[dwVWIndex] = lpInput->lpDDSrcSurface;
  2805. lpSrcSurfaceData->dwOverlayFlags |= FLG_ENABLED;
  2806. #ifdef WINNT_VER40
  2807. RegInitVideoVW(ppdev, dwVWIndex, lpInput->lpDDSrcSurface);
  2808. #else
  2809. RegInitVideoVW(dwVWIndex, lpInput->lpDDSrcSurface, lpDDHALData);
  2810. #endif
  2811. }
  2812. else if (lpInput->dwFlags & DDOVER_HIDE)
  2813. {
  2814. if (lpHardwareOwner[dwVWIndex] == lpInput->lpDDSrcSurface)
  2815. {
  2816. lpHardwareOwner[dwVWIndex] = NULL;
  2817. // clear panning show bit here
  2818. // Turn the video off
  2819. lpSrcSurfaceData->dwOverlayFlags &= ~FLG_ENABLED;
  2820. #ifdef WINNT_VER40
  2821. DisableOverlay(ppdev, dwVWIndex);
  2822. #else
  2823. DisableOverlay(lpDDHALData, dwVWIndex);
  2824. #endif
  2825. }
  2826. }
  2827. else if (lpHardwareOwner[dwVWIndex] == lpInput->lpDDSrcSurface)
  2828. {
  2829. //Save the rectangles
  2830. #ifdef WINNT_VER40
  2831. if (! SaveRectangles(ppdev, dwVWIndex, bCheckBandwidth, dwBitCount, lpInput))
  2832. #else
  2833. if (! SaveRectangles(dwVWIndex, bCheckBandwidth, dwBitCount,lpInput,lpDDHALData))
  2834. #endif
  2835. {
  2836. // SaveRectangles sets lpInput->ddRVal on error
  2837. return DDHAL_DRIVER_HANDLED;
  2838. }
  2839. #if DDRAW_COMPAT >= 50
  2840. lpInput->lpDDSrcSurface->lpSurfMore->dwOverlayFlags = lpInput->dwFlags;
  2841. #endif
  2842. #ifdef WINNT_VER40
  2843. RegInitVideoVW(ppdev, dwVWIndex, lpInput->lpDDSrcSurface);
  2844. #else
  2845. RegInitVideoVW(dwVWIndex, lpInput->lpDDSrcSurface, lpDDHALData);
  2846. #endif
  2847. }
  2848. lpInput->ddRVal = DD_OK;
  2849. return DDHAL_DRIVER_HANDLED;
  2850. }
  2851. /***************************************************************************
  2852. *
  2853. * FUNCTION: SetPosition
  2854. *
  2855. * DESCRIPTION:
  2856. *
  2857. ****************************************************************************/
  2858. STATIC DWORD SetPosition
  2859. (
  2860. #ifdef WINNT_VER40
  2861. PDEV *ppdev,
  2862. PDD_SETOVERLAYPOSITIONDATA lpInput
  2863. #else
  2864. LPDDHAL_SETOVERLAYPOSITIONDATA lpInput
  2865. #endif
  2866. )
  2867. {
  2868. LP_SURFACE_DATA lpSrcSurfaceData;
  2869. DWORD dwVWIndex;
  2870. #ifndef WINNT_VER40
  2871. LPGLOBALDATA lpDDHALData = GetDDHALContext( lpInput->lpDD);
  2872. #endif
  2873. #ifndef WINNT_VER40
  2874. DBG_MESSAGE(("Overlay SetPosition (lpInput = 0x%08lX)", lpInput));
  2875. #endif
  2876. if (0 == lpInput->lpDDSrcSurface->dwReserved1)
  2877. {
  2878. lpInput->ddRVal = DDERR_NOTAOVERLAYSURFACE;
  2879. return DDHAL_DRIVER_HANDLED;
  2880. }
  2881. lpSrcSurfaceData = GET_SURFACE_DATA_PTR(lpInput->lpDDSrcSurface);
  2882. dwVWIndex = GetVideoWindowIndex(lpSrcSurfaceData->dwOverlayFlags);
  2883. ASSERT(dwNumVideoWindows > dwVWIndex);
  2884. if (lpHardwareOwner[dwVWIndex] == lpInput->lpDDSrcSurface)
  2885. {
  2886. // Update the rectangles
  2887. grOverlayDest[dwVWIndex].right =
  2888. (int)(grOverlayDest[dwVWIndex].right - grOverlayDest[dwVWIndex].left)
  2889. + (int)lpInput->lXPos;
  2890. grOverlayDest[dwVWIndex].left = (int) lpInput->lXPos;
  2891. grOverlayDest[dwVWIndex].bottom =
  2892. (int)(grOverlayDest[dwVWIndex].bottom - grOverlayDest[dwVWIndex].top)
  2893. + (int)lpInput->lYPos;
  2894. grOverlayDest[dwVWIndex].top = (int) lpInput->lYPos;
  2895. #ifdef WINNT_VER40
  2896. RegMoveVideoVW(ppdev, dwVWIndex, lpInput->lpDDSrcSurface);
  2897. #else
  2898. RegMoveVideoVW(dwVWIndex, lpInput->lpDDSrcSurface, lpDDHALData);
  2899. #endif
  2900. }
  2901. lpInput->ddRVal = DD_OK;
  2902. return DDHAL_DRIVER_HANDLED;
  2903. }
  2904. /***************************************************************************
  2905. *
  2906. * FUNCTION: GetOverlayFlipStatus
  2907. *
  2908. * DESCRIPTION:
  2909. *
  2910. ****************************************************************************/
  2911. STATIC DWORD GetOverlayFlipStatus
  2912. (
  2913. #ifdef WINNT_VER40
  2914. PDEV *ppdev,
  2915. #else
  2916. LPGLOBALDATA lpDDHALData,
  2917. #endif
  2918. FLATPTR fpVidMem,
  2919. DWORD dwVWIndex
  2920. )
  2921. {
  2922. if (gsOverlayFlip.bFlipFlag &&
  2923. ((fpVidMem == 0) || (fpVidMem == gsOverlayFlip.fpFlipFrom)))
  2924. {
  2925. #if 1
  2926. // if arm bit is set then some action is still pending
  2927. // so fail
  2928. ASSERT(dwNumVideoWindows > dwVWIndex);
  2929. if (VW_ARM & ((PVGAR)lpDDHALData->RegsAddress)->VideoWindow[dwVWIndex].grVW_CONTROL0)
  2930. return (DWORD)DDERR_WASSTILLDRAWING;
  2931. #else
  2932. __int64 ttime;
  2933. int iTemp;
  2934. DBG_MESSAGE(("GetOverlayFlipStatus (fpVidMem = 0x%08lX)", fpVidMem));
  2935. // If the current scanline is less than the flip scan line,
  2936. // we know that a VSYNC has occurred.
  2937. iTemp = CurrentVLine(lpDDHALData);
  2938. if (gsOverlayFlip.dwFlipScanline > (DWORD) iTemp)
  2939. {
  2940. // Don't allow access during the vertical retrace
  2941. if (iTemp == 0)
  2942. {
  2943. if (gsOverlayFlip.bWasEverInDisplay)
  2944. {
  2945. gsOverlayFlip.bHaveEverCrossedVBlank = TRUE;
  2946. }
  2947. return (DWORD)DDERR_WASSTILLDRAWING;
  2948. }
  2949. }
  2950. // Otherwise, we can check to see if 1) we have ever
  2951. // been in a vertical retrace or 2) if a fixed amount of time
  2952. // has expired.
  2953. else if (gsOverlayFlip.bHaveEverCrossedVBlank == FALSE)
  2954. {
  2955. gsOverlayFlip.bWasEverInDisplay = TRUE;
  2956. QueryPerformanceCounter((LARGE_INTEGER *)&ttime);
  2957. if ((ttime-gsOverlayFlip.liFlipTime) <= gsOverlayFlip.dwFlipDuration)
  2958. {
  2959. return (DWORD)DDERR_WASSTILLDRAWING;
  2960. }
  2961. }
  2962. #endif
  2963. gsOverlayFlip.bFlipFlag = FALSE;
  2964. }
  2965. return DD_OK;
  2966. }
  2967. /***************************************************************************
  2968. *
  2969. * FUNCTION: ComputeVWZoomCodes
  2970. *
  2971. * DESCRIPTION: Computes HACCUM_STP, HACCUM_SD,
  2972. * VACCUM_STP, VACCUM_SDA and VACCUM_SDB
  2973. *
  2974. ****************************************************************************/
  2975. STATIC VOID ComputeVWZoomCodes
  2976. (
  2977. #ifdef WINNT_VER40
  2978. PDEV *ppdev,
  2979. #endif
  2980. DWORD dwVWIndex,
  2981. VWDATA *pVWData
  2982. )
  2983. {
  2984. SIZEL Dst;
  2985. SIZEL Src;
  2986. Dst.cx = grOverlayDest[dwVWIndex].right - grOverlayDest[dwVWIndex].left;
  2987. Src.cx = grOverlaySrc[dwVWIndex].right - grOverlaySrc[dwVWIndex].left;
  2988. if (Dst.cx == Src.cx)
  2989. {
  2990. // no horizontal resize
  2991. pVWData->HACCUM_STP = 0x00010000;
  2992. }
  2993. else if (Dst.cx > Src.cx)
  2994. {
  2995. // make sure we aren't going beyond hw capabilities
  2996. ASSERT(Dst.cx <= 8 * Src.cx);
  2997. // horizontal stretch
  2998. //
  2999. // ideally zoom code = 256 * (256 * Src.cx / Dst.cx)
  3000. // we always want to truncate (256 * Src.cy / Dst.cx)
  3001. // because truncating will give us back a Src.cx which is less than or
  3002. // equal to the actual width of the source and we will never overrun the
  3003. // source extent (and won't get the green stripe)
  3004. pVWData->HACCUM_STP = (256 * 256 * Src.cx) / Dst.cx;
  3005. }
  3006. else
  3007. {
  3008. // make sure we aren't going beyond hw capabilities
  3009. ASSERT(2 * Dst.cx >= Src.cx);
  3010. // horizontal shrink
  3011. //
  3012. // this is the zoom code for Src.cx/2 be stretched to Dst.cx
  3013. // using 128 seems to give a zoom code one too high
  3014. // then we get the green stripe on the right edge of the video
  3015. pVWData->HACCUM_STP = (256 * 127 * Src.cx) / Dst.cx;
  3016. pVWData->CONTROL0 |= VW_XShrinkBy2;
  3017. }
  3018. // Just set horizontal seeds to zero for now
  3019. pVWData->HACCUM_SD = 0;
  3020. Dst.cy = grOverlayDest[dwVWIndex].bottom - grOverlayDest[dwVWIndex].top;
  3021. Src.cy = grOverlaySrc[dwVWIndex].bottom - grOverlaySrc[dwVWIndex].top;
  3022. if (Dst.cy == Src.cy)
  3023. {
  3024. pVWData->VACCUM_STP = 0x00010000;
  3025. }
  3026. else if (Dst.cy > Src.cy)
  3027. {
  3028. // make sure we aren't going beyond hw capabilities
  3029. ASSERT(Dst.cy <= 8 * Src.cy);
  3030. // vertical stretch
  3031. //
  3032. // ideally zoom code = 256 * (256 * Src.cy / Dst.cy)
  3033. // we always want to truncate (256 * Src.cy / Dst.cy)
  3034. // because truncating will give us back a Src.cy which is less than or
  3035. // equal to the actual size of the source and we will never overrun the
  3036. // source extent (and won't get the green stripe)
  3037. // using 256 seems to give a zoom code one too high for full screen
  3038. // then we get garbage on the bottom of the screen
  3039. pVWData->VACCUM_STP = (256 * 255 * Src.cy) / Dst.cy;
  3040. }
  3041. else
  3042. {
  3043. // vertical shrink
  3044. //
  3045. // ideally zoom code = 256 * (256 * Dst.cy / Src.cy)
  3046. // we always want to round up (256 * Dst.cy / Src.cy)
  3047. // because rounding up will give us back a Src.cy which is less than or
  3048. // equal to the actual size of the source and we will never overrun the
  3049. // source extent (and won't get the green stripe)
  3050. pVWData->VACCUM_STP = (256 * 256 * Dst.cy + 256 * (Src.cy - 1)) / Src.cy;
  3051. pVWData->CONTROL1 |= VW_YShrinkEn;
  3052. }
  3053. // Just set vertical seeds to zero for now
  3054. pVWData->VACCUM_SDA = 0;
  3055. pVWData->VACCUM_SDB = 0;
  3056. }
  3057. /***************************************************************************
  3058. *
  3059. * FUNCTION: ComputeVWPositionData
  3060. *
  3061. * DESCRIPTION: Computes HSTRT, HEND, HSDSZ, VSTRT, VEND,
  3062. * PD_STRT_ADDR and SD_PITCH
  3063. *
  3064. ****************************************************************************/
  3065. STATIC VOID
  3066. ComputeVWPositionData ( PRECTL pVideoRect,
  3067. PRECTL pOverlaySrc,
  3068. PRECTL pOverlayDest,
  3069. #ifdef WINNT_VER40
  3070. PDD_SURFACE_GLOBAL pGbl,
  3071. #else
  3072. LPDDRAWI_DDRAWSURFACE_GBL pGbl,
  3073. LPGLOBALDATA lpDDHALData,
  3074. #endif
  3075. DWORD dwBitCount,
  3076. VWDATA *pVWData,
  3077. BOOL bCLPL )
  3078. {
  3079. DWORD dwSurfBase,dwSurfOffset;
  3080. pVWData->HSTRT = LOWORD(pVideoRect->left);
  3081. pVWData->HEND = LOWORD(pVideoRect->right) - 1;
  3082. pVWData->HSDSZ = (WORD)(pOverlaySrc->right - pOverlaySrc->left);
  3083. pVWData->VSTRT = LOWORD(pVideoRect->top);
  3084. pVWData->VEND = LOWORD(pVideoRect->bottom) - 1;
  3085. #ifdef WINNT_VER40
  3086. dwSurfBase = pGbl->fpVidMem;
  3087. #else
  3088. dwSurfBase = (pGbl->fpVidMem - lpDDHALData->ScreenAddress);
  3089. #endif
  3090. dwSurfOffset = pOverlaySrc->top * pGbl->lPitch +
  3091. pOverlaySrc->left * (dwBitCount / 8);
  3092. pVWData->PSD_STRT_ADDR = dwSurfBase + dwSurfOffset;
  3093. #if ENABLE_YUVPLANAR
  3094. if (bCLPL)
  3095. {
  3096. // qword aligned offset of UV interleaved data in aperture 0
  3097. // need same offset into UV data as offset into Y data
  3098. // so it's just PSD_STRT_ADDR plus area of Y data
  3099. pVWData->PSD_UVSTRT_ADDR = dwSurfBase +
  3100. (((pGbl->wHeight * pGbl->lPitch) + 7) & ~7) +
  3101. (dwSurfOffset / 2);
  3102. }
  3103. else
  3104. pVWData->PSD_UVSTRT_ADDR = 0;
  3105. #endif
  3106. #if ENABLE_MIRRORING
  3107. if (bIsVWMirrored[dwVWIndex])
  3108. {
  3109. // for mirroring
  3110. // point to the last byte of the last pixel on the right edge of the source
  3111. pVWData->PSD_STRT_ADDR += (DWORD)(pOverlaySrc->right - pOverlaySrc->left - 1);
  3112. }
  3113. #endif
  3114. pVWData->SD_PITCH = (WORD)(pGbl->lPitch);
  3115. }
  3116. /***************************************************************************
  3117. *
  3118. * FUNCTION: RGBtoYCrCb
  3119. *
  3120. * DESCRIPTION: Conversion equations are from page 42 of the second edition
  3121. * of "Video Demystified" by Keith Jack
  3122. *
  3123. ****************************************************************************/
  3124. STATIC DWORD INLINE
  3125. RGBtoYCbCr ( DWORD dwRGB )
  3126. {
  3127. long Y, Cr, Cb;
  3128. long r, g, b;
  3129. r = (dwRGB & 0xF800) >> 8;
  3130. g = (dwRGB & 0x07E0) >> 3;
  3131. b = (dwRGB & 0x001F) << 3;
  3132. Y = ( 77 * r + 150 * g + 29 * b) / 256;
  3133. // max value of Y from this is if r, g & b are all 255 then Y = 255
  3134. // min value of Y from this is if r, g & b are all 0 then Y = 0
  3135. // so don't need to clamp Y
  3136. Cb = (-44 * r - 87 * g + 131 * b) / 256 + 128;
  3137. // max value of Cb is if r & g are 0 and b is 255 then Cb = 258
  3138. // min value of Cb is if r & g are 255 and b is 0 then Cb = -2
  3139. // so need to clamp Cb between 0 and 255
  3140. if (255 < Cb)
  3141. Cb = 255;
  3142. else if (0 > Cb)
  3143. Cb = 0;
  3144. Cr = (131 * r - 110 * g - 21 * b) / 256 + 128;
  3145. // max value of Cr is if r is 255 and g & b are 0 then Cr = 258
  3146. // min value of Cr is if r is 0 and g & b are 255 then Cr = -2
  3147. // so need to clamp Cr between 0 and 255
  3148. if (255 < Cr)
  3149. Cr = 255;
  3150. else if (0 > Cr)
  3151. Cr = 0;
  3152. return (((Y & 0xFF) << 16) | ((Cb & 0xFF) << 8) | ((Cr & 0xFF)));
  3153. }
  3154. /***************************************************************************
  3155. *
  3156. * FUNCTION: DetermineVWColorKeyData
  3157. *
  3158. * DESCRIPTION: Determines CLRKEY_MIN & CLRKEY_MAX or
  3159. * CHRMKEY_MIN & CHRMKEY_MAX
  3160. *
  3161. ****************************************************************************/
  3162. STATIC VOID DetermineVWColorKeyData
  3163. (
  3164. #ifdef WINNT_VER40
  3165. PDEV *ppdev,
  3166. #else
  3167. LPGLOBALDATA lpDDHALData,
  3168. #endif
  3169. DWORD dwOverlayFlags,
  3170. DWORD dwBitCount,
  3171. VWDATA *pVWData
  3172. )
  3173. {
  3174. if (FLG_COLOR_KEY & dwOverlayFlags)
  3175. {
  3176. // destination color key, uses color key on 5465
  3177. pVWData->CLRKEY_MIN = gdwColorKey;
  3178. pVWData->CLRKEY_MAX = gdwColorKey;
  3179. pVWData->CONTROL0 &= ~VW_OCCLUDE_MASK;
  3180. pVWData->CONTROL0 |= (COLOR_KEY << OCCLUDE_SHIFT);
  3181. }
  3182. else if (FLG_SRC_COLOR_KEY & dwOverlayFlags)
  3183. {
  3184. PVGAR pREG = (PVGAR)lpDDHALData->RegsAddress;
  3185. BYTE r,g,b;
  3186. // source color key, uses chroma key on 5465
  3187. switch (dwBitCount)
  3188. {
  3189. case 8:
  3190. // read colors from the DAC
  3191. LL8(grPalette_Read_Address,(BYTE)(gdwSrcColorKeyLow & 0xFF));
  3192. r = pREG->grPalette_Data;
  3193. g = pREG->grPalette_Data;
  3194. b = pREG->grPalette_Data;
  3195. pVWData->CHRMKEY_MIN = ((DWORD)(r) << 16) |
  3196. ((DWORD)(g) << 8) |
  3197. ((DWORD)(b));
  3198. LL8(grPalette_Read_Address,(BYTE)(gdwSrcColorKeyHigh & 0xFF));
  3199. r = pREG->grPalette_Data;
  3200. g = pREG->grPalette_Data;
  3201. b = pREG->grPalette_Data;
  3202. pVWData->CHRMKEY_MAX = ((DWORD)(r) << 16) |
  3203. ((DWORD)(g) << 8) |
  3204. ((DWORD)(b));
  3205. break;
  3206. case 16:
  3207. if ((FLG_UYVY | FLG_YUY2) & dwOverlayFlags)
  3208. {
  3209. // Since we are currently using ITU 601 compliant YUV data
  3210. // convert color key to YCrCb
  3211. pVWData->CHRMKEY_MIN = RGBtoYCbCr(gdwSrcColorKeyLow);
  3212. pVWData->CHRMKEY_MAX = RGBtoYCbCr(gdwSrcColorKeyHigh);
  3213. }
  3214. else
  3215. {
  3216. // convert 5:6:5 to true color
  3217. pVWData->CHRMKEY_MIN = ((gdwSrcColorKeyLow & 0xF800) << 8) | // red
  3218. ((gdwSrcColorKeyLow & 0x07E0) << 5) | // green
  3219. ((gdwSrcColorKeyLow & 0x001F) << 3); // blue
  3220. pVWData->CHRMKEY_MAX = ((gdwSrcColorKeyHigh & 0xF800) << 8) | // red
  3221. ((gdwSrcColorKeyHigh & 0x07E0) << 5) | // green
  3222. ((gdwSrcColorKeyHigh & 0x001F) << 3); // blue
  3223. }
  3224. break;
  3225. case 24:
  3226. case 32:
  3227. pVWData->CHRMKEY_MIN = (gdwSrcColorKeyLow & 0x00FFFFFF);
  3228. pVWData->CHRMKEY_MAX = (gdwSrcColorKeyHigh & 0x00FFFFFF);
  3229. break;
  3230. }
  3231. pVWData->CONTROL0 &= ~VW_OCCLUDE_MASK;
  3232. pVWData->CONTROL0 |= (CHROMA_KEY << OCCLUDE_SHIFT);
  3233. }
  3234. else
  3235. {
  3236. pVWData->CONTROL0 &= ~VW_OCCLUDE_MASK;
  3237. pVWData->CONTROL0 |= (NO_OCCLUSION << OCCLUDE_SHIFT);
  3238. }
  3239. }
  3240. /***************************************************************************
  3241. *
  3242. * FUNCTION: ComputeVWFifoThreshold
  3243. *
  3244. * DESCRIPTION:
  3245. *
  3246. ****************************************************************************/
  3247. static INLINE VOID ComputeVWFifoThreshold
  3248. (
  3249. #ifdef WINNT_VER40
  3250. PDEV *ppdev,
  3251. #else
  3252. LPGLOBALDATA lpDDHALData,
  3253. #endif
  3254. VWDATA *pVWData
  3255. )
  3256. {
  3257. PVGAR pREG = (PVGAR)lpDDHALData->RegsAddress;
  3258. pREG->grDisplay_Threshold_and_Tiling =
  3259. (pREG->grDisplay_Threshold_and_Tiling & 0xFFC0) |
  3260. (gsProgRegs.DispThrsTiming & 0x003F);
  3261. pVWData->FIFO_THRSH = gsProgRegs.VW0_FIFO_THRSH;
  3262. }
  3263. /***************************************************************************
  3264. *
  3265. * FUNCTION: PanOverlay1_Init
  3266. *
  3267. * DESCRIPTION: Save data for panning overlay window one.
  3268. * Clip lpVideoRect to panning viewport.
  3269. *
  3270. ****************************************************************************/
  3271. static INLINE VOID PanOverlay1_Init
  3272. (
  3273. #ifdef WINNT_VER40
  3274. PDEV *ppdev,
  3275. #endif
  3276. LPRECTL lpVideoRect,
  3277. LPRECTL lpOverlaySrc,
  3278. LPRECTL lpOverlayDest
  3279. )
  3280. {
  3281. // This is not necessary on Laguna since we can't pan the screen
  3282. // clip left edge of destination
  3283. if (0 > (lpVideoRect->left = lpOverlayDest->left))
  3284. lpVideoRect->left = 0;
  3285. // clip right edge of destination
  3286. #ifdef WINNT_VER40
  3287. if ((LONG)ppdev->cxScreen < (lpVideoRect->right = lpOverlayDest->right))
  3288. lpVideoRect->right = (LONG)ppdev->cxScreen;
  3289. #else
  3290. if ((LONG)pPDevice->deWidth < (lpVideoRect->right = lpOverlayDest->right))
  3291. lpVideoRect->right = (LONG)pPDevice->deWidth;
  3292. #endif
  3293. // clip top edge of destination
  3294. if (0 > (lpVideoRect->top = lpOverlayDest->top))
  3295. lpVideoRect->top = 0;
  3296. // clip bottom edge of destination
  3297. #ifdef WINNT_VER40
  3298. if ((LONG)ppdev->cyScreen < (lpVideoRect->bottom = lpOverlayDest->bottom))
  3299. lpVideoRect->bottom = (LONG)ppdev->cyScreen;
  3300. #else
  3301. if ((LONG)pPDevice->deHeight < (lpVideoRect->bottom = lpOverlayDest->bottom))
  3302. lpVideoRect->bottom = (LONG)pPDevice->deHeight;
  3303. #endif
  3304. }
  3305. /***************************************************************************
  3306. *
  3307. * FUNCTION: RegInitVideoVW
  3308. *
  3309. * DESCRIPTION: This function is called to program the video format and
  3310. * the physical offset of the Video Window video data
  3311. * in the frame buffer.
  3312. *
  3313. ****************************************************************************/
  3314. STATIC BOOL RegInitVideoVW
  3315. (
  3316. #ifdef WINNT_VER40
  3317. PDEV *ppdev,
  3318. DWORD dwVWIndex,
  3319. PDD_SURFACE_LOCAL lpSurface
  3320. #else
  3321. DWORD dwVWIndex,
  3322. LPDDRAWI_DDRAWSURFACE_LCL lpSurface,
  3323. LPGLOBALDATA lpDDHALData
  3324. #endif
  3325. )
  3326. {
  3327. LP_SURFACE_DATA lpSurfaceData = GET_SURFACE_DATA_PTR(lpSurface);
  3328. VWDATA VWData;
  3329. BOOL bOverlayTooSmall = FALSE;
  3330. DWORD dwFourcc;
  3331. LONG lPitch;
  3332. DWORD dwBitCount;
  3333. RECTL rVideoRect;
  3334. PVGAR pREG = (PVGAR)lpDDHALData->RegsAddress;
  3335. #if DDRAW_COMPAT >= 50
  3336. DWORD dwSrfFlags = FALSE;
  3337. #endif
  3338. DWORD width;
  3339. //////#ifndef WINNT_VER40
  3340. PDD_ATTACHLIST lpSurfaceAttached;
  3341. LP_SURFACE_DATA lpSurfaceDataTmp;
  3342. //////#endif
  3343. ASSERT(dwNumVideoWindows > dwVWIndex);
  3344. // Determine the format of the video data
  3345. if (lpSurface->dwFlags & DDRAWISURF_HASPIXELFORMAT)
  3346. {
  3347. GetFormatInfo(&(lpSurface->lpGbl->ddpfSurface), &dwFourcc, &dwBitCount);
  3348. }
  3349. else
  3350. {
  3351. dwBitCount = BITSPERPIXEL;
  3352. if (16 == dwBitCount)
  3353. dwFourcc = BI_BITFIELDS; // 5:6:5
  3354. else
  3355. dwFourcc = BI_RGB; // 8bpp, 5:5:5, 24bpp & 32bpp
  3356. }
  3357. #ifdef WINNT_VER40
  3358. PanOverlay1_Init(ppdev,&rVideoRect,&grOverlaySrc[dwVWIndex],&grOverlayDest[dwVWIndex]);
  3359. #else
  3360. PanOverlay1_Init(&rVideoRect,&grOverlaySrc[dwVWIndex],&grOverlayDest[dwVWIndex]);
  3361. #endif
  3362. // rVideoRect is now adjusted and clipped to the panning viewport.
  3363. // Disable overlay if totally clipped by viewport.
  3364. if (((rVideoRect.right - rVideoRect.left) <= 0) ||
  3365. ((rVideoRect.bottom- rVideoRect.top ) <= 0))
  3366. {
  3367. #ifdef WINNT_VER40
  3368. DisableOverlay(ppdev, dwVWIndex);
  3369. #else
  3370. DisableOverlay(lpDDHALData,dwVWIndex);
  3371. #endif
  3372. return TRUE;
  3373. }
  3374. memset(&VWData, 0, sizeof(VWData));
  3375. lPitch = lpSurface->lpGbl->lPitch;
  3376. #ifdef WINNT_VER40
  3377. ComputeVWZoomCodes(ppdev, dwVWIndex, &VWData);
  3378. #else
  3379. ComputeVWZoomCodes(dwVWIndex, &VWData);
  3380. #endif
  3381. ComputeVWPositionData(&rVideoRect,
  3382. &grOverlaySrc[dwVWIndex],
  3383. &grOverlayDest[dwVWIndex],
  3384. lpSurface->lpGbl,
  3385. #ifndef WINNT_VER40
  3386. lpDDHALData,
  3387. #endif
  3388. dwBitCount,
  3389. &VWData,
  3390. FOURCC_YUVPLANAR == dwFourcc);
  3391. lpSurfaceData->dwOverlayOffset = //This offset will be used in FlipOverlay
  3392. VWData.PSD_STRT_ADDR - // and VPE
  3393. lpSurface->lpGbl->fpVidMem
  3394. #ifndef WINNT_VER40
  3395. + lpDDHALData->ScreenAddress
  3396. #endif
  3397. ;
  3398. /////////#ifndef WINNT_VER40
  3399. //Update all the attached surfaces
  3400. lpSurfaceAttached = lpSurface->lpAttachListFrom;
  3401. while( lpSurfaceAttached)
  3402. {
  3403. if(lpSurfaceAttached->lpAttached)
  3404. {
  3405. lpSurfaceDataTmp = GET_SURFACE_DATA_PTR(lpSurfaceAttached->lpAttached);
  3406. lpSurfaceDataTmp->dwOverlayOffset = lpSurfaceData->dwOverlayOffset;
  3407. lpSurfaceAttached = lpSurfaceAttached->lpAttached->lpAttachListFrom;
  3408. }
  3409. else
  3410. break;
  3411. }
  3412. lpSurfaceAttached = lpSurface->lpAttachList;
  3413. while( lpSurfaceAttached)
  3414. {
  3415. if(lpSurfaceAttached->lpAttached)
  3416. {
  3417. lpSurfaceDataTmp = GET_SURFACE_DATA_PTR(lpSurfaceAttached->lpAttached);
  3418. lpSurfaceDataTmp->dwOverlayOffset = lpSurfaceData->dwOverlayOffset;
  3419. lpSurfaceAttached = lpSurfaceAttached->lpAttached->lpAttachList;
  3420. }
  3421. else
  3422. break;
  3423. }
  3424. //////////#endif
  3425. #if ENABLE_MIRRORING
  3426. // Mirror Video Windows support.
  3427. if (bIsVWMirrored[dwVWIndex])
  3428. VWData.CONTROL0 |= VW_HMIRR_EN;
  3429. #endif
  3430. // Xing, isn't the memset above enough?
  3431. VWData.SSD_STRT_ADDR = 0L;
  3432. #if DDRAW_COMPAT >= 50
  3433. if (gwNotify & VPE_ON)
  3434. {
  3435. if((lpSurface->lpSurfMore->lpVideoPort != NULL)&&
  3436. (lpSurface->ddsCaps.dwCaps & DDSCAPS_VIDEOPORT))
  3437. {
  3438. if((lpSurface->lpSurfMore->dwOverlayFlags & DDOVER_BOB)
  3439. &&(lpSurface->lpSurfMore->lpVideoPort->ddvpInfo.dwVPFlags
  3440. & DDVP_INTERLEAVE))
  3441. {
  3442. dwSrfFlags = DDOVER_BOB;
  3443. }
  3444. else if((lpSurface->lpSurfMore->lpVideoPort->ddvpInfo.dwVPFlags
  3445. &DDVP_AUTOFLIP)
  3446. &&(lpSurface->lpSurfMore->dwOverlayFlags & DDOVER_AUTOFLIP)
  3447. && (lpSurface->lpAttachListFrom != NULL)
  3448. && (lpSurface->lpAttachListFrom->lpAttached != NULL))
  3449. {
  3450. dwSrfFlags = DDOVER_AUTOFLIP;
  3451. }
  3452. }
  3453. }
  3454. if((dwSrfFlags & DDOVER_BOB)
  3455. ||(!dwSrfFlags
  3456. &&(lpSurface->lpSurfMore->dwOverlayFlags & DDOVER_INTERLEAVED)))
  3457. {
  3458. RECTL rcTemp;
  3459. rcTemp = grOverlaySrc[dwVWIndex];
  3460. grOverlaySrc[dwVWIndex].top >>=1;
  3461. grOverlaySrc[dwVWIndex].bottom >>=1; //use half source size to
  3462. VWData.CONTROL1 &= ~VW_YShrinkEn; //find zoom factor
  3463. ComputeVWZoomCodes(dwVWIndex, &VWData);
  3464. grOverlaySrc[dwVWIndex] = rcTemp;
  3465. VWData.SD_PITCH <<= 1;
  3466. VWData.CONTROL0 &= ~0x30000ul;
  3467. if(dwSrfFlags & DDOVER_BOB)
  3468. {
  3469. VWData.SSD_STRT_ADDR = VWData.PSD_STRT_ADDR + lPitch;
  3470. VWData.CONTROL0 |= 0x20000ul; //enable buffer two
  3471. }
  3472. }
  3473. else if(dwSrfFlags & DDOVER_AUTOFLIP)
  3474. {
  3475. VWData.SSD_STRT_ADDR = lpSurfaceData->dwAutoBaseAddr2 +
  3476. lpSurfaceData->dwOverlayOffset;
  3477. if( VWData.PSD_STRT_ADDR == VWData.SSD_STRT_ADDR )
  3478. {
  3479. VWData.PSD_STRT_ADDR = lpSurfaceData->dwAutoBaseAddr1 +
  3480. lpSurfaceData->dwOverlayOffset;
  3481. }
  3482. VWData.CONTROL0 &= ~0x30000ul;
  3483. VWData.CONTROL0 |= 0x20000ul; //enable the second buffer
  3484. if(!(lpSurface->lpSurfMore->dwOverlayFlags & DDOVER_BOB))
  3485. {
  3486. //For non-smooth-interlaced auto-flip these two address need
  3487. // to be switched. HW BUG
  3488. DWORD dwTmp = VWData.PSD_STRT_ADDR;
  3489. VWData.PSD_STRT_ADDR = VWData.SSD_STRT_ADDR;
  3490. VWData.SSD_STRT_ADDR = dwTmp;
  3491. }
  3492. }
  3493. if(lpSurface->lpSurfMore->dwOverlayFlags & DDOVER_BOB)
  3494. {
  3495. BOOL fSDAHalf = TRUE;
  3496. #if ENABLE_MIRRORING
  3497. if (lpInput->overlayFX.dwDDFX & DDOVERFX_MIRRORLEFTRIGHT)
  3498. fSDAHalf = !fSDAHalf;
  3499. #endif
  3500. if(VWData.VACCUM_STP >= 0x8000ul)
  3501. fSDAHalf = !fSDAHalf;
  3502. if(fSDAHalf)
  3503. {
  3504. VWData.VACCUM_SDA = 0x8000ul;
  3505. VWData.VACCUM_SDB = 0ul;
  3506. }
  3507. else
  3508. {
  3509. VWData.VACCUM_SDA = 0ul;
  3510. VWData.VACCUM_SDB = 0x8000ul;
  3511. }
  3512. VWData.CONTROL0 |= 0x8ul;
  3513. }
  3514. #endif
  3515. if (lpSurfaceData->dwOverlayFlags & FLG_ENABLED)
  3516. VWData.CONTROL0 |= (VW_VWE | VW_ARM);
  3517. // set source data format
  3518. if (dwFourcc == BI_RGB)
  3519. {
  3520. if (dwBitCount == 16)
  3521. {
  3522. VWData.CONTROL0 |= (SD_RGB16_555 << SD_FRMT_SHIFT);
  3523. }
  3524. #if ENABLE_SD_RGB32
  3525. else if (dwBitCount == 32)
  3526. {
  3527. VWData.CONTROL0 |= (SD_RGB32 << SD_FRMT_SHIFT);
  3528. }
  3529. #endif
  3530. }
  3531. else if (dwFourcc == BI_BITFIELDS)
  3532. {
  3533. VWData.CONTROL0 |= (SD_RGB16_565 << SD_FRMT_SHIFT);
  3534. }
  3535. #if ENABLE_YUVPLANAR
  3536. else if (dwFourcc == FOURCC_YUVPLANAR)
  3537. {
  3538. VWData.CONTROL0 |= (SD_YUV420 << SD_FRMT_SHIFT);
  3539. }
  3540. #endif
  3541. else if (FOURCC_UYVY == dwFourcc)
  3542. {
  3543. VWData.CONTROL0 |= (SD_YUV422 << SD_FRMT_SHIFT);
  3544. }
  3545. #ifdef WINNT_VER40
  3546. DetermineVWColorKeyData(ppdev, lpSurfaceData->dwOverlayFlags, dwBitCount, &VWData);
  3547. #else
  3548. DetermineVWColorKeyData(lpDDHALData,lpSurfaceData->dwOverlayFlags, dwBitCount, &VWData);
  3549. #endif
  3550. #ifdef WINNT_VER40
  3551. ComputeVWFifoThreshold(ppdev, &VWData);
  3552. #else
  3553. ComputeVWFifoThreshold(lpDDHALData,&VWData);
  3554. #endif
  3555. // Now start programming the registers
  3556. #ifdef WINNT_VER40
  3557. WaitForVWArmToClear(ppdev, dwVWIndex);
  3558. #else
  3559. WaitForVWArmToClear(lpDDHALData, dwVWIndex);
  3560. #endif
  3561. ASSERT(! (pREG->VideoWindow[dwVWIndex].grVW_TEST0 & VW_PostImed));
  3562. LL16(VideoWindow[dwVWIndex].grVW_HSTRT, VWData.HSTRT);
  3563. LL16(VideoWindow[dwVWIndex].grVW_HEND, VWData.HEND);
  3564. LL16(VideoWindow[dwVWIndex].grVW_HSDSZ, VWData.HSDSZ);
  3565. LL32(VideoWindow[dwVWIndex].grVW_HACCUM_STP, VWData.HACCUM_STP);
  3566. LL32(VideoWindow[dwVWIndex].grVW_HACCUM_SD, VWData.HACCUM_SD);
  3567. LL16(VideoWindow[dwVWIndex].grVW_VSTRT, VWData.VSTRT);
  3568. LL16(VideoWindow[dwVWIndex].grVW_VEND, VWData.VEND);
  3569. LL32(VideoWindow[dwVWIndex].grVW_VACCUM_STP, VWData.VACCUM_STP);
  3570. LL32(VideoWindow[dwVWIndex].grVW_VACCUM_SDA, VWData.VACCUM_SDA);
  3571. LL32(VideoWindow[dwVWIndex].grVW_VACCUM_SDB, VWData.VACCUM_SDB);
  3572. LL32(VideoWindow[dwVWIndex].grVW_PSD_STRT_ADDR, VWData.PSD_STRT_ADDR);
  3573. LL32(VideoWindow[dwVWIndex].grVW_SSD_STRT_ADDR, VWData.SSD_STRT_ADDR);
  3574. #if ENABLE_YUVPLANAR
  3575. if (dwFourcc == FOURCC_YUVPLANAR)
  3576. {
  3577. LL32(VideoWindow[dwVWIndex].grVW_PSD_UVSTRT_ADDR, VWData.PSD_UVSTRT_ADDR);
  3578. LL32(VideoWindow[dwVWIndex].grVW_SSD_UVSTRT_ADDR, VWData.SSD_UVSTRT_ADDR);
  3579. }
  3580. #endif
  3581. LL16(VideoWindow[dwVWIndex].grVW_SD_PITCH, VWData.SD_PITCH);
  3582. if (FLG_SRC_COLOR_KEY & lpSurfaceData->dwOverlayFlags)
  3583. {
  3584. LL32(VideoWindow[dwVWIndex].grVW_CHRMKEY_MIN, VWData.CHRMKEY_MIN);
  3585. LL32(VideoWindow[dwVWIndex].grVW_CHRMKEY_MAX, VWData.CHRMKEY_MAX);
  3586. }
  3587. else if (FLG_COLOR_KEY & lpSurfaceData->dwOverlayFlags)
  3588. {
  3589. LL32(VideoWindow[dwVWIndex].grVW_CLRKEY_MIN, VWData.CLRKEY_MIN);
  3590. LL32(VideoWindow[dwVWIndex].grVW_CLRKEY_MAX, VWData.CLRKEY_MAX);
  3591. }
  3592. LL16(VideoWindow[dwVWIndex].grVW_FIFO_THRSH, VWData.FIFO_THRSH);
  3593. LL32(VideoWindow[dwVWIndex].grVW_CONTROL1, VWData.CONTROL1);
  3594. // fix for PDR #10815
  3595. // if src width >= 1536 bytes (or 3072 bytes for shrink)
  3596. // disable vertical interpolation
  3597. width = (grOverlaySrc[dwVWIndex].right - grOverlaySrc[dwVWIndex].left) * (dwBitCount / 8);
  3598. if (VW_YShrinkEn & VWData.CONTROL1)
  3599. width /= 2;
  3600. if (width >= 1536)
  3601. {
  3602. // set replication bit in TEST0 reg
  3603. pREG->VideoWindow[dwVWIndex].grVW_TEST0 |= VWVRepEnable;
  3604. }
  3605. else
  3606. {
  3607. // clear replication bit in TEST0 reg
  3608. pREG->VideoWindow[dwVWIndex].grVW_TEST0 &= ~VWVRepEnable;
  3609. }
  3610. // write last to arm
  3611. LL32(VideoWindow[dwVWIndex].grVW_CONTROL0, VWData.CONTROL0);
  3612. return TRUE;
  3613. }
  3614. /***************************************************************************
  3615. *
  3616. * FUNCTION: RegMoveVideoVW
  3617. *
  3618. * DESCRIPTION: This function is called to move the video window that has
  3619. * already been programed.
  3620. *
  3621. ****************************************************************************/
  3622. STATIC VOID RegMoveVideoVW
  3623. (
  3624. #ifdef WINNT_VER40
  3625. PDEV *ppdev,
  3626. DWORD dwVWIndex,
  3627. PDD_SURFACE_LOCAL lpSurface
  3628. #else
  3629. DWORD dwVWIndex,
  3630. LPDDRAWI_DDRAWSURFACE_LCL lpSurface,
  3631. LPGLOBALDATA lpDDHALData
  3632. #endif
  3633. )
  3634. {
  3635. LP_SURFACE_DATA lpSurfaceData = GET_SURFACE_DATA_PTR(lpSurface);
  3636. VWDATA VWData;
  3637. DWORD dwFourcc;
  3638. LONG lPitch;
  3639. DWORD dwBitCount;
  3640. RECTL rVideoRect;
  3641. PVGAR pREG = (PVGAR)lpDDHALData->RegsAddress;
  3642. ASSERT(dwNumVideoWindows > dwVWIndex);
  3643. // Determine the format of the video data
  3644. if (lpSurface->dwFlags & DDRAWISURF_HASPIXELFORMAT)
  3645. {
  3646. GetFormatInfo (&(lpSurface->lpGbl->ddpfSurface), &dwFourcc, &dwBitCount);
  3647. }
  3648. else
  3649. {
  3650. dwBitCount = BITSPERPIXEL;
  3651. if (16 == dwBitCount)
  3652. dwFourcc = BI_BITFIELDS; // 5:6:5
  3653. else
  3654. dwFourcc = BI_RGB; // 8bpp, 5:5:5, 24bpp & 32bpp
  3655. }
  3656. #ifdef WINNT_VER40
  3657. PanOverlay1_Init(ppdev,&rVideoRect,&grOverlaySrc[dwVWIndex],&grOverlayDest[dwVWIndex]);
  3658. #else
  3659. PanOverlay1_Init(&rVideoRect,&grOverlaySrc[dwVWIndex],&grOverlayDest[dwVWIndex]);
  3660. #endif
  3661. // rVideoRect is now adjusted and clipped to the panning viewport.
  3662. // Disable overlay if totally clipped by viewport.
  3663. if (((rVideoRect.right - rVideoRect.left) <= 0) ||
  3664. ((rVideoRect.bottom- rVideoRect.top ) <= 0))
  3665. {
  3666. #ifdef WINNT_VER40
  3667. DisableOverlay(ppdev, dwVWIndex);
  3668. #else
  3669. DisableOverlay(lpDDHALData, dwVWIndex);
  3670. #endif
  3671. return;
  3672. }
  3673. memset(&VWData, 0, sizeof(VWData));
  3674. VWData.CONTROL0 = pREG->VideoWindow[dwVWIndex].grVW_CONTROL0;
  3675. if (lpSurfaceData->dwOverlayFlags & FLG_ENABLED)
  3676. VWData.CONTROL0 |= VW_VWE;
  3677. VWData.CONTROL0 |= VW_ARM;
  3678. lPitch = lpSurface->lpGbl->lPitch;
  3679. // if shrink in x, set shrink x by 2 bit in CONTROL0
  3680. // shrink in y is okay, because that bit is in CONTROL1 and
  3681. // we aren't touching CONTROL1 here
  3682. if ((grOverlayDest[dwVWIndex].right - grOverlayDest[dwVWIndex].left) <
  3683. (grOverlaySrc[dwVWIndex].right - grOverlaySrc[dwVWIndex].left))
  3684. {
  3685. VWData.CONTROL0 |= VW_XShrinkBy2;
  3686. }
  3687. ComputeVWPositionData(&rVideoRect,
  3688. &grOverlaySrc[dwVWIndex],
  3689. &grOverlayDest[dwVWIndex],
  3690. lpSurface->lpGbl,
  3691. #ifndef WINNT_VER40
  3692. lpDDHALData,
  3693. #endif
  3694. dwBitCount,
  3695. &VWData,
  3696. FOURCC_YUVPLANAR == dwFourcc);
  3697. #if ENABLE_MIRRORING
  3698. if (bIsVWMirrored[dwVWIndex])
  3699. VWData.CONTROL0 |= VW_HMIRR_EN;
  3700. #endif
  3701. // Xing, isn't the memset above enough?
  3702. VWData.SSD_STRT_ADDR = 0;
  3703. #if DDRAW_COMPAT >= 50
  3704. if( gwNotify & VPE_ON)
  3705. {
  3706. if(lpSurface->lpSurfMore->lpVideoPort != NULL)
  3707. {
  3708. if((lpSurface->lpSurfMore->lpVideoPort->ddvpInfo.dwVPFlags
  3709. &DDVP_AUTOFLIP)
  3710. && (lpSurface->lpSurfMore->dwOverlayFlags & DDOVER_AUTOFLIP)
  3711. && (lpSurface->lpAttachListFrom != NULL)
  3712. && (lpSurface->lpAttachListFrom->lpAttached != NULL))
  3713. {
  3714. VWData.SSD_STRT_ADDR = lpSurfaceData->dwAutoBaseAddr2 +
  3715. lpSurfaceData->dwOverlayOffset;
  3716. if( VWData.PSD_STRT_ADDR == VWData.SSD_STRT_ADDR )
  3717. {
  3718. VWData.PSD_STRT_ADDR = lpSurfaceData->dwAutoBaseAddr1 +
  3719. lpSurfaceData->dwOverlayOffset;
  3720. }
  3721. VWData.CONTROL0 &= ~0x30000ul;
  3722. VWData.CONTROL0 |= 0x20000ul; //enable the second buffer
  3723. if(!(lpSurface->lpSurfMore->dwOverlayFlags & DDOVER_BOB))
  3724. {
  3725. //For non-smooth-interlaced auto-flip these two address need
  3726. // to be switched. HW BUG
  3727. DWORD dwTmp = VWData.PSD_STRT_ADDR;
  3728. VWData.PSD_STRT_ADDR = VWData.SSD_STRT_ADDR;
  3729. VWData.SSD_STRT_ADDR = dwTmp;
  3730. }
  3731. }
  3732. else if((lpSurface->lpSurfMore->dwOverlayFlags & DDOVER_BOB)
  3733. &&(lpSurface->lpSurfMore->lpVideoPort->ddvpInfo.dwVPFlags
  3734. & DDVP_INTERLEAVE))
  3735. {
  3736. VWData.SSD_STRT_ADDR = VWData.PSD_STRT_ADDR + lPitch;
  3737. }
  3738. }
  3739. }
  3740. #endif
  3741. // Now start programming the registers
  3742. ASSERT(! (pREG->VideoWindow[dwVWIndex].grVW_TEST0 & VW_PostImed));
  3743. #ifdef WINNT_VER40
  3744. WaitForVWArmToClear(ppdev, dwVWIndex);
  3745. #else
  3746. WaitForVWArmToClear(lpDDHALData, dwVWIndex);
  3747. #endif
  3748. LL16(VideoWindow[dwVWIndex].grVW_HSTRT, VWData.HSTRT);
  3749. LL16(VideoWindow[dwVWIndex].grVW_HEND, VWData.HEND);
  3750. LL16(VideoWindow[dwVWIndex].grVW_HSDSZ, VWData.HSDSZ);
  3751. LL16(VideoWindow[dwVWIndex].grVW_VSTRT, VWData.VSTRT);
  3752. LL16(VideoWindow[dwVWIndex].grVW_VEND, VWData.VEND);
  3753. LL32(VideoWindow[dwVWIndex].grVW_PSD_STRT_ADDR, VWData.PSD_STRT_ADDR);
  3754. LL32(VideoWindow[dwVWIndex].grVW_SSD_STRT_ADDR, VWData.SSD_STRT_ADDR);
  3755. #if ENABLE_YUVPLANAR
  3756. if (dwFourcc == FOURCC_YUVPLANAR)
  3757. {
  3758. LL32(VideoWindow[dwVWIndex].grVW_PSD_UVSTRT_ADDR, VWData.PSD_UVSTRT_ADDR);
  3759. LL32(VideoWindow[dwVWIndex].grVW_SSD_UVSTRT_ADDR, VWData.SSD_UVSTRT_ADDR);
  3760. }
  3761. #endif
  3762. LL16(VideoWindow[dwVWIndex].grVW_SD_PITCH, VWData.SD_PITCH);
  3763. LL32(VideoWindow[dwVWIndex].grVW_CONTROL0, VWData.CONTROL0);
  3764. }
  3765. /***************************************************************************
  3766. *
  3767. * FUNCTION: ChipIOReadBWRegs
  3768. *
  3769. * DESCRIPTION:
  3770. *
  3771. ****************************************************************************/
  3772. BOOL ChipIOReadBWRegs
  3773. (
  3774. #ifdef WINNT_VER40
  3775. PDEV *ppdev,
  3776. #else
  3777. LPGLOBALDATA lpDDHALData,
  3778. #endif
  3779. LPBWREGS pBWRegs
  3780. )
  3781. {
  3782. PVGAR pREG = (PVGAR)lpDDHALData->RegsAddress;
  3783. #ifdef WINNT_VER40
  3784. pBWRegs->BCLK_Mult = pREG->grBCLK_Multiplier;
  3785. #else
  3786. pBWRegs->BCLK_Mult = pREG->grBCLK_numerator;
  3787. #endif
  3788. pBWRegs->MISCOutput = pREG->grMISC;
  3789. pBWRegs->VCLK3Denom = pREG->grSRE;
  3790. pBWRegs->VCLK3Num = pREG->grSR1E;
  3791. pBWRegs->DispThrsTiming = pREG->grDisplay_Threshold_and_Tiling;
  3792. pBWRegs->RIFControl = pREG->grRIF_CONTROL;
  3793. pBWRegs->GfVdFormat = pREG->grFormat;
  3794. #ifdef WINNT_VER40
  3795. pBWRegs->BCLK_Denom = pREG->grBCLK_Denominator;
  3796. #else
  3797. pBWRegs->BCLK_Denom = pREG->grBCLK_denom;
  3798. #endif
  3799. pBWRegs->Control2 = pREG->grCONTROL2;
  3800. pBWRegs->CR1 = pREG->grCR1;
  3801. pBWRegs->CR1E = pREG->grCR1E;
  3802. #if ENABLE_256_BYTE_FETCH
  3803. // if we are disabling 256 byte fetch when overlay or videoport
  3804. // surfaces are created, then wipe out the 256 byte fetch related
  3805. // bits in CONTROL2
  3806. // clear MONO_SAFETY_256 & BYTE_REQ_256 bits of CONTROL2 register
  3807. pBWRegs->Control2 &= ~(MONO_SAFETY_256 | BYTE_REQ_256);
  3808. #endif
  3809. return TRUE;
  3810. }
  3811. #ifdef USE_OLD_BWEQ
  3812. /***************************************************************************
  3813. *
  3814. * FUNCTION: KillOverlay
  3815. *
  3816. * DESCRIPTION: Disable overlay in the following cases
  3817. *
  3818. ****************************************************************************/
  3819. BOOL KillOverlay
  3820. (
  3821. #ifdef WINNT_VER40
  3822. PDEV *ppdev,
  3823. #endif
  3824. WORD wScreenX,
  3825. UINT uScreenDepth
  3826. )
  3827. {
  3828. BWREGS bwregs;
  3829. DWORD dwMCLK, dwVCLK;
  3830. #ifdef WINNT_VER40
  3831. if(!ChipIOReadBWRegs(ppdev, &bwregs))
  3832. #else
  3833. if(!ChipIOReadBWRegs(&bwregs))
  3834. #endif
  3835. {
  3836. return TRUE;
  3837. }
  3838. if(!ChipCalcMCLK(&bwregs, &dwMCLK))
  3839. {
  3840. return TRUE;
  3841. }
  3842. if(!ChipCalcVCLK(&bwregs, &dwVCLK))
  3843. {
  3844. return TRUE;
  3845. }
  3846. if(dwMCLK < 75000000)
  3847. {
  3848. if(uScreenDepth == 32 )
  3849. {
  3850. if(wScreenX == 640 )
  3851. {
  3852. if(dwVCLK > 32000000)
  3853. return TRUE;
  3854. }
  3855. }
  3856. }
  3857. return FALSE;
  3858. }
  3859. #endif // USE_OLD_BWEQ
  3860. #endif // WINNT_VER35