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
4313 lines
134 KiB
/**************************************************************************
|
|
***************************************************************************
|
|
*
|
|
* Copyright (c) 1997, Cirrus Logic, Inc.
|
|
* All Rights Reserved
|
|
*
|
|
* FILE: 5465over.c
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
* REVISION HISTORY:
|
|
*
|
|
* $Log: \\uinac\log\log\laguna\ddraw\src\5465over.c $
|
|
*
|
|
* Rev 1.75 19 May 1998 09:54:36 xcong
|
|
* Assign GfVdFormat in ChipIOReadBWRegs() for TV-Out support.
|
|
*
|
|
* Rev 1.74 07 Apr 1998 17:28:58 xcong
|
|
* Get CR1 and CR1E in ChipIOBWRead()
|
|
*
|
|
* Rev 1.73 Mar 30 1998 13:06:52 frido
|
|
* Changed some parenthesis so the Codewright source parser can find the
|
|
* functions.
|
|
*
|
|
* Rev 1.72 08 Jan 1998 10:45:28 xcong
|
|
* Don't pass lpDDHALData in ComputeVWPositionData() for NT.
|
|
*
|
|
* Rev 1.71 07 Jan 1998 17:55:32 xcong
|
|
* Delete *lpDDHALData in SetPostion() for NT only.
|
|
*
|
|
*
|
|
* Rev 1.70 06 Jan 1998 14:43:54 xcong
|
|
* Pass lpDDHALData in CurrentVLine().
|
|
*
|
|
* Rev 1.69 06 Jan 1998 11:42:06 xcong
|
|
* Change pDriverData into local lpDDHALData for multi-monitor support.
|
|
*
|
|
* Rev 1.68 Dec 11 1997 14:03:28 frido
|
|
* PDR#11011: A workaround has been added to convert a "dummy"
|
|
* update into a SHOW update when certain criteria are met.
|
|
*
|
|
* Rev 1.67 Dec 10 1997 13:41:32 frido
|
|
* Merged from 1.62 branch.
|
|
*
|
|
* Rev 1.63.2.0 Dec 03 1997 14:44:54 frido
|
|
* PDR#11017. The hardware is broken when shrinking videos horizontally with
|
|
* RGB32 format. A software workaround has been added to disable overlay in
|
|
* this case.
|
|
*
|
|
* Rev 1.66 Dec 10 1997 13:32:08 frido
|
|
* Merged from 1.62 branch.
|
|
*
|
|
* Rev 1.65 14 Nov 1997 13:04:18 XCONG
|
|
* Undo the modification for dwOverlayOffset for NT.
|
|
*
|
|
* Rev 1.64 06 Nov 1997 15:46:14 XCONG
|
|
* When update dwOverlayOffset, update this variable for all the attached surf
|
|
* too.
|
|
*
|
|
* Rev 1.63.2.0 Dec 03 1997 14:44:54 frido
|
|
* PDR#11017. The hardware is broken when shrinking videos horizontally with
|
|
* RGB32 format. A software workaround has been added to disable overlay in
|
|
* this case.
|
|
*
|
|
* Rev 1.63 04 Nov 1997 13:41:34 RUSSL
|
|
* Fix for PDR #10815
|
|
*
|
|
* Rev 1.62 04 Nov 1997 12:57:02 RUSSL
|
|
* Removed forcing of min stretch in 24bpp to start at 1000 (for new bweq code)
|
|
*
|
|
* Rev 1.61 30 Oct 1997 14:34:18 RUSSL
|
|
* Mods to support new interface to bweqn code
|
|
* Moved KillOverlay function here from 5465bw.c
|
|
* ChipIOReadBWRegs reads additional regs that are new to the BWREGS struct
|
|
* Added code in ChipIOReadBWRegs to clear bits 4 & 7 (the 256 byte fetch
|
|
* related bits) of the BWREGS Control2 value. The bweqn should use
|
|
* 256 byte fetch off values, since we are disabling 256 byte fetch
|
|
* when overlay or videoport surfaces are created.
|
|
*
|
|
* Rev 1.60 08 Oct 1997 11:15:02 RUSSL
|
|
* Fix for NT40 build without overlay support
|
|
*
|
|
* Rev 1.59 25 Sep 1997 17:33:40 RUSSL
|
|
* Modified HeapAlloc calls to use HEAP_ALLOC macro
|
|
* and HeapFree calls to use HEAP_FREE macro
|
|
*
|
|
* Rev 1.58 19 Sep 1997 14:35:04 bennyn
|
|
* Fixed NT4.0 5462/64 build problem
|
|
*
|
|
* Rev 1.57 17 Sep 1997 16:27:20 RUSSL
|
|
* Looks like setting the HardwareOwner is FlipOverlayStatus is an NT only
|
|
* thing.
|
|
*
|
|
* Rev 1.56 16 Sep 1997 15:28:38 bennyn
|
|
* Modified for NT DD overlay
|
|
*
|
|
* Rev 1.55 04 Sep 1997 09:43:26 RUSSL
|
|
* Fixed up Xing's changes so they compile for NT
|
|
*
|
|
* Rev 1.54 04 Sep 1997 10:07:52 XCONG
|
|
* Delete f256Fetch, since the code to disable 256 byte fetch is moved to
|
|
* surface.c, nobody use this variable anymore.
|
|
*
|
|
* Rev 1.53 03 Sep 1997 18:40:12 XCONG
|
|
* Disable overlay in 640*480*32 at 85Hz by calling KillOverlay().
|
|
* This is temporary fix for PDR#10381.
|
|
*
|
|
* Rev 1.52 03 Sep 1997 16:35:02 RUSSL
|
|
*
|
|
* Rev 1.51 02 Sep 1997 12:35:48 RUSSL
|
|
* Added GET_SURFACE_DATA_PTR macro and modified relevant code to get ptr
|
|
* using macro. This will minimize the remaining changes needed for NT.
|
|
*
|
|
* Rev 1.50 29 Aug 1997 16:47:26 RUSSL
|
|
* Added support for NT
|
|
* It's not quite complete, we need to allocate a LP_SURFACE_DATA structure
|
|
* for each overlay surface and store it somewhere in the DD_SURFACE_LOCAL
|
|
* structure (this needs to be done by CreateSurface). And then add code
|
|
* in here to get access to that struct when necessary. #pragma message's
|
|
* indicate where.
|
|
* Removed code to disable 256 byte fetch, its done by CreateSurface32
|
|
*
|
|
* Rev 1.49 15 Aug 1997 16:38:30 XCONG
|
|
* Put overlay source alignment back to 1. This is screen alignment instead o
|
|
*
|
|
* Rev 1.48 14 Aug 1997 16:47:42 XCONG
|
|
* If overlay window is created, disable 256 byte fetch.
|
|
* Move gwNormalDTTR initialization into CreateSurface function.
|
|
*
|
|
* Rev 1.47 29 Jul 1997 15:29:14 XCONG
|
|
* For autoflip overlay make sure dwNumAutoFlip == 2
|
|
*
|
|
* Rev 1.46 28 Jul 1997 09:19:46 RUSSL
|
|
* Modified GetOverlayFlipStatus to check arm bit in hw rather than determine
|
|
* elapsed time since previous flip
|
|
* Added video window index argument to GetOverlayFlipStatus function
|
|
* Made dwNumVideoWindows a global var rather than static
|
|
* Moved GetVideoWindowIndex inline function to overlay.h
|
|
*
|
|
* Rev 1.45 24 Jul 1997 17:50:14 RUSSL
|
|
* modified src alignment values reported in ddhalinfo
|
|
* fixed error with disabling dst colorkey at 24bpp, I was turning off
|
|
* src colorkey related caps bits
|
|
*
|
|
* Rev 1.44 16 Jul 1997 17:15:32 XCONG
|
|
* Add and use dwOverlayOffset and more in SURFACE_DATA structure in order
|
|
* to eliminate global variables.
|
|
*
|
|
* Rev 1.43 14 Jul 1997 13:11:50 RUSSL
|
|
* added ChipIOReadBWRegs (moved here from 5465bw.c)
|
|
*
|
|
* Rev 1.42 11 Jul 1997 11:57:26 XCONG
|
|
* Fix ptich problem in FlipOverlay for interleaved surface.
|
|
*
|
|
* Rev 1.41 11 Jul 1997 08:57:02 RUSSL
|
|
* Fixed y clipping of CLPL surfaces in FlipOverlaySurface and
|
|
* ComputeVWPositionData
|
|
*
|
|
* Rev 1.40 09 Jul 1997 15:27:44 RUSSL
|
|
* Implemented CLPL lobotomy mode
|
|
* allocates a block of system memory for the app to write the UV data to,
|
|
* when the app locks the surface the system memory addresses are returned
|
|
* so the app writes to system memory, and when the app unlocks the surface,
|
|
* the data is copied into the frame buffer. The copy is done from left to
|
|
* right a scanline at a time. There appears to be a hw bug when writing
|
|
* to aperture 3 from right to left. Roughly every other 4 dwords is
|
|
* dropped. This bug showed up when allowing the Compcore MPEG player to
|
|
* write directly to aperture 3. (also see comments in SysToFBCopy)
|
|
* Added GetUserSettings to read user controllable options from registry
|
|
* Current user controllable settings are:
|
|
* OverlayBW - enables/disables use of bandwidth equation (default=enabled)
|
|
* OverlayCLPL - enables/disables support for CLPL format (default=enabled)
|
|
* OverlayCLPLLobotomyMode - enables/disables above described CLPL
|
|
* lobotomy mode (default=enabled)
|
|
* For forward compatibility, assume future chips have one video window
|
|
*
|
|
* Rev 1.39 30 Jun 1997 10:37:20 RUSSL
|
|
* Added global var to control whether or not CLPL is supported
|
|
* CLPL support is based on a registry key "OverlayCLPL", set to "on" to
|
|
* enable CLPL, default is "off"
|
|
*
|
|
* Rev 1.38 23 Jun 1997 10:50:10 RUSSL
|
|
* Modified for reduced size of CLPL surfaces
|
|
*
|
|
* Rev 1.37 20 Jun 1997 13:47:44 RUSSL
|
|
* Enabled CLPL overlay surface support (aka YUV420 & YUVPLANAR)
|
|
* Enabled 32 bit overlay surface support
|
|
* Removed REQUIREs and HW_(UN)LOCK_SEMAPHOREs (they didn't do anything anyway)
|
|
* CreateSurface now returns an HRESULT
|
|
*
|
|
* Rev 1.36 09 Jun 1997 13:46:22 XCONG
|
|
* In FlipOverlaySurface(), Update VW_CONTROL0 too for DDFLIP_EVEN.
|
|
*
|
|
* Rev 1.35 03 Jun 1997 09:52:50 RUSSL
|
|
* Added setting of VWEnable bit in CONTROL0 register in SetPosition and
|
|
* FlipOverlaySurface functions
|
|
*
|
|
* Rev 1.34 22 May 1997 16:27:46 RUSSL
|
|
* Disable overlay shrink at 24bpp
|
|
*
|
|
* Rev 1.33 15 May 1997 17:36:38 RUSSL
|
|
* Set ddCaps.dwAlignStrideAlign to bytes per pixel in Init5465Overlay
|
|
* Set bNoOverlayInThisMode to TRUE if in interlaced mode
|
|
*
|
|
* Rev 1.32 15 May 1997 15:48:20 XCONG
|
|
* Change all the BWE flags back (in bw.h).
|
|
*
|
|
* Rev 1.31 15 May 1997 10:56:54 RUSSL
|
|
* Changed IsFormatValid to return an HRESULT rather than a BOOL so
|
|
* CanCreateSurface32 can return a reasonable error code if the surface
|
|
* can't be created
|
|
*
|
|
* Rev 1.30 13 May 1997 09:53:04 RUSSL
|
|
* Removed code in Init5465Info that was initializing the VW0_TEST0 register
|
|
*
|
|
* Rev 1.29 12 May 1997 17:22:32 XCONG
|
|
* Change wVPortCreated in VideoPortEx into wNotify
|
|
*
|
|
* Rev 1.28 10 May 1997 12:51:02 EDWINW
|
|
* Fix PDR 9574. DestroySurface trashes tile size when trying to restore the
|
|
* DTTR's FIFO threshold.
|
|
*
|
|
* Rev 1.27 09 May 1997 16:26:36 XCONG
|
|
* Only check VPE_ON and OVERLAY_ON flags in DX5
|
|
*
|
|
* Rev 1.26 09 May 1997 11:10:22 XCONG
|
|
* Uses the flags in overlay.h for BWE flags. Befor save and restore
|
|
* gwNormIDTTR check VPE is still running or not, because VPE will do the same
|
|
* thing.
|
|
*
|
|
* Rev 1.25 08 May 1997 17:57:40 XCONG
|
|
* Make the BWE variables global. Set uDispDepth as the same as
|
|
* sourc depth instead of graphic depth.
|
|
*
|
|
* Rev 1.24 24 Apr 1997 14:36:46 XCONG
|
|
* For SW playback only use smooth-interlaced mode when BOB and INTERLEAVE
|
|
* flags are both set.
|
|
*
|
|
* Rev 1.23 24 Apr 1997 12:02:54 RUSSL
|
|
* Reenabled writing 0x52 to TEST0 reg on 5465AC if bw eqn is in use.
|
|
* 800x600x16 @ 85Hz looks like it's running on the hairy edge of
|
|
* stability with this. All other modes (at all resolutions, colordepths
|
|
* and refresh rates) with sufficient bandwidth to use overlay looked
|
|
* stable although there is still some static in some modes.
|
|
*
|
|
* Rev 1.22 17 Apr 1997 09:38:22 RUSSL
|
|
* Fix for PDR #9339, disable destination colorkeying support at 24bpp.
|
|
* This looks like its a HWBUG. This code can be disabled by defining
|
|
* HWBUG_24BPP_DST_COLORKEY as zero.
|
|
* Write DTTR FIFO value returned by ChipIsEnoughBandwidth, original DTTR
|
|
* setting is saved in a global var which is restored when final overlay
|
|
* surface is destroyed
|
|
*
|
|
* Rev 1.21 16 Apr 1997 10:19:28 RUSSL
|
|
* Had to update list of parms passed to GetBooleanSetting
|
|
*
|
|
* Rev 1.20 15 Apr 1997 17:46:46 RUSSL
|
|
* Added use of PDC's bandwidth equation
|
|
* Added use of registry key/system.ini entry to disable use of BWEqn
|
|
* Removed IsSufficientBandwidth functions
|
|
* Modified Init5465Info to determine min & max zoom factors in current
|
|
* mode by calling BWEqn
|
|
* ComputeVWFifoThreshold sets VW fifo threshold to value returned previously
|
|
* by bandwidth equation (or it uses 8 if use of BWEqn is disabled)
|
|
*
|
|
* Rev 1.19 04 Apr 1997 16:11:56 XCONG
|
|
* Add support for SW double-buffer and BOB palyback. Change the way to
|
|
* calculate VACCUM_STP for interleaved BOB.
|
|
*
|
|
* Rev 1.18 03 Apr 1997 09:58:42 RUSSL
|
|
* Disable writing 0x42 or 0x52 to TEST0 reg, it's more grief than it's worth
|
|
* Wait until we get a real bandwidth equation
|
|
* Made IsFormatValid always return FALSE when we're in an interlaced mode,
|
|
* this essentially disables use of overlay in interlaced modes
|
|
*
|
|
* Rev 1.17 28 Mar 1997 14:57:26 RUSSL
|
|
* Need to write 0x42 to TEST0 in 24bpp modes
|
|
* Display driver now puts 32bit linear address of pDevice in
|
|
* pDriverData->lpPDevice, so don't need to call MapSLFix
|
|
*
|
|
* Rev 1.16 24 Mar 1997 22:54:58 XCONG
|
|
* Add auto-flip overlay support. Include SSD_STRT_ADDR in tagVWDATA for
|
|
* all the version of DDRAW.
|
|
*
|
|
* Rev 1.15 24 Mar 1997 16:44:56 RUSSL
|
|
* Changed CreateSurface so that CreateSurface32 fills in the blocksize, etc.
|
|
*
|
|
* Rev 1.14 24 Mar 1997 12:12:40 RUSSL
|
|
* Added write of 0x52 to TEST0 reg on 5465AC, this enables some hw fixes
|
|
*
|
|
* Rev 1.13 19 Mar 1997 11:47:40 cjl
|
|
* Simply added line to include new ddshared.h file.
|
|
*
|
|
* Rev 1.12 12 Mar 1997 14:59:00 RUSSL
|
|
* replaced a block of includes with include of precomp.h for
|
|
* precompiled headers
|
|
* Removed unneeded pragma message related to mapping in YUY2 aperture
|
|
*
|
|
* Rev 1.11 07 Mar 1997 12:43:22 RUSSL
|
|
* Modified DDRAW_COMPAT usage
|
|
* Merged in PDC's VPE code for DX5
|
|
* Made IsSufficientBandwidth5465 global rather than static
|
|
*
|
|
* Rev 1.10 24 Feb 1997 13:49:52 RUSSL
|
|
* Enabled YUY2 format
|
|
* Added RBGtoYCbCr function
|
|
* Modified DetermineVWColorKeyData to handle source color keying of UYVY
|
|
* and YUY2 surfaces
|
|
*
|
|
* Rev 1.9 14 Feb 1997 10:01:14 RUSSL
|
|
* Added more conditional compilation flags to enable/disable horizontal
|
|
* mirroring, use of REQUIRE for qfree checking and use of HW_IN_USE
|
|
* driver semaphore.
|
|
* If building debug version, change inline functions to not be inline.
|
|
* WINICE can't deal with inline functions, so source code doesn't line
|
|
* up correctly.
|
|
* Added ASSERT to make sure post immediately bit is clear in TEST0 reg
|
|
* before updating video window registers
|
|
* Ignore DDOVER_DDFX flag in UpdateSurface because Microsoft's WHQL Overfly
|
|
* test program sets this flag but fills overlayFX.dwDDFX with junk.
|
|
* In some cases they set the DDOVERFX_MIRRORLEFTRIGHT bit even though
|
|
* we don't even say we support that capability! In order to get Overfly
|
|
* to work, we need to ignore the overlayFX.dwDDFX flags that we don't
|
|
* support (which is currently all of them) This fixes BPR #8528
|
|
*
|
|
* Rev 1.8 04 Feb 1997 14:15:48 RUSSL
|
|
* Added check in IsFormatValid to see if VPM is using the hardware
|
|
* Added SaveRectangles to reduce duplicate code in UpdateSurface
|
|
* Adjusted zoom code calculation for x shrink so don't go past end of src
|
|
*
|
|
* Rev 1.7 31 Jan 1997 08:59:30 RUSSL
|
|
* Added better video window support checking based on chip id in
|
|
* Init5465Overlay
|
|
* Adjusted init code alignment requirements reported to ddraw
|
|
* Addressed most of pragma message statements
|
|
* Fixed bug in FlipOverlaySurface when surface is clipped
|
|
* Enabled overlay shrink caps and added shrink zoom code calculations
|
|
*
|
|
* Rev 1.6 29 Jan 1997 18:00:30 RUSSL
|
|
* Added use of require macro before register writes
|
|
* Modified zoom code calculations
|
|
*
|
|
* Rev 1.5 28 Jan 1997 17:34:58 RUSSL
|
|
* VEND is the last line shown by the overlay
|
|
* Karl and I figured out how to make source color key work (at least at 16bpp)
|
|
* hopefully the code matches what we did manually. We need an app
|
|
* that uses source color keying to really test it.
|
|
*
|
|
* Rev 1.4 28 Jan 1997 15:29:42 RUSSL
|
|
* destination color keying is actually done using the hardware CLRKEY
|
|
* registers and setting OCCLUDE in CONTROL0 to 1 (the documentation
|
|
* appears to have the source color key settings & the destination color
|
|
* key settings swapped)
|
|
* source color keying doesn't appear to work
|
|
*
|
|
* Rev 1.3 27 Jan 1997 19:10:26 RUSSL
|
|
* Use a variable dwNumVideoWindows rather than a hardcoded define
|
|
* Added WaitForArmToClear, Set5465FlipDuration & PanOverlay1_Init
|
|
* Made IsFormatValid return TRUE only for UYVY overlay surfaces for now
|
|
* Made CreateSurface use rectangular allocation, specify block size for
|
|
* rgb surfaces if we are managing surface creation, let CreateSurface
|
|
* return NOTHANDLED so DDraw will fill in the surface ptr
|
|
* Added error checking for dwReserved1 of local surface struct in case
|
|
* it's NULL
|
|
* Added additional debug output
|
|
* Put code in ComputeVWZoomCodes, ComputeVWPosData, DetermineColorKeyData,
|
|
* ComputeVWFifoThreshold
|
|
* Added programming of the hw registers in RegInitVideoVW & RegMoveVideoVW
|
|
*
|
|
* Rev 1.2 21 Jan 1997 15:44:40 RUSSL
|
|
* Okay this didn't compile and link last time
|
|
*
|
|
* Rev 1.1 21 Jan 1997 14:55:14 RUSSL
|
|
* Port of 5480 overlay code from CirrusMM driver to 5465
|
|
*
|
|
* Rev 1.0 15 Jan 1997 10:36:22 RUSSL
|
|
* Initial revision.
|
|
*
|
|
***************************************************************************
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* I N C L U D E S
|
|
****************************************************************************/
|
|
|
|
#include "precomp.h"
|
|
|
|
#if defined WINNT_VER35 // WINNT_VER35
|
|
// If WinNT 3.5 skip all the source code
|
|
#elif defined (NTDRIVER_546x)
|
|
// If WinNT 4.0 and 5462/64 build skip all the source code
|
|
#elif defined(WINNT_VER40) && !defined(OVERLAY)
|
|
// if nt40 without overlay, skip all the source code
|
|
#else
|
|
|
|
#ifndef WINNT_VER40
|
|
#include "ddshared.h"
|
|
#include "flip.h"
|
|
#include "surface.h"
|
|
#include "blt.h"
|
|
#include "overlay.h"
|
|
|
|
#if DDRAW_COMPAT >= 50
|
|
#include "vp.h"
|
|
#endif
|
|
|
|
#include "settings.h"
|
|
#include "5465bw.h"
|
|
#include "swat.inc"
|
|
#endif
|
|
|
|
/***************************************************************************
|
|
* D E F I N E S
|
|
****************************************************************************/
|
|
|
|
#ifdef WINNT_VER40
|
|
#define ENABLE_YUY2 0
|
|
#define ENABLE_YUVPLANAR 0
|
|
#define DISABLE_MOST_MODES 0
|
|
#else
|
|
#define ENABLE_YUY2 1
|
|
#define ENABLE_YUVPLANAR 1
|
|
#define DISABLE_MOST_MODES 0
|
|
#endif
|
|
|
|
#define ENABLE_SD_RGB32 1
|
|
|
|
#define ENABLE_MIRRORING 0
|
|
|
|
#define HWBUG_24BPP_DST_COLORKEY 1
|
|
|
|
#ifdef DEBUG
|
|
#define INLINE
|
|
#else
|
|
#define INLINE __inline
|
|
#endif
|
|
|
|
// VW_CAP0 bits
|
|
#define VWCAP_VW_PRESENT 0x00000001
|
|
|
|
// VW_CONTROL1 bits
|
|
#define VW_ByPassClrSpc 0x00000002
|
|
#define VW_YShrinkEn 0x00000001
|
|
|
|
// VW_CONTROL0 bits
|
|
#define VW_XShrinkBy2 0x80000000
|
|
#define VW_ClkMode2x 0x40000000
|
|
#define VW_FIFO_THRSH_EN 0x20000000
|
|
#define VW_ALPHA_KEYCMP_EN 0x10000000
|
|
|
|
#define VW_DB_VPORT_ID_MASK 0x0F000000
|
|
#define VW_DB_VSM_ID_MASK 0x00F00000
|
|
#define VW_DB_CTL_MASK 0x000F0000
|
|
|
|
#define VW_SD_FRMT_MASK 0x0000FF00
|
|
#define VW_OCCLUDE_MASK 0x000000F0
|
|
|
|
#define VW_SMTH_INT 0x00000008
|
|
#define VW_HMIRR_EN 0x00000004
|
|
#define VW_VWE 0x00000002
|
|
#define VW_ARM 0x00000001
|
|
|
|
// Source Data Formats for SD_FRMT
|
|
#define SD_YUV422 0x00 // ITU 601 compliant YUV data
|
|
#define SD_YUV420 0x03 // ITU 601 compliant YUV data
|
|
#define SD_YUV422_FS 0x04 // Full Scale YUV data
|
|
#define SD_YVU420_FS 0x07 // Full Scale YUV data
|
|
#define SD_RGB16_555 0x08 // 5:5:5
|
|
#define SD_RGB16_565 0x09 // 5:6:5
|
|
#define SD_RGB32 0x0B // ARGB
|
|
|
|
#define SD_FRMT_SHIFT 8
|
|
|
|
// Occlude types for OCCLUDE
|
|
#define NO_OCCLUSION 0 // video window always displayed
|
|
#define COLOR_KEY 1 // destination color keying
|
|
#define CHROMA_KEY 2 // source color keying
|
|
|
|
#define OCCLUDE_SHIFT 4
|
|
|
|
// VW_TEST0 bits
|
|
#define VW_PostImed 1
|
|
#define VWVRepEnable 0x4
|
|
|
|
// defines used in Init5465Info()
|
|
#define SRC_WIDTH 160
|
|
#define SRC_HEIGHT 120
|
|
#define MAX_ZOOM 8000
|
|
#define MIN_ZOOM 500
|
|
#define ZOOM_STEP 100
|
|
|
|
#ifdef WINNT_VER40
|
|
#define lpDDHALData ((DRIVERDATA *)(&(ppdev->DriverData)))
|
|
#define ASSERT(x)
|
|
#define DRAW_ENGINE_BUSY DrawEngineBusy(lpDDHALData)
|
|
#endif
|
|
|
|
#ifdef WINNT_VER40
|
|
#define GET_SURFACE_DATA_PTR(lpSurface) (LP_SURFACE_DATA)((lpSurface)->dwReserved1)
|
|
#else
|
|
#define GET_SURFACE_DATA_PTR(lpSurface) (LP_SURFACE_DATA)((lpSurface)->dwReserved1)
|
|
#endif
|
|
|
|
#if ENABLE_256_BYTE_FETCH
|
|
// bit defs for PERFORMANCE register
|
|
#define ECO_256_BYTES_FIX_EN 0x4000
|
|
// bit defs for CONTROL2 register
|
|
#define MONO_SAFETY_256 0x0080
|
|
#define BYTE_REQ_256 0x0010
|
|
#endif
|
|
|
|
/***************************************************************************
|
|
* T Y P E D E F S
|
|
****************************************************************************/
|
|
|
|
typedef struct tagVWDATA
|
|
{
|
|
WORD HSTRT;
|
|
WORD HSDSZ;
|
|
WORD HEND;
|
|
DWORD HACCUM_STP;
|
|
DWORD HACCUM_SD;
|
|
WORD VSTRT;
|
|
WORD VEND;
|
|
DWORD VACCUM_STP;
|
|
DWORD VACCUM_SDA;
|
|
DWORD VACCUM_SDB;
|
|
DWORD PSD_STRT_ADDR;
|
|
DWORD SSD_STRT_ADDR;
|
|
#if ENABLE_YUVPLANAR
|
|
DWORD PSD_UVSTRT_ADDR;
|
|
DWORD SSD_UVSTRT_ADDR;
|
|
#endif
|
|
WORD SD_PITCH;
|
|
DWORD CLRKEY_MIN;
|
|
DWORD CLRKEY_MAX;
|
|
DWORD CHRMKEY_MIN;
|
|
DWORD CHRMKEY_MAX;
|
|
// WORD BRIGHT_ADJ;
|
|
// BYTE Z_ORDER;
|
|
WORD FIFO_THRSH;
|
|
DWORD CONTROL1;
|
|
DWORD CONTROL0;
|
|
// DWORD CAP1;
|
|
// DWORD CAP0;
|
|
// DWORD TEST0;
|
|
} VWDATA;
|
|
|
|
typedef struct tagUSERSETTINGS
|
|
{
|
|
BOOL *pVar;
|
|
char *pRegKey;
|
|
BOOL defaultVal;
|
|
} USERSETTINGS;
|
|
|
|
#if ENABLE_YUVPLANAR
|
|
// structure for CLPL (YUV planar) surface
|
|
typedef struct tagCLPLInfo
|
|
{
|
|
LPVOID fpYSurface; // Y data in first aperture
|
|
LPVOID fpUSurface; // U data in 0-2M of fourth aperture
|
|
LPVOID fpVSurface; // V data in 2-4M of fourth aperture
|
|
|
|
// pointers for CLPLLobotomyMode
|
|
LPVOID fpUSystemSurface;
|
|
LPVOID fpVSystemSurface;
|
|
LPVOID fpRealUSurface; // U data in 0-2M of fourth aperture
|
|
LPVOID fpRealVSurface; // V data in 2-4M of fourth aperture
|
|
} CLPLInfo;
|
|
|
|
typedef CLPLInfo *LPCLPLSURFACE;
|
|
#endif
|
|
|
|
/***************************************************************************
|
|
* E X T E R N A L V A R I A B L E S
|
|
****************************************************************************/
|
|
|
|
#ifndef WINNT_VER40
|
|
#if DDRAW_COMPAT >= 50
|
|
extern WORD gwNotify; //#xc
|
|
#endif
|
|
#endif
|
|
|
|
/***************************************************************************
|
|
* S T A T I C V A R I A B L E S
|
|
****************************************************************************/
|
|
|
|
#ifdef WINNT_VER40
|
|
|
|
// For NT these are in ppdev->DriverData
|
|
#define bUseBWEqn ppdev->DriverData.bUseBWEqn
|
|
#define bNoOverlayInThisMode ppdev->DriverData.bNoOverlayInThisMode
|
|
|
|
#define lpHardwareOwner ppdev->DriverData.lpHardwareOwner
|
|
#define lpColorSurfaceVW ppdev->DriverData.lpColorSurfaceVW
|
|
#define lpSrcColorSurfaceVW ppdev->DriverData.lpSrcColorSurfaceVW
|
|
|
|
#define grOverlaySrc ppdev->DriverData.grOverlaySrc
|
|
#define grOverlayDest ppdev->DriverData.grOverlayDest
|
|
#define gdwFourccVW ppdev->DriverData.gdwFourccVW
|
|
#if ENABLE_MIRRORING
|
|
#define bIsVWMirrored ppdev->DriverData.bIsVWMirrored
|
|
#endif
|
|
|
|
#define gdwAvailVW ppdev->DriverData.gdwAvailVW // Next available video window
|
|
//#define gwZOrder ppdev->DriverData.gwZOrder // default primary on top.
|
|
#define gdwColorKey ppdev->DriverData.gdwColorKey
|
|
#define gdwSrcColorKeyLow ppdev->DriverData.gdwSrcColorKeyLow
|
|
#define gdwSrcColorKeyHigh ppdev->DriverData.gdwSrcColorKeyHigh
|
|
#define gdwDestColorKeyOwnerVW ppdev->DriverData.gdwDestColorKeyOwnerVW // DstColorKey owner (NULL or FLG_VWX)
|
|
#define gdwSrcColorKeyOwnerVW ppdev->DriverData.gdwSrcColorKeyOwnerVW // SrcColorKey owner (NULL or FLG_VWX)
|
|
|
|
#define giOvlyCnt ppdev->DriverData.giOvlyCnt
|
|
#if ENABLE_YUVPLANAR // YUV Planar surfaces cannot exist
|
|
#define giPlanarCnt ppdev->DriverData.giPlanarCnt // with other overlay surfaces
|
|
#define bCLPLLobotomyMode ppdev->DriverData.bCLPLLobotomyMode
|
|
#endif
|
|
//#define gbDoubleClock ppdev->DriverData.gbDoubleClock
|
|
|
|
#if DISABLE_MOST_MODES
|
|
#define bDisableMostModes ppdev->DriverData.bDisableMostModes
|
|
#endif
|
|
|
|
#else // Win95
|
|
|
|
ASSERTFILE("5465over.c");
|
|
|
|
STATIC DIBENGINE *pPDevice;
|
|
STATIC BOOL bUseBWEqn;
|
|
STATIC BOOL bNoOverlayInThisMode;
|
|
|
|
STATIC LPDDRAWI_DDRAWSURFACE_LCL lpHardwareOwner[MAX_VIDEO_WINDOWS];
|
|
STATIC LPDDRAWI_DDRAWSURFACE_LCL lpColorSurfaceVW[MAX_VIDEO_WINDOWS];
|
|
STATIC LPDDRAWI_DDRAWSURFACE_LCL lpSrcColorSurfaceVW[MAX_VIDEO_WINDOWS];
|
|
|
|
STATIC RECTL grOverlaySrc[MAX_VIDEO_WINDOWS];
|
|
STATIC RECTL grOverlayDest[MAX_VIDEO_WINDOWS];
|
|
STATIC DWORD gdwFourccVW[MAX_VIDEO_WINDOWS];
|
|
#if ENABLE_MIRRORING
|
|
STATIC BOOL bIsVWMirrored[MAX_VIDEO_WINDOWS];
|
|
#endif
|
|
|
|
STATIC DWORD gdwAvailVW; // Next available video window
|
|
//STATIC WORD gwZOrder = OVERLAYZ_PRIMARY_ON_TOP; // default primary on top.
|
|
STATIC DWORD gdwColorKey;
|
|
STATIC DWORD gdwSrcColorKeyLow;
|
|
STATIC DWORD gdwSrcColorKeyHigh;
|
|
STATIC DWORD gdwDestColorKeyOwnerVW = 0; // DstColorKey owner (NULL or FLG_VWX)
|
|
STATIC DWORD gdwSrcColorKeyOwnerVW = 0; // SrcColorKey owner (NULL or FLG_VWX)
|
|
|
|
STATIC int giOvlyCnt[MAX_VIDEO_WINDOWS];
|
|
#if ENABLE_YUVPLANAR // YUV Planar surfaces cannot exist
|
|
STATIC int giPlanarCnt = 0; // with other overlay surfaces
|
|
STATIC BOOL bCLPLLobotomyMode;
|
|
#endif
|
|
//STATIC BOOL gbDoubleClock;
|
|
|
|
#if DISABLE_MOST_MODES
|
|
STATIC BOOL bDisableMostModes;
|
|
#endif
|
|
|
|
#endif
|
|
|
|
/***************************************************************************
|
|
* G L O B A L V A R I A B L E S
|
|
****************************************************************************/
|
|
|
|
#ifdef WINNT_VER40
|
|
|
|
// For NT these are in ppdev->DriverData
|
|
#define gsOverlayFlip ppdev->DriverData.gsOverlayFlip
|
|
#define gsProgRegs ppdev->DriverData.gsProgRegs
|
|
#define gvidConfig ppdev->DriverData.gvidConfig
|
|
#define gwNormalDTTR ppdev->DriverData.gwNormalDTTR
|
|
#define dwNumVideoWindows ppdev->DriverData.dwNumVideoWindows
|
|
|
|
#if ENABLE_YUVPLANAR
|
|
#define bEnableCLPL ppdev->DriverData.bEnableCLPL
|
|
#endif
|
|
|
|
#else
|
|
|
|
OVERLAYFLIPRECORD gsOverlayFlip;
|
|
|
|
PROGREGS gsProgRegs = {0}; //Make them global so VPE can use the same ones
|
|
VIDCONFIG gvidConfig = {0};
|
|
WORD gwNormalDTTR;
|
|
DWORD dwNumVideoWindows;
|
|
|
|
#if ENABLE_YUVPLANAR
|
|
BOOL bEnableCLPL;
|
|
#endif
|
|
|
|
#endif
|
|
|
|
/***************************************************************************
|
|
* S T A T I C F U N C T I O N P R O T O T Y P E S
|
|
****************************************************************************/
|
|
|
|
#ifdef WINNT_VER40
|
|
|
|
static void GetUserSettings ( PDEV * );
|
|
|
|
STATIC HRESULT IsFormatValid ( PDEV*, DWORD, DWORD );
|
|
STATIC HRESULT CreateOverlaySurface ( PDEV*, PDD_SURFACE_LOCAL, DWORD );
|
|
STATIC VOID DestroyOverlaySurface( PDEV*, PDD_DESTROYSURFACEDATA );
|
|
STATIC DWORD FlipOverlaySurface ( PDEV*, PDD_FLIPDATA );
|
|
STATIC DWORD LockSurface ( PDEV*, PDD_LOCKDATA );
|
|
STATIC VOID UnlockSurface ( PDEV*, PDD_UNLOCKDATA );
|
|
STATIC VOID SetColorKey ( PDEV*, PDD_SETCOLORKEYDATA );
|
|
STATIC DWORD UpdateSurface ( PDEV*, PDD_UPDATEOVERLAYDATA );
|
|
STATIC DWORD SetPosition ( PDEV*, PDD_SETOVERLAYPOSITIONDATA );
|
|
STATIC DWORD GetOverlayFlipStatus ( PDEV*, FLATPTR, DWORD );
|
|
|
|
STATIC BOOL RegInitVideoVW ( PDEV*, DWORD, PDD_SURFACE_LOCAL );
|
|
STATIC VOID RegMoveVideoVW ( PDEV*, DWORD, PDD_SURFACE_LOCAL );
|
|
|
|
#else
|
|
|
|
static void GetUserSettings ( void );
|
|
|
|
STATIC HRESULT IsFormatValid ( LPGLOBALDATA, DWORD, DWORD );
|
|
STATIC HRESULT CreateSurface ( LPDDRAWI_DDRAWSURFACE_LCL, DWORD,LPGLOBALDATA );
|
|
STATIC VOID DestroySurface ( LPDDHAL_DESTROYSURFACEDATA );
|
|
STATIC DWORD FlipOverlaySurface ( LPDDHAL_FLIPDATA );
|
|
STATIC DWORD LockSurface ( LPDDHAL_LOCKDATA );
|
|
STATIC VOID UnlockSurface ( LPDDHAL_UNLOCKDATA );
|
|
STATIC VOID SetColorKey ( LPDDHAL_SETCOLORKEYDATA);
|
|
STATIC DWORD UpdateSurface ( LPDDHAL_UPDATEOVERLAYDATA );
|
|
STATIC DWORD SetPosition ( LPDDHAL_SETOVERLAYPOSITIONDATA );
|
|
STATIC DWORD GetOverlayFlipStatus (LPGLOBALDATA, FLATPTR, DWORD );
|
|
|
|
STATIC BOOL RegInitVideoVW ( DWORD, LPDDRAWI_DDRAWSURFACE_LCL,LPGLOBALDATA );
|
|
STATIC VOID RegMoveVideoVW ( DWORD, LPDDRAWI_DDRAWSURFACE_LCL,LPGLOBALDATA );
|
|
|
|
#endif
|
|
|
|
/***************************************************************************
|
|
* 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
|
|
****************************************************************************/
|
|
|
|
#if WINNT_VER40
|
|
extern int CurrentVLine (PDEV *);
|
|
extern VOID GetFormatInfo (LPDDPIXELFORMAT, LPDWORD, LPDWORD);
|
|
#endif
|
|
#ifdef USE_OLD_BWEQ
|
|
extern BOOL KillOverlay
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
#endif
|
|
WORD wScreenX,
|
|
UINT uScreenDepth
|
|
); //fix PDR#10381
|
|
#endif
|
|
|
|
BOOL ChipIOReadBWRegs
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
#else
|
|
LPGLOBALDATA lpDDHALData,
|
|
#endif
|
|
LPBWREGS pBWRegs
|
|
);
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: MakeVideoWindowFlag
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
****************************************************************************/
|
|
|
|
static INLINE DWORD
|
|
MakeVideoWindowFlag ( DWORD dwVWIndex )
|
|
{
|
|
ASSERT(dwNumVideoWindows > dwVWIndex);
|
|
return ((1 << dwVWIndex) << FLG_VW_SHIFT);
|
|
}
|
|
|
|
#if 0
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: GetDoubleClockStatus
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
****************************************************************************/
|
|
|
|
static INLINE DWORD
|
|
GetDoubleClockStatus ( VOID )
|
|
{
|
|
#pragma message("GetDoubleClockStatus not implemented!")
|
|
return FALSE;
|
|
}
|
|
#endif
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: GetDDHALContext
|
|
*
|
|
* DESCRIPTION:
|
|
* Get shared data structure (SDATA) pointer
|
|
****************************************************************************/
|
|
#ifndef WINNT_VER40
|
|
INLINE LPGLOBALDATA GetDDHALContext( LPDDRAWI_DIRECTDRAW_GBL lpGb )
|
|
{
|
|
#if (DDRAW_COMPAT >= 50)
|
|
if(lpGb->dwReserved3) //the SDATA pointer is passed by dwReserved3
|
|
//for DX50
|
|
return (LPGLOBALDATA)lpGb->dwReserved3;
|
|
else
|
|
#endif
|
|
return pDriverData;
|
|
}
|
|
#endif
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: IsHardwareInUseVW
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
****************************************************************************/
|
|
|
|
static INLINE BOOL IsVWHardwareInUse
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
#else
|
|
LPGLOBALDATA lpDDHALData,
|
|
#endif
|
|
DWORD dwVWIndex
|
|
)
|
|
{
|
|
ASSERT(dwNumVideoWindows > dwVWIndex);
|
|
if (VW_VWE & ((PVGAR)lpDDHALData->RegsAddress)->VideoWindow[dwVWIndex].grVW_CONTROL0)
|
|
return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: WaitForArmToClear
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
****************************************************************************/
|
|
|
|
static INLINE VOID WaitForVWArmToClear
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
#else
|
|
LPGLOBALDATA lpDDHALData,
|
|
#endif
|
|
DWORD dwVWIndex
|
|
)
|
|
{
|
|
// wait for previous register writes to post
|
|
// the hardware clears the ARM bit at that time
|
|
ASSERT(dwNumVideoWindows > dwVWIndex);
|
|
while (((PVGAR)lpDDHALData->RegsAddress)->VideoWindow[dwVWIndex].grVW_CONTROL0 & VW_ARM)
|
|
;
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: EnableOverlay
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
****************************************************************************/
|
|
|
|
static INLINE VOID EnableOverlay
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
#else
|
|
LPGLOBALDATA lpDDHALData,
|
|
#endif
|
|
DWORD dwVWIndex
|
|
)
|
|
{
|
|
ASSERT(dwNumVideoWindows > dwVWIndex);
|
|
#ifdef WINNT_VER40
|
|
WaitForVWArmToClear(ppdev,dwVWIndex);
|
|
#else
|
|
WaitForVWArmToClear(lpDDHALData,dwVWIndex);
|
|
#endif
|
|
((PVGAR)lpDDHALData->RegsAddress)->VideoWindow[dwVWIndex].grVW_CONTROL0 |= (VW_VWE | VW_ARM);
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: DisableOverlay
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
****************************************************************************/
|
|
|
|
static INLINE VOID DisableOverlay
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
#else
|
|
LPGLOBALDATA lpDDHALData,
|
|
#endif
|
|
DWORD dwVWIndex
|
|
)
|
|
{
|
|
ASSERT(dwNumVideoWindows > dwVWIndex);
|
|
#ifdef WINNT_VER40
|
|
WaitForVWArmToClear(ppdev,dwVWIndex);
|
|
#else
|
|
WaitForVWArmToClear(lpDDHALData,dwVWIndex);
|
|
#endif
|
|
((PVGAR)lpDDHALData->RegsAddress)->VideoWindow[dwVWIndex].grVW_CONTROL0 &=
|
|
~(VW_FIFO_THRSH_EN | VW_VWE);
|
|
((PVGAR)lpDDHALData->RegsAddress)->VideoWindow[dwVWIndex].grVW_CONTROL0 |= VW_ARM;
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: Set5465FlipDuration
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
****************************************************************************/
|
|
|
|
VOID Set5465FlipDuration
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
#endif
|
|
DWORD dwFlipDuration
|
|
)
|
|
{
|
|
gsOverlayFlip.dwFlipDuration = dwFlipDuration;
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: GetUserSettings
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
****************************************************************************/
|
|
|
|
VOID GetUserSettings
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev
|
|
#else
|
|
VOID
|
|
#endif
|
|
)
|
|
{
|
|
#ifdef WINNT_VER40
|
|
|
|
#pragma message("GetUserSettings: Where are laguna settings stored in the NT registry?")
|
|
bUseBWEqn = TRUE;
|
|
|
|
#if ENABLE_YUVPLANAR
|
|
bEnableCLPL = TRUE;
|
|
bCLPLLobotomyMode = TRUE;
|
|
#endif
|
|
|
|
#else // else Win95
|
|
static const USERSETTINGS UserSettings[] =
|
|
{
|
|
{ &bUseBWEqn, "OverlayBW", TRUE },
|
|
#if ENABLE_YUVPLANAR
|
|
{ &bEnableCLPL, "OverlayCLPL", TRUE },
|
|
{ &bCLPLLobotomyMode, "OverlayCLPLLobotomyMode", TRUE },
|
|
#endif
|
|
#if DISABLE_MOST_MODES
|
|
{ &bDisableMostModes, "OverlayBWHack", TRUE },
|
|
#endif
|
|
};
|
|
|
|
const USERSETTINGS *pUserSetting;
|
|
|
|
|
|
for (pUserSetting = &UserSettings[0];
|
|
pUserSetting < &UserSettings[sizeof(UserSettings)/sizeof(UserSettings[0])];
|
|
pUserSetting++)
|
|
{
|
|
*(pUserSetting->pVar) = pUserSetting->defaultVal;
|
|
GetBooleanSetting(pUserSetting->pRegKey,
|
|
pUserSetting->pVar,
|
|
LOCATION_OF_3D_PERFORMANCE);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: Init5465Overlay
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
****************************************************************************/
|
|
|
|
VOID Init5465Overlay
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
DWORD dwChipType,
|
|
PDD_HALINFO pDDHALInfo,
|
|
LPOVERLAYTABLE pOverlayTable
|
|
#else
|
|
DWORD dwChipType,
|
|
LPDDHALINFO pDDHALInfo,
|
|
LPOVERLAYTABLE pOverlayTable,
|
|
LPGLOBALDATA lpDDHALData
|
|
#endif
|
|
)
|
|
{
|
|
DWORD dwNumFourCCs;
|
|
|
|
|
|
#ifdef WINNT_VER40
|
|
GetUserSettings(ppdev);
|
|
#else
|
|
GetUserSettings();
|
|
#endif
|
|
|
|
if (! bUseBWEqn)
|
|
gsProgRegs.VW0_FIFO_THRSH = 8;
|
|
|
|
// We should check the capabilities register on the chip
|
|
// but it's busted
|
|
#ifdef WINNT_VER40
|
|
if (CL_GD5465 == dwChipType)
|
|
#else
|
|
if (GD5465_PCI_DEVICE_ID == dwChipType)
|
|
#endif
|
|
dwNumVideoWindows = 1;
|
|
else
|
|
{
|
|
#if 1
|
|
dwNumVideoWindows = 1;
|
|
#else
|
|
int i;
|
|
PVGAR pREG = (PVGAR)lpDDHALData->RegsAddress;
|
|
|
|
dwNumVideoWindows = 0;
|
|
for (i = 0; i < MAX_VIDEO_WINDOWS; i++)
|
|
{
|
|
if (VWCAP_VW_PRESENT & pREG->VideoWindow[i].grVW_CAP0)
|
|
dwNumVideoWindows++;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
#ifdef WINNT_VER40
|
|
if (NULL != pDDHALInfo)
|
|
#endif
|
|
{
|
|
pDDHALInfo->ddCaps.dwMaxVisibleOverlays = dwNumVideoWindows;
|
|
pDDHALInfo->ddCaps.dwCurrVisibleOverlays = 0;
|
|
|
|
#ifndef WINNT_VER40
|
|
pPDevice = (DIBENGINE *)lpDDHALData->lpPDevice;
|
|
#endif
|
|
|
|
// Fill in the caps
|
|
pDDHALInfo->ddCaps.dwCaps |= DDCAPS_OVERLAY
|
|
| DDCAPS_OVERLAYFOURCC
|
|
| DDCAPS_OVERLAYSTRETCH
|
|
| DDCAPS_ALIGNSTRIDE
|
|
| DDCAPS_OVERLAYCANTCLIP
|
|
;
|
|
|
|
pDDHALInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_OVERLAY
|
|
;
|
|
|
|
pDDHALInfo->ddCaps.dwFXCaps |= DDFXCAPS_OVERLAYARITHSTRETCHY
|
|
| DDFXCAPS_OVERLAYSTRETCHX
|
|
| DDFXCAPS_OVERLAYSTRETCHY
|
|
| DDFXCAPS_OVERLAYSHRINKX
|
|
| DDFXCAPS_OVERLAYSHRINKY
|
|
#if ENABLE_MIRRORING
|
|
| DDFXCAPS_OVERLAYMIRRORLEFTRIGHT
|
|
#endif
|
|
;
|
|
}
|
|
|
|
/* FOURCCs supported */
|
|
#if (MAX_FOURCCS < 3)
|
|
#error dwFourCC array too small
|
|
#endif
|
|
dwNumFourCCs = 0;
|
|
lpDDHALData->dwFourCC[dwNumFourCCs++] = FOURCC_UYVY;
|
|
#if ENABLE_YUY2
|
|
lpDDHALData->dwFourCC[dwNumFourCCs++] = FOURCC_YUY2;
|
|
#endif
|
|
#if ENABLE_YUVPLANAR
|
|
// add CLPL fourcc if registry key set to "on"
|
|
if (bEnableCLPL)
|
|
lpDDHALData->dwFourCC[dwNumFourCCs++] = FOURCC_YUVPLANAR;
|
|
#endif
|
|
|
|
#ifdef WINNT_VER40
|
|
if (NULL != pDDHALInfo)
|
|
#endif
|
|
{
|
|
pDDHALInfo->ddCaps.dwNumFourCCCodes = dwNumFourCCs;
|
|
|
|
// say we can handle byte alignment and any byte width
|
|
pDDHALInfo->ddCaps.dwAlignBoundarySrc = 1; // src rect x byte alignment
|
|
pDDHALInfo->ddCaps.dwAlignSizeSrc = 1; // src rect x byte size
|
|
pDDHALInfo->ddCaps.dwAlignBoundaryDest = 1; // dst rect x byte alignment
|
|
pDDHALInfo->ddCaps.dwAlignSizeDest = 1; // dst rect x byte size
|
|
// stride alignment
|
|
#ifdef WINNT_VER40
|
|
pDDHALInfo->ddCaps.dwAlignStrideAlign = ppdev->cxMemory;
|
|
#else
|
|
pDDHALInfo->ddCaps.dwAlignStrideAlign = pPDevice->deWidthBytes;
|
|
#endif
|
|
|
|
pDDHALInfo->ddCaps.dwMinOverlayStretch = 500; // min stretch is 0.5:1
|
|
pDDHALInfo->ddCaps.dwMaxOverlayStretch = 8000; // max stretch is 8:1
|
|
#ifdef WINNT_VER40
|
|
ppdev->DriverData.dwMinOverlayStretch = 500;
|
|
ppdev->DriverData.dwMaxOverlayStretch = 8000;
|
|
#endif
|
|
pDDHALInfo->vmiData.dwOverlayAlign = 8 * 8; // qword alignment in bits
|
|
}
|
|
|
|
// Initialize OverlayTable function pointers
|
|
pOverlayTable->pfnCanCreateSurface = IsFormatValid;
|
|
#ifdef WINNT_VER40
|
|
pOverlayTable->pfnCreateSurface = CreateOverlaySurface;
|
|
pOverlayTable->pfnDestroySurface = DestroyOverlaySurface;
|
|
#else
|
|
pOverlayTable->pfnCreateSurface = CreateSurface;
|
|
pOverlayTable->pfnDestroySurface = DestroySurface;
|
|
#endif
|
|
pOverlayTable->pfnLock = LockSurface;
|
|
pOverlayTable->pfnUnlock = UnlockSurface;
|
|
pOverlayTable->pfnSetColorKey = SetColorKey;
|
|
pOverlayTable->pfnFlip = FlipOverlaySurface;
|
|
pOverlayTable->pfnUpdateOverlay = UpdateSurface;
|
|
pOverlayTable->pfnSetOverlayPos = SetPosition;
|
|
pOverlayTable->pfnGetFlipStatus = GetOverlayFlipStatus;
|
|
|
|
// do mode specific initialization
|
|
#ifdef WINNT_VER40
|
|
if (NULL != pDDHALInfo)
|
|
Init5465Info(ppdev, pDDHALInfo);
|
|
#else
|
|
Init5465Info(pDDHALInfo, lpDDHALData);
|
|
#endif
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: Init5465Info
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
****************************************************************************/
|
|
|
|
VOID Init5465Info
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
PDD_HALINFO pDDHALInfo
|
|
#else
|
|
LPDDHALINFO pDDHALInfo,
|
|
LPGLOBALDATA lpDDHALData
|
|
#endif
|
|
)
|
|
{
|
|
// assume we can use overlay in this mode
|
|
bNoOverlayInThisMode = FALSE;
|
|
|
|
if (! bUseBWEqn)
|
|
gsProgRegs.DispThrsTiming =
|
|
((PVGAR)lpDDHALData->RegsAddress)->grDisplay_Threshold_and_Tiling & 0x3F;
|
|
|
|
// Are we double clocked?
|
|
// gbDoubleClock = GetDoubleClockStatus();
|
|
|
|
// re-init these on mode change, we might tweak them below
|
|
pDDHALInfo->ddCaps.dwAlignBoundaryDest = 1;
|
|
pDDHALInfo->ddCaps.dwAlignSizeDest = 1;
|
|
pDDHALInfo->ddCaps.dwMinOverlayStretch = 500;
|
|
pDDHALInfo->ddCaps.dwMaxOverlayStretch = 8000;
|
|
#ifdef WINNT_VER40
|
|
ppdev->DriverData.dwMinOverlayStretch = 500;
|
|
ppdev->DriverData.dwMaxOverlayStretch = 8000;
|
|
#endif
|
|
|
|
// tell ddraw we can do colorkeying
|
|
// we might undo this below
|
|
pDDHALInfo->ddCaps.dwCKeyCaps |= DDCKEYCAPS_DESTOVERLAY
|
|
| DDCKEYCAPS_DESTOVERLAYYUV
|
|
| DDCKEYCAPS_DESTOVERLAYONEACTIVE
|
|
| DDCKEYCAPS_SRCOVERLAY
|
|
| DDCKEYCAPS_SRCOVERLAYYUV
|
|
| DDCKEYCAPS_SRCOVERLAYONEACTIVE
|
|
| DDCKEYCAPS_SRCOVERLAYCLRSPACE
|
|
| DDCKEYCAPS_SRCOVERLAYCLRSPACEYUV
|
|
;
|
|
if (bUseBWEqn)
|
|
{
|
|
DWORD dwZoom;
|
|
VIDCONFIG vidConfig;
|
|
BWREGS bwregs;
|
|
|
|
|
|
// initialize vidConfig
|
|
memset(&vidConfig, 0, sizeof(vidConfig));
|
|
|
|
vidConfig.uSrcDepth = 16;
|
|
#ifdef WINNT_VER40
|
|
vidConfig.uDispDepth = ppdev->ulBitCount;
|
|
vidConfig.uGfxDepth = ppdev->ulBitCount;
|
|
#else
|
|
vidConfig.uDispDepth = pPDevice->deBitsPixel;
|
|
vidConfig.uGfxDepth = pPDevice->deBitsPixel;
|
|
#endif
|
|
vidConfig.dwFlags = VCFLG_COLORKEY | VCFLG_DISP;
|
|
|
|
vidConfig.sizSrc.cx = SRC_WIDTH;
|
|
vidConfig.sizSrc.cy = SRC_HEIGHT;
|
|
if(gvidConfig.dwFlags & VCFLG_CAP)
|
|
{
|
|
//if video port is on, includes it for BWE
|
|
vidConfig.dwFlags |= VCFLG_CAP;
|
|
vidConfig.sizXfer = gvidConfig.sizXfer;
|
|
vidConfig.sizCap = gvidConfig.sizCap;
|
|
vidConfig.sizXfer = gvidConfig.sizXfer;
|
|
vidConfig.dwXferRate = gvidConfig.dwXferRate;
|
|
vidConfig.uXferDepth = gvidConfig.uXferDepth;
|
|
vidConfig.uCapDepth = gvidConfig.uCapDepth;
|
|
vidConfig.uSrcDepth = gvidConfig.uSrcDepth;
|
|
}
|
|
#ifdef WINNT_VER40
|
|
ChipIOReadBWRegs(ppdev, &bwregs);
|
|
#else
|
|
ChipIOReadBWRegs(lpDDHALData, &bwregs);
|
|
#endif
|
|
#ifdef USE_OLD_BWEQ
|
|
//Kill overlay for some modes
|
|
#ifdef WINNT_VER40
|
|
if(KillOverlay(ppdev, (WORD)ppdev->cxScreen, (UINT)ppdev->ulBitCount))
|
|
#else
|
|
if(KillOverlay( pPDevice->deWidth,pPDevice->deBitsPixel))
|
|
#endif
|
|
bNoOverlayInThisMode = TRUE;
|
|
else
|
|
#endif
|
|
{
|
|
// stupid linear search for min & max zoom factors
|
|
|
|
// Check bandwidth to find the maximum zoom factor of 16 bit data
|
|
// with colorkey
|
|
dwZoom = MAX_ZOOM;
|
|
do
|
|
{
|
|
vidConfig.sizDisp.cx = (SRC_WIDTH * dwZoom) / 1000;
|
|
vidConfig.sizDisp.cy = (SRC_HEIGHT * dwZoom) / 1000;
|
|
|
|
if (ChipIsEnoughBandwidth(&gsProgRegs, &vidConfig, &bwregs))
|
|
{
|
|
#ifndef WINNT_VER40
|
|
DBG_MESSAGE(("Maximum zoom factor: %d", dwZoom));
|
|
#endif
|
|
|
|
pDDHALInfo->ddCaps.dwMaxOverlayStretch = dwZoom;
|
|
|
|
#ifdef WINNT_VER40
|
|
ppdev->DriverData.dwMaxOverlayStretch = dwZoom;
|
|
#endif
|
|
break;
|
|
}
|
|
dwZoom -= ZOOM_STEP;
|
|
} while (dwZoom > 4000);
|
|
if (dwZoom != pDDHALInfo->ddCaps.dwMaxOverlayStretch)
|
|
bNoOverlayInThisMode = TRUE;
|
|
|
|
// Check bandwidth to find the minimum zoom factor of 16 bit data
|
|
// with colorkey
|
|
dwZoom = MIN_ZOOM;
|
|
#ifdef USE_OLD_BWEQ
|
|
// disable overlay shrink in 24bpp modes
|
|
#ifdef WINNT_VER40
|
|
if (24 == ppdev->ulBitCount)
|
|
#else
|
|
if (24 == pPDevice->deBitsPixel)
|
|
#endif
|
|
dwZoom = 1000;
|
|
#endif
|
|
do
|
|
{
|
|
vidConfig.sizDisp.cx = (SRC_WIDTH * dwZoom) / 1000;
|
|
vidConfig.sizDisp.cy = (SRC_HEIGHT * dwZoom) / 1000;
|
|
|
|
if (ChipIsEnoughBandwidth(&gsProgRegs, &vidConfig, &bwregs))
|
|
{
|
|
#ifndef WINNT_VER40
|
|
DBG_MESSAGE(("Minimum zoom factor: %d", dwZoom));
|
|
#endif
|
|
|
|
pDDHALInfo->ddCaps.dwMinOverlayStretch = dwZoom;
|
|
|
|
#ifdef WINNT_VER40
|
|
ppdev->DriverData.dwMinOverlayStretch = dwZoom;
|
|
#endif
|
|
break;
|
|
}
|
|
dwZoom += ZOOM_STEP;
|
|
} while (dwZoom < 4000);
|
|
if (dwZoom != pDDHALInfo->ddCaps.dwMinOverlayStretch)
|
|
bNoOverlayInThisMode = TRUE;
|
|
}
|
|
// I'll leave this code in here but so far I have only seen that if
|
|
// we don't have enough bandwidth to use overlay with colorkey then
|
|
// we don't have enough bandwidth period
|
|
|
|
// try to see if there's enough bandwidth to use overlay without colorkey
|
|
if (TRUE == bNoOverlayInThisMode)
|
|
{
|
|
// reset this in case we find enough bandwidth to use overlay
|
|
// without colorkey
|
|
bNoOverlayInThisMode = FALSE;
|
|
|
|
// retry without colorkey available
|
|
// tell ddraw we don't do colorkeying
|
|
pDDHALInfo->ddCaps.dwCKeyCaps &= ~(DDCKEYCAPS_DESTOVERLAY
|
|
| DDCKEYCAPS_DESTOVERLAYYUV
|
|
| DDCKEYCAPS_DESTOVERLAYONEACTIVE
|
|
| DDCKEYCAPS_SRCOVERLAY
|
|
| DDCKEYCAPS_SRCOVERLAYYUV
|
|
| DDCKEYCAPS_SRCOVERLAYONEACTIVE
|
|
| DDCKEYCAPS_SRCOVERLAYCLRSPACE
|
|
| DDCKEYCAPS_SRCOVERLAYCLRSPACEYUV)
|
|
;
|
|
|
|
#ifdef USE_OLD_BWEQ
|
|
#ifdef WINNT_VER40
|
|
if(KillOverlay(ppdev, (WORD)ppdev->cxScreen, (UINT)ppdev->ulBitCount))
|
|
#else
|
|
if(KillOverlay( pPDevice->deWidth,pPDevice->deBitsPixel))
|
|
#endif
|
|
bNoOverlayInThisMode = TRUE;
|
|
else
|
|
#endif
|
|
{
|
|
// Check bandwidth to find the maximum zoom factor of 16 bit data
|
|
dwZoom = MAX_ZOOM;
|
|
do
|
|
{
|
|
vidConfig.sizDisp.cx = (SRC_WIDTH * dwZoom) / 1000;
|
|
vidConfig.sizDisp.cy = (SRC_HEIGHT * dwZoom) / 1000;
|
|
|
|
if (ChipIsEnoughBandwidth(&gsProgRegs, &vidConfig, &bwregs))
|
|
{
|
|
#ifndef WINNT_VER40
|
|
DBG_MESSAGE(("Maximum zoom factor: %d", dwZoom));
|
|
#endif
|
|
|
|
pDDHALInfo->ddCaps.dwMaxOverlayStretch = dwZoom;
|
|
|
|
#ifdef WINNT_VER40
|
|
ppdev->DriverData.dwMaxOverlayStretch = dwZoom;
|
|
#endif
|
|
break;
|
|
}
|
|
dwZoom -= ZOOM_STEP;
|
|
} while (dwZoom > 4000);
|
|
if (dwZoom != pDDHALInfo->ddCaps.dwMaxOverlayStretch)
|
|
bNoOverlayInThisMode = TRUE;
|
|
|
|
// Check bandwidth to find the minimum zoom factor of 16 bit data
|
|
dwZoom = MIN_ZOOM;
|
|
// disable overlay shrink in 24bpp modes
|
|
#ifdef WINNT_VER40
|
|
if (24 == ppdev->ulBitCount)
|
|
#else
|
|
if (24 == pPDevice->deBitsPixel)
|
|
#endif
|
|
dwZoom = 1000;
|
|
do
|
|
{
|
|
vidConfig.sizDisp.cx = (SRC_WIDTH * dwZoom) / 1000;
|
|
vidConfig.sizDisp.cy = (SRC_HEIGHT * dwZoom) / 1000;
|
|
|
|
if (ChipIsEnoughBandwidth(&gsProgRegs, &vidConfig, &bwregs))
|
|
{
|
|
#ifndef WINNT_VER40
|
|
DBG_MESSAGE(("Minimum zoom factor: %d", dwZoom));
|
|
#endif
|
|
|
|
pDDHALInfo->ddCaps.dwMinOverlayStretch = dwZoom;
|
|
|
|
#ifdef WINNT_VER40
|
|
ppdev->DriverData.dwMinOverlayStretch = dwZoom;
|
|
#endif
|
|
break;
|
|
}
|
|
dwZoom += ZOOM_STEP;
|
|
} while (dwZoom < 4000);
|
|
if (dwZoom != pDDHALInfo->ddCaps.dwMinOverlayStretch)
|
|
bNoOverlayInThisMode = TRUE;
|
|
}
|
|
#ifdef DEBUG
|
|
if (bNoOverlayInThisMode)
|
|
{
|
|
ERRORLOG((" overlay disabled in %ldx%ldx%ld",
|
|
(DWORD)pPDevice->deWidth,
|
|
(DWORD)pPDevice->deHeight,
|
|
(DWORD)pPDevice->deBitsPixel));
|
|
}
|
|
else
|
|
{
|
|
ERRORLOG((" overlay colorkey not supported in %ldx%ldx%ld",
|
|
(DWORD)pPDevice->deWidth,
|
|
(DWORD)pPDevice->deHeight,
|
|
(DWORD)pPDevice->deBitsPixel));
|
|
}
|
|
#endif
|
|
}
|
|
// see if we're in interlaced mode, if so disable overlay
|
|
if (1 & ((PVGAR)lpDDHALData->RegsAddress)->grCR1A)
|
|
bNoOverlayInThisMode = TRUE;
|
|
|
|
#if DISABLE_MOST_MODES
|
|
if (bDisableMostModes)
|
|
{
|
|
PVGAR pREG = (PVGAR)lpDDHALData->RegsAddress;
|
|
|
|
// disable overlay support for 1024x768 and above
|
|
if ((1024 <= pPDevice->deWidth) && ( 768 <= pPDevice->deHeight))
|
|
bNoOverlayInThisMode = TRUE;
|
|
// disable overlay support for 640x480x32@85Hz
|
|
if ((640 == pPDevice->deWidth) &&
|
|
(480 == pPDevice->deHeight) &&
|
|
( 32 == pPDevice->deBitsPixel) &&
|
|
(0x33 == pREG->grSRE) &&
|
|
(0x7E == pREG->grSR1E))
|
|
bNoOverlayInThisMode = TRUE;
|
|
// disable overlay support for 800x600x32@85Hz
|
|
if ((800 == pPDevice->deWidth) &&
|
|
(600 == pPDevice->deHeight) &&
|
|
( 32 == pPDevice->deBitsPixel) &&
|
|
(0x1C == pREG->grSRE) &&
|
|
(0x37 == pREG->grSR1E))
|
|
bNoOverlayInThisMode = TRUE;
|
|
}
|
|
#endif
|
|
|
|
#if 0
|
|
// TDDRAW.EXE error return from UpdateOverlay in to following cases
|
|
if (ppdev->ulBitCount == 8 && ppdev->cxScreen == 1280)
|
|
{
|
|
if ( (ppdev->cyScreen == 1024 && ppdev->ulFreq >= 72) ||
|
|
(ppdev->cyScreen == 960 && ppdev->ulFreq >= 85) )
|
|
bNoOverlayInThisMode = TRUE;
|
|
}
|
|
if ( ppdev->cxScreen == 640 &&
|
|
ppdev->cyScreen == 350 )
|
|
bNoOverlayInThisMode = TRUE;
|
|
#endif// 0
|
|
|
|
// if no overlay in this mode set min & max overlay stretch to 0
|
|
if (TRUE == bNoOverlayInThisMode)
|
|
{
|
|
pDDHALInfo->ddCaps.dwMinOverlayStretch = 0;
|
|
pDDHALInfo->ddCaps.dwMaxOverlayStretch = 0;
|
|
#ifdef WINNT_VER40
|
|
ppdev->DriverData.dwMinOverlayStretch = 0;
|
|
ppdev->DriverData.dwMaxOverlayStretch = 0;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
#if HWBUG_24BPP_DST_COLORKEY
|
|
#ifdef WINNT_VER40
|
|
if (24 == ppdev->ulBitCount)
|
|
#else
|
|
if (24 == pPDevice->deBitsPixel)
|
|
#endif
|
|
{
|
|
// disable destination colorkey support at 24bpp
|
|
// the hardware appears to be busted
|
|
pDDHALInfo->ddCaps.dwCKeyCaps &= ~( DDCKEYCAPS_DESTOVERLAY
|
|
| DDCKEYCAPS_DESTOVERLAYYUV
|
|
| DDCKEYCAPS_DESTOVERLAYONEACTIVE);
|
|
}
|
|
#endif
|
|
|
|
#if 0
|
|
// When double clocking (i.e. 1280x1024), the minimum
|
|
// zoom is 2X.
|
|
if ((gbDoubleClock) && (pDDHALInfo->ddCaps.dwMinOverlayStretch < 2000))
|
|
{
|
|
pDDHALInfo->ddCaps.dwMinOverlayStretch = 2000;
|
|
}
|
|
|
|
// don't use overlay in the 1X case.
|
|
if (pDDHALInfo->ddCaps.dwMinOverlayStretch < 1500)
|
|
{
|
|
pDDHALInfo->ddCaps.dwMinOverlayStretch = 1500;
|
|
}
|
|
|
|
// Specify destination requirements.
|
|
if ((BITSPERPIXEL == 24) || gbDoubleClock)
|
|
{
|
|
pDDHALInfo->ddCaps.dwCaps |= DDCAPS_ALIGNBOUNDARYDEST
|
|
| DDCAPS_ALIGNSIZEDEST
|
|
;
|
|
pDDHALInfo->ddCaps.dwAlignBoundaryDest = 4;
|
|
pDDHALInfo->ddCaps.dwAlignSizeDest = 4;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: IsFormatValid
|
|
*
|
|
* DESCRIPTION: This function verifies that the overlay hardware can
|
|
* support the specified format.
|
|
*
|
|
****************************************************************************/
|
|
|
|
STATIC HRESULT IsFormatValid
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
#else
|
|
LPGLOBALDATA lpDDHALData,
|
|
#endif
|
|
DWORD dwFourcc,
|
|
DWORD dwBitCount
|
|
)
|
|
{
|
|
DWORD i;
|
|
|
|
|
|
#ifndef WINNT_VER40
|
|
DBG_MESSAGE(("IsFormatValid (dwFourcc = 0x%08lX, dwBitCount = 0x%08lX)",
|
|
dwFourcc, dwBitCount));
|
|
#endif
|
|
|
|
// see if we're in interlaced mode
|
|
// if so then don't allow overlay surface to be created
|
|
// also if there isn't enough bandwidth then fail all
|
|
// overlay surface CanCreate requests
|
|
if (bNoOverlayInThisMode || (1 & ((PVGAR)lpDDHALData->RegsAddress)->grCR1A))
|
|
return DDERR_CURRENTLYNOTAVAIL;
|
|
|
|
for (i = 0; i < dwNumVideoWindows; i++)
|
|
{
|
|
// see if ddraw thinks the video window is available
|
|
// and make sure VPM isn't using it
|
|
if ((0 == giOvlyCnt[i]) &&
|
|
#ifdef WINNT_VER40
|
|
(! IsVWHardwareInUse(ppdev,i))
|
|
#else
|
|
(! IsVWHardwareInUse(lpDDHALData,i))
|
|
#endif
|
|
)
|
|
{
|
|
#ifndef WINNT_VER40
|
|
DBG_MESSAGE(("Video Window %d available", i));
|
|
#endif
|
|
|
|
// I'll say YUCK again!
|
|
// I hate this, what if VPM sneaks in between a CanCreateSurface
|
|
// call and a CreateSurface call and grabs this video window
|
|
// Guess we'll just say the creation succeeded but then fail all use
|
|
// of the video window
|
|
gdwAvailVW = MakeVideoWindowFlag(i);
|
|
break;
|
|
}
|
|
}
|
|
if (dwNumVideoWindows == i)
|
|
{
|
|
DBG_MESSAGE(("All video windows in use, returning FALSE"));
|
|
return DDERR_CURRENTLYNOTAVAIL;
|
|
}
|
|
|
|
// only support 5:5:5, 5:6:5 and UYVY overlay surfaces
|
|
if ( ((dwFourcc != BI_RGB) || (dwBitCount != 16))
|
|
#if ENABLE_SD_RGB32
|
|
&& ((dwFourcc != BI_RGB) || (dwBitCount != 32))
|
|
#endif
|
|
&& (dwFourcc != BI_BITFIELDS)
|
|
&& (dwFourcc != FOURCC_UYVY)
|
|
#if ENABLE_YUY2
|
|
&& (dwFourcc != FOURCC_YUY2)
|
|
#endif
|
|
#if ENABLE_YUVPLANAR
|
|
&& (dwFourcc != FOURCC_YUVPLANAR)
|
|
#endif
|
|
)
|
|
{
|
|
#ifndef WINNT_VER40
|
|
DBG_MESSAGE(("IsFormatValid5465: returning FALSE, FourCC = %08lX", dwFourcc));
|
|
#endif
|
|
|
|
return DDERR_INVALIDPIXELFORMAT;
|
|
}
|
|
|
|
#ifndef WINNT_VER40
|
|
DBG_MESSAGE(("IsFormatValid5465: returning TRUE, FourCC = %08lX", dwFourcc));
|
|
#endif
|
|
|
|
return DD_OK;
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: CreateSurface
|
|
*
|
|
* DESCRIPTION: This function sets various flags depending on what
|
|
* is happening.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef WINNT_VER40
|
|
STATIC HRESULT CreateOverlaySurface(
|
|
#else
|
|
STATIC HRESULT CreateSurface(
|
|
#endif
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
PDD_SURFACE_LOCAL lpSurface,
|
|
DWORD dwFourcc
|
|
#else
|
|
LPDDRAWI_DDRAWSURFACE_LCL lpSurface,
|
|
DWORD dwFourcc,
|
|
LPGLOBALDATA lpDDHALData
|
|
#endif
|
|
)
|
|
{
|
|
LP_SURFACE_DATA lpSurfaceData = GET_SURFACE_DATA_PTR(lpSurface);
|
|
DWORD dwVWIndex;
|
|
|
|
|
|
// For non-RGB surfaces, we must always specify the block size.
|
|
#ifndef WINNT_VER40
|
|
DBG_MESSAGE(("Overlay CreateSurface (lpSurface = %08lX, dwFourcc = %08lX)",
|
|
lpSurface, dwFourcc));
|
|
#endif
|
|
|
|
lpSurfaceData->dwOverlayFlags |= FLG_OVERLAY;
|
|
|
|
#ifdef WINNT_VER40
|
|
if (gdwAvailVW == 0)
|
|
{
|
|
UINT i;
|
|
for (i = 0; i < dwNumVideoWindows; i++)
|
|
{
|
|
// see if ddraw thinks the video window is available
|
|
// and make sure VPM isn't using it
|
|
if ( (giOvlyCnt[i] == 0) && ! IsVWHardwareInUse(ppdev,i) )
|
|
{
|
|
gdwAvailVW = MakeVideoWindowFlag(i);
|
|
break;
|
|
}
|
|
}
|
|
if (i == dwNumVideoWindows)
|
|
{
|
|
DBG_MESSAGE(("All video windows in use, returning FALSE"));
|
|
return DDERR_CURRENTLYNOTAVAIL;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
dwVWIndex = GetVideoWindowIndex(gdwAvailVW);
|
|
ASSERT(dwNumVideoWindows > dwVWIndex);
|
|
lpSurfaceData->dwOverlayFlags |= gdwAvailVW;
|
|
gdwFourccVW[dwVWIndex] = dwFourcc;
|
|
|
|
if ( (dwFourcc == FOURCC_UYVY)
|
|
#if ENABLE_YUY2
|
|
|| (dwFourcc == FOURCC_YUY2)
|
|
#endif
|
|
#if ENABLE_YUVPLANAR
|
|
|| (dwFourcc == FOURCC_YUVPLANAR)
|
|
#endif
|
|
)
|
|
{
|
|
lpSurface->lpGbl->ddpfSurface.dwYUVBitCount = 16;
|
|
lpSurface->lpGbl->ddpfSurface.dwYBitMask = (DWORD) -1;
|
|
lpSurface->lpGbl->ddpfSurface.dwUBitMask = (DWORD) -1;
|
|
lpSurface->lpGbl->ddpfSurface.dwVBitMask = (DWORD) -1;
|
|
|
|
if (dwFourcc == FOURCC_UYVY)
|
|
{
|
|
lpSurfaceData->dwOverlayFlags |= FLG_UYVY;
|
|
}
|
|
#if ENABLE_YUY2
|
|
else if (dwFourcc == FOURCC_YUY2)
|
|
{
|
|
lpSurfaceData->dwOverlayFlags |= FLG_YUY2;
|
|
}
|
|
#endif
|
|
#if ENABLE_YUVPLANAR
|
|
else // if (dwFourcc == FOURCC_YUVPLANAR)
|
|
{
|
|
lpSurfaceData->dwOverlayFlags |= FLG_YUVPLANAR;
|
|
giPlanarCnt++;
|
|
|
|
lpSurface->lpGbl->ddpfSurface.dwYUVBitCount = 12;
|
|
|
|
//allocate a CLPLInfo structure
|
|
lpSurfaceData->lpCLPLData = HEAP_ALLOC(hSharedHeap,
|
|
HEAP_ZERO_MEMORY,
|
|
sizeof(CLPLInfo),
|
|
OWNER_OVERLAY,
|
|
(DWORD)lpSurface);
|
|
if (0 == lpSurfaceData->lpCLPLData)
|
|
{
|
|
return DDERR_OUTOFMEMORY;
|
|
}
|
|
if (bCLPLLobotomyMode)
|
|
{
|
|
LPCLPLSURFACE lpCLPL = lpSurfaceData->lpCLPLData;
|
|
DWORD dwSize;
|
|
|
|
dwSize = (lpSurface->lpGbl->wWidth * lpSurface->lpGbl->wHeight) / 2;
|
|
lpCLPL->fpUSystemSurface = HEAP_ALLOC(hSharedHeap,
|
|
HEAP_ZERO_MEMORY,
|
|
dwSize,
|
|
OWNER_OVERLAY,
|
|
(DWORD)lpSurface);
|
|
if (0 == lpCLPL->fpUSystemSurface)
|
|
{
|
|
HEAP_FREE(hSharedHeap, 0, (LPVOID)lpSurfaceData->lpCLPLData);
|
|
lpSurfaceData->lpCLPLData = NULL;
|
|
return DDERR_OUTOFMEMORY;
|
|
}
|
|
lpCLPL->fpVSystemSurface = (LPVOID)((DWORD)(lpCLPL->fpUSystemSurface) + dwSize / 2);
|
|
|
|
DBG_MESSAGE(("CLPL lobotomy mode addrs: USys=%08lX, VSys=%08lX, size=%08lX",
|
|
lpCLPL->fpUSystemSurface, lpCLPL->fpVSystemSurface, dwSize));
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
if(giOvlyCnt[dwVWIndex] == 0 )
|
|
{
|
|
// save copy of current DTTR value
|
|
#if DDRAW_COMPAT >= 50
|
|
gwNotify |= OVERLAY_ON;
|
|
//if VPE is created this variable is already initialized
|
|
if(!(gwNotify & VPE_ON))
|
|
#endif
|
|
{
|
|
gwNormalDTTR = ((PVGAR)lpDDHALData->RegsAddress)->grDisplay_Threshold_and_Tiling;
|
|
}
|
|
}
|
|
giOvlyCnt[dwVWIndex]++;
|
|
|
|
// CreateSurface32 fills in block size
|
|
return DD_OK;
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: DestroySurface
|
|
*
|
|
* DESCRIPTION: This does misc things when an overlay surface is
|
|
* destroyed.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef WINNT_VER40
|
|
STATIC VOID DestroyOverlaySurface(
|
|
#else
|
|
STATIC VOID DestroySurface(
|
|
#endif
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
PDD_DESTROYSURFACEDATA lpInput
|
|
#else
|
|
LPDDHAL_DESTROYSURFACEDATA lpInput
|
|
#endif
|
|
)
|
|
{
|
|
#ifndef WINNT_VER40
|
|
LPGLOBALDATA lpDDHALData = GetDDHALContext( lpInput->lpDD);
|
|
#endif
|
|
LP_SURFACE_DATA lpSurfaceData;
|
|
PVGAR pREG = (PVGAR)lpDDHALData->RegsAddress;
|
|
DWORD dwVWIndex;
|
|
|
|
#ifndef WINNT_VER40
|
|
DBG_MESSAGE(("Overlay DestroySurface (lpInput = 0x%08lX)", lpInput));
|
|
#endif
|
|
|
|
if (0 == lpInput->lpDDSurface->dwReserved1)
|
|
{
|
|
lpInput->ddRVal = DDERR_NOTAOVERLAYSURFACE;
|
|
return;
|
|
}
|
|
lpSurfaceData = GET_SURFACE_DATA_PTR(lpInput->lpDDSurface);
|
|
|
|
dwVWIndex = GetVideoWindowIndex(lpSurfaceData->dwOverlayFlags);
|
|
ASSERT(dwNumVideoWindows > dwVWIndex);
|
|
|
|
if (lpSurfaceData->dwOverlayFlags & FLG_ENABLED)
|
|
{
|
|
// Turn the video off
|
|
#ifndef WINNT_VER40
|
|
DBG_MESSAGE(("Turning off VW %ld in DestroySurface", dwVWIndex));
|
|
#endif
|
|
|
|
#ifdef WINNT_VER40
|
|
DisableOverlay(ppdev, dwVWIndex);
|
|
#else
|
|
DisableOverlay(lpDDHALData, dwVWIndex);
|
|
#endif
|
|
|
|
lpHardwareOwner[dwVWIndex] = NULL;
|
|
|
|
// clear show bit if panning of desktop enabled
|
|
}
|
|
|
|
#if ENABLE_YUVPLANAR
|
|
if (lpSurfaceData->dwOverlayFlags & FLG_YUVPLANAR)
|
|
{
|
|
if (giPlanarCnt > 0)
|
|
{
|
|
LPCLPLSURFACE lpCLPL = lpSurfaceData->lpCLPLData;
|
|
|
|
giPlanarCnt--;
|
|
if (0 != lpCLPL)
|
|
{
|
|
if ((bCLPLLobotomyMode) && (0 != lpCLPL->fpUSystemSurface))
|
|
HEAP_FREE(hSharedHeap, 0, (LPVOID)lpCLPL->fpUSystemSurface);
|
|
// Free up the memory for the CLPLInfo structure
|
|
HEAP_FREE(hSharedHeap, 0, (LPVOID)lpCLPL);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
if (lpSurfaceData->dwOverlayFlags & FLG_VW_MASK)
|
|
{
|
|
if (giOvlyCnt[dwVWIndex] > 0)
|
|
{
|
|
if (0 == --giOvlyCnt[dwVWIndex])
|
|
{
|
|
// get current DTTR, mask off FIFO threshold
|
|
WORD CurrentDTTR = pREG->grDisplay_Threshold_and_Tiling & 0xFFC0;
|
|
|
|
#if DDRAW_COMPAT >= 50
|
|
gvidConfig.dwFlags &= ~(VCFLG_COLORKEY | VCFLG_CHROMAKEY |
|
|
VCFLG_DISP | VCFLG_420);
|
|
|
|
gwNotify &= ~OVERLAY_ON;
|
|
if(!(gwNotify & VPE_ON))
|
|
#endif
|
|
{
|
|
// Fix PDR 9574: Restore FIFO threshold value when overlay surface
|
|
// is destroyed, do not restore the tile size.
|
|
// If tile size has changed, we are likely in the middle of changing
|
|
// video mode. No need to resotre FIFO in this case.
|
|
if ( CurrentDTTR == (gwNormalDTTR & 0xFFC0) ) { // check tile size
|
|
pREG->grDisplay_Threshold_and_Tiling =
|
|
CurrentDTTR | (gwNormalDTTR & 0x003F); // reset FIFO Threshold
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Clear up the ownership of Dest ColorKey.
|
|
gdwDestColorKeyOwnerVW &= ~(lpSurfaceData->dwOverlayFlags & FLG_VW_MASK);
|
|
|
|
// Clear up the ownership of Src ColorKey.
|
|
gdwSrcColorKeyOwnerVW &= ~(lpSurfaceData->dwOverlayFlags & FLG_VW_MASK);
|
|
|
|
#if 0
|
|
if (lpInput->lpDDSurface->ddsCaps.dwCaps & DDSCAPS_LIVEVIDEO)
|
|
{
|
|
// Disable Video Capture.
|
|
#pragma message("Destroy Surface")
|
|
#pragma message(" Who turned on video capture?")
|
|
#pragma message(" Shouldn't they shut it off?")
|
|
#pragma message(" How do I disable video capture on this fraggin' thing?")
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: FlipOverlaySurface
|
|
*
|
|
* DESCRIPTION: This function is called by DDDRV when it wants to flip the
|
|
* overlay surface.
|
|
*
|
|
****************************************************************************/
|
|
|
|
STATIC DWORD FlipOverlaySurface
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
PDD_FLIPDATA lpFlipData
|
|
#else
|
|
LPDDHAL_FLIPDATA lpFlipData
|
|
#endif
|
|
)
|
|
{
|
|
#ifndef WINNT_VER40
|
|
LPGLOBALDATA lpDDHALData = GetDDHALContext( lpFlipData->lpDD);
|
|
#endif
|
|
DWORD dwOffset,dwOffset2;
|
|
LP_SURFACE_DATA lpSurfaceData;
|
|
DWORD dwFourcc;
|
|
DWORD dwBitCount;
|
|
PVGAR pREG = (PVGAR)lpDDHALData->RegsAddress;
|
|
DWORD dwVWIndex;
|
|
#if DDRAW_COMPAT >= 50
|
|
DWORD dwControl0;
|
|
DWORD dwSrfFlags = FALSE;
|
|
#endif
|
|
DWORD dwSurfBase, dwSurfOffset;
|
|
|
|
|
|
#ifndef WINNT_VER40
|
|
DBG_MESSAGE(("FlipOverlaySurface (lpFlipData = 0x%08lX)", lpFlipData));
|
|
#endif
|
|
|
|
if (0 == lpFlipData->lpSurfCurr->dwReserved1)
|
|
{
|
|
lpFlipData->ddRVal = DDERR_NOTAOVERLAYSURFACE;
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
lpSurfaceData = GET_SURFACE_DATA_PTR(lpFlipData->lpSurfCurr);
|
|
|
|
dwVWIndex = GetVideoWindowIndex(lpSurfaceData->dwOverlayFlags);
|
|
ASSERT(dwNumVideoWindows > dwVWIndex);
|
|
|
|
// When TVTap/VPM is used with DirectDraw, things got more twisted.
|
|
// VPM doesn't call UpdateSurface, so lpHardwareOwner
|
|
// won't be set, nevertheless, the HW is grabbed by VPM.
|
|
// In that case, should fail the Flip call to prevent bad VPM.
|
|
|
|
// YUCK!!!
|
|
// The VWE bit in the hardware seems to be the semaphore for sharing the
|
|
// overlay with VPM
|
|
|
|
if ((lpHardwareOwner[dwVWIndex] == NULL) &&
|
|
#ifdef WINNT_VER40
|
|
IsVWHardwareInUse(ppdev, dwVWIndex)
|
|
#else
|
|
IsVWHardwareInUse(lpDDHALData,dwVWIndex)
|
|
#endif
|
|
)
|
|
{
|
|
#ifndef WINNT_VER40
|
|
DBG_MESSAGE(("VW %ld already in use, Out of Caps!", dwVWIndex));
|
|
#endif
|
|
|
|
lpFlipData->ddRVal = DDERR_OUTOFCAPS;
|
|
return (DDHAL_DRIVER_HANDLED);
|
|
}
|
|
|
|
#ifdef WINNT_VER40
|
|
if(GetOverlayFlipStatus(ppdev, 0, dwVWIndex) != DD_OK || DRAW_ENGINE_BUSY || IN_VBLANK)
|
|
#else
|
|
if(GetOverlayFlipStatus(lpDDHALData,0, dwVWIndex) != DD_OK || DRAW_ENGINE_BUSY || IN_VBLANK)
|
|
#endif
|
|
{
|
|
lpFlipData->ddRVal = DDERR_WASSTILLDRAWING;
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
// Determine the format of the video data
|
|
if (lpFlipData->lpSurfTarg->dwFlags & DDRAWISURF_HASPIXELFORMAT)
|
|
{
|
|
GetFormatInfo (&(lpFlipData->lpSurfTarg->lpGbl->ddpfSurface),
|
|
&dwFourcc,
|
|
&dwBitCount);
|
|
}
|
|
else
|
|
{
|
|
dwBitCount = BITSPERPIXEL;
|
|
}
|
|
|
|
// Determine the offset to the new area.
|
|
#ifdef WINNT_VER40
|
|
dwSurfBase = lpFlipData->lpSurfTarg->lpGbl->fpVidMem;
|
|
#else
|
|
dwSurfBase = (lpFlipData->lpSurfTarg->lpGbl->fpVidMem - lpDDHALData->ScreenAddress);
|
|
#endif
|
|
dwSurfOffset = lpSurfaceData->dwOverlayOffset;
|
|
dwOffset = dwSurfBase + dwSurfOffset;
|
|
|
|
#if ENABLE_MIRRORING
|
|
// Flip the overlay surface by changing PSD_STRT_ADDR
|
|
if (bIsVWMirrored[dwVWIndex])
|
|
{
|
|
// for mirroring
|
|
// point to the last byte of the last pixel on the right edge of the source
|
|
dwOffset += (DWORD)(grOverlaySrc[dwVWIndex].right -
|
|
grOverlaySrc[dwVWIndex].left - 1);
|
|
}
|
|
#endif
|
|
dwOffset2 = 0;
|
|
#if DDRAW_COMPAT >= 50
|
|
dwControl0 = pREG->VideoWindow[dwVWIndex].grVW_CONTROL0;
|
|
if(lpFlipData->lpSurfTarg->lpSurfMore->lpVideoPort != NULL)
|
|
{
|
|
if(( lpFlipData->lpSurfTarg->lpSurfMore->dwOverlayFlags & DDOVER_AUTOFLIP)
|
|
&&(lpFlipData->lpSurfTarg->lpSurfMore->lpVideoPort->ddvpInfo.dwVPFlags
|
|
&DDVP_AUTOFLIP)
|
|
&& (lpFlipData->lpSurfTarg->lpAttachListFrom != NULL)
|
|
&& (lpFlipData->lpSurfTarg->lpAttachListFrom->lpAttached != NULL))
|
|
{
|
|
dwSrfFlags = DDOVER_AUTOFLIP;
|
|
}
|
|
else if(( lpFlipData->lpSurfTarg->lpSurfMore->dwOverlayFlags & DDOVER_BOB)
|
|
&&(lpFlipData->lpSurfTarg->lpSurfMore->lpVideoPort->ddvpInfo.dwVPFlags
|
|
& DDVP_INTERLEAVE))
|
|
{
|
|
dwSrfFlags = DDOVER_BOB;
|
|
//Smooth interlace
|
|
dwOffset2 = dwOffset +
|
|
lpFlipData->lpSurfTarg->lpGbl->lPitch; //point to the next line
|
|
}
|
|
}
|
|
|
|
if(dwSrfFlags & DDOVER_BOB)
|
|
{
|
|
//Smooth interlace
|
|
dwOffset2 = dwOffset +
|
|
lpFlipData->lpSurfTarg->lpGbl->lPitch; //point to the next line
|
|
|
|
}
|
|
else if(dwSrfFlags & DDOVER_AUTOFLIP)
|
|
{
|
|
//Auto Flip Overlay
|
|
dwOffset2 = lpSurfaceData->dwAutoBaseAddr2 + dwSurfOffset;
|
|
if(dwOffset2 == dwOffset)
|
|
{
|
|
dwOffset = lpSurfaceData->dwAutoBaseAddr1 + dwSurfOffset;
|
|
}
|
|
//For non-smooth-interlaced auto-flip these two address need
|
|
// to be switched. HW BUG
|
|
if(!(lpFlipData->lpSurfTarg->lpSurfMore->dwOverlayFlags & DDOVER_BOB))
|
|
{
|
|
DWORD dwTmp = dwOffset;
|
|
dwOffset = dwOffset2;
|
|
dwOffset2 = dwTmp;
|
|
}
|
|
}
|
|
else if( lpFlipData->lpSurfTarg->lpSurfMore->dwOverlayFlags & DDOVER_INTERLEAVED)
|
|
{
|
|
dwControl0 &= ~0x30000;
|
|
if(lpFlipData->dwFlags & DDFLIP_ODD) //SW flip
|
|
{
|
|
dwOffset2 = dwOffset +
|
|
lpFlipData->lpSurfTarg->lpGbl->lPitch ; //point to the next line
|
|
dwControl0 |= 0x10000; //use VW_SDD
|
|
|
|
}
|
|
}
|
|
else if(lpFlipData->dwFlags & DDFLIP_ODD) //SW flip
|
|
{
|
|
dwOffset2 = dwOffset;
|
|
dwControl0 &= ~0x30000;
|
|
dwControl0 |= 0x10000; //use VW_SDD
|
|
}
|
|
#endif
|
|
|
|
// write new start address to hardware
|
|
#ifdef WINNT_VER40
|
|
WaitForVWArmToClear(ppdev,dwVWIndex);
|
|
#else
|
|
WaitForVWArmToClear(lpDDHALData,dwVWIndex);
|
|
#endif
|
|
ASSERT(! (pREG->VideoWindow[dwVWIndex].grVW_TEST0 & VW_PostImed));
|
|
|
|
LL32(VideoWindow[dwVWIndex].grVW_PSD_STRT_ADDR, dwOffset);
|
|
LL32(VideoWindow[dwVWIndex].grVW_SSD_STRT_ADDR, dwOffset2);
|
|
#if ENABLE_YUVPLANAR
|
|
if (lpSurfaceData->dwOverlayFlags & FLG_YUVPLANAR)
|
|
{
|
|
// PSD_STRT_ADDR has been set to the start of the Y data in aperture0
|
|
// set PSD_UVSTRT_ADDR to start of UV interleaved data in aperture 0
|
|
// UV data is only half the height of Y data
|
|
LL32(VideoWindow[dwVWIndex].grVW_PSD_UVSTRT_ADDR,
|
|
dwSurfBase +
|
|
(((lpFlipData->lpSurfTarg->lpGbl->wHeight * lpFlipData->lpSurfTarg->lpGbl->lPitch) + 7) & ~7) +
|
|
(dwSurfOffset / 2));
|
|
LL32(VideoWindow[dwVWIndex].grVW_SSD_UVSTRT_ADDR, dwOffset2);
|
|
}
|
|
#endif
|
|
|
|
#if DDRAW_COMPAT >= 50
|
|
if (lpSurfaceData->dwOverlayFlags & FLG_ENABLED)
|
|
pREG->VideoWindow[dwVWIndex].grVW_CONTROL0 = (dwControl0 |VW_VWE | VW_ARM);
|
|
else
|
|
pREG->VideoWindow[dwVWIndex].grVW_CONTROL0 = dwControl0 | VW_ARM;
|
|
#else
|
|
if (lpSurfaceData->dwOverlayFlags & FLG_ENABLED)
|
|
pREG->VideoWindow[dwVWIndex].grVW_CONTROL0 |= (VW_VWE | VW_ARM);
|
|
else
|
|
pREG->VideoWindow[dwVWIndex].grVW_CONTROL0 |= VW_ARM;
|
|
#endif
|
|
|
|
#ifdef WINNT_VER40
|
|
// Update the hardware owner
|
|
lpHardwareOwner[dwVWIndex] = lpFlipData->lpSurfTarg;
|
|
#endif
|
|
|
|
// remember where/when we were when we did the flip
|
|
#ifdef WINNT_VER40
|
|
EngQueryPerformanceCounter(&gsOverlayFlip.liFlipTime);
|
|
#else
|
|
QueryPerformanceCounter((LARGE_INTEGER *)&gsOverlayFlip.liFlipTime);
|
|
#endif
|
|
#ifdef WINNT_VER40
|
|
gsOverlayFlip.dwFlipScanline = CurrentVLine(ppdev);
|
|
#else
|
|
gsOverlayFlip.dwFlipScanline = CurrentVLine(lpDDHALData);
|
|
#endif
|
|
gsOverlayFlip.bFlipFlag = TRUE;
|
|
gsOverlayFlip.fpFlipFrom = lpFlipData->lpSurfCurr->lpGbl->fpVidMem;
|
|
gsOverlayFlip.bHaveEverCrossedVBlank = FALSE;
|
|
|
|
if (IN_VBLANK)
|
|
{
|
|
gsOverlayFlip.bWasEverInDisplay = FALSE;
|
|
}
|
|
else
|
|
{
|
|
gsOverlayFlip.bWasEverInDisplay = TRUE;
|
|
}
|
|
|
|
lpFlipData->ddRVal = DD_OK;
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: LockSurface
|
|
*
|
|
* DESCRIPTION: Checks for flipping before allowing access to the surface.
|
|
*
|
|
****************************************************************************/
|
|
|
|
STATIC DWORD LockSurface
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
PDD_LOCKDATA lpInput
|
|
#else
|
|
LPDDHAL_LOCKDATA lpInput
|
|
#endif
|
|
)
|
|
{
|
|
#if ENABLE_YUVPLANAR
|
|
LPCLPLSURFACE lpCLPL; // pointer to our YUV planar
|
|
DWORD dwUVOffset;
|
|
#endif
|
|
LP_SURFACE_DATA lpSurfaceData;
|
|
DWORD dwVWIndex;
|
|
#ifndef WINNT_VER40
|
|
LPGLOBALDATA lpDDHALData = GetDDHALContext( lpInput->lpDD);
|
|
#endif
|
|
|
|
#ifndef WINNT_VER40
|
|
DBG_MESSAGE(("Overlay LockSurface (lpInput = 0x%08lX)", lpInput));
|
|
#endif
|
|
|
|
if (0 == lpInput->lpDDSurface->dwReserved1)
|
|
{
|
|
lpInput->ddRVal = DDERR_NOTAOVERLAYSURFACE;
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
lpSurfaceData = GET_SURFACE_DATA_PTR(lpInput->lpDDSurface);
|
|
|
|
dwVWIndex = GetVideoWindowIndex(lpSurfaceData->dwOverlayFlags);
|
|
ASSERT(dwNumVideoWindows > dwVWIndex);
|
|
|
|
// Check for flipping
|
|
if ((gsOverlayFlip.bFlipFlag) &&
|
|
(
|
|
#ifdef WINNT_VER40
|
|
GetOverlayFlipStatus(ppdev, lpInput->lpDDSurface->lpGbl->fpVidMem, dwVWIndex)
|
|
#else
|
|
GetOverlayFlipStatus(lpDDHALData,lpInput->lpDDSurface->lpGbl->fpVidMem, dwVWIndex)
|
|
#endif
|
|
== DDERR_WASSTILLDRAWING))
|
|
{
|
|
lpInput->ddRVal = DDERR_WASSTILLDRAWING;
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
#if ENABLE_YUVPLANAR
|
|
if (lpSurfaceData->dwOverlayFlags & FLG_YUVPLANAR)
|
|
{
|
|
// make sure CLPL aperture is mapped in
|
|
if (! lpDDHALData->dwCLPLAperture)
|
|
{
|
|
lpInput->ddRVal = DD_OK;
|
|
return DDHAL_DRIVER_NOTHANDLED;
|
|
}
|
|
|
|
// here's how this YUV420/YUVPLANAR/CLPL stuff works:
|
|
// the CLPL surface consists of all the Y data followed by a region of
|
|
// UV interleaved data. We are currently supporting only linear surfaces
|
|
// for CLPL so there will be wHeight lines of Y data followed by wHeight/2
|
|
// lines of UV interleaved data. CreateSurface32 has padded the surface
|
|
// allocation such that the UV interleaved data will start on the first
|
|
// quadword boundary following the Y data.
|
|
//
|
|
// We pass back a pointer to a structure containing the address of a Y
|
|
// region, a U region and a V region to the app. The app writes to the
|
|
// U and V regions as if they are linear and the hardware converts this
|
|
// data into the UV interleaved data in aperture 0.
|
|
//
|
|
// For the U ptr we give the app an address pointing somewhere in the
|
|
// first four meg of aperture 3 and for the V ptr we give the app an
|
|
// address pointing to the same somewhere but in the second four meg
|
|
// of aperture 3. When the app writes to these addresses, the data
|
|
// shows up in aperture 0 such that:
|
|
// the U data is at ap0_offset = ap3_offset * 2
|
|
// the V data is at ap0_offset = (ap3_offset - 4MB) * 2 + 1
|
|
//
|
|
// what we need to do then is give the app the folloing ptrs:
|
|
// Y ptr = ap0_offset of the Y region (the beginning of the surface)
|
|
// U ptr = ap3_offset for U data = U_ap0_offset / 2
|
|
// V ptr = ap3_offset for V data = (V_ap0_offset - 1) / 2 + 4MB
|
|
// where U_ap0_offset = offset we want the U data to start
|
|
// and V_ap0_offset = offset we want the V data to start
|
|
// we also need V_ap0_offset = U_ap0_offset + 1
|
|
|
|
// Compute Y and UV aperture in frame buffer
|
|
lpCLPL = (LPCLPLSURFACE)lpSurfaceData->lpCLPLData;
|
|
lpInput->lpSurfData = (LPVOID)lpCLPL;
|
|
|
|
// Y data starts at beginning of surface in aperture0
|
|
lpCLPL->fpYSurface = (LPVOID)lpInput->lpDDSurface->lpGbl->fpVidMem;
|
|
|
|
DBG_MESSAGE(("Aperture0 Y offset = %08lX",
|
|
(lpInput->lpDDSurface->lpGbl->fpVidMem - lpDDHALData->ScreenAddress)));
|
|
DBG_MESSAGE((" surface height = %08lX, pitch = %08lX",
|
|
lpInput->lpDDSurface->lpGbl->wHeight,
|
|
lpInput->lpDDSurface->lpGbl->lPitch));
|
|
|
|
// determine offset of UV data in aperture 0 (and make it qword aligned)
|
|
dwUVOffset = (lpInput->lpDDSurface->lpGbl->fpVidMem - lpDDHALData->ScreenAddress) +
|
|
(((lpInput->lpDDSurface->lpGbl->wHeight * lpInput->lpDDSurface->lpGbl->lPitch) + 7) & ~7);
|
|
DBG_MESSAGE(("Aperture0 UV offset = %08lX", dwUVOffset));
|
|
|
|
// convert UV aperture0 offset to aperture3 offset
|
|
DBG_MESSAGE(("Aperture3 UV offset = %08lX", dwUVOffset / 2));
|
|
dwUVOffset = lpDDHALData->dwCLPLAperture + dwUVOffset / 2;
|
|
|
|
if (bCLPLLobotomyMode)
|
|
{
|
|
lpCLPL->fpRealUSurface = (LPVOID)(dwUVOffset);
|
|
lpCLPL->fpRealVSurface = (LPVOID)(dwUVOffset + 0x400000);
|
|
DBG_MESSAGE(("CLPL lobotomy mode addrs: RealU=%08lX, RealV=%08lX",
|
|
lpCLPL->fpRealUSurface, lpCLPL->fpRealVSurface));
|
|
lpCLPL->fpUSurface = lpCLPL->fpUSystemSurface;
|
|
lpCLPL->fpVSurface = lpCLPL->fpVSystemSurface;
|
|
}
|
|
else
|
|
{
|
|
lpCLPL->fpUSurface = (LPVOID)(dwUVOffset);
|
|
lpCLPL->fpVSurface = (LPVOID)(dwUVOffset + 0x400000);
|
|
}
|
|
|
|
DBG_MESSAGE(("CLPL addrs: Y=%08lX, U=%08lX, V=%08lX",
|
|
lpCLPL->fpYSurface, lpCLPL->fpUSurface, lpCLPL->fpVSurface));
|
|
|
|
lpInput->ddRVal = DD_OK;
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
#endif
|
|
|
|
#if ENABLE_YUY2
|
|
// Force them to use the byte swap aperture
|
|
if (lpSurfaceData->dwOverlayFlags & FLG_YUY2)
|
|
{
|
|
// make sure the YUY2 aperture is mapped in
|
|
if (! lpDDHALData->dwYUY2Aperture)
|
|
{
|
|
lpInput->ddRVal = DD_OK;
|
|
return DDHAL_DRIVER_NOTHANDLED;
|
|
}
|
|
|
|
lpInput->lpSurfData = (LPVOID) ((lpInput->lpDDSurface->lpGbl->fpVidMem -
|
|
lpDDHALData->ScreenAddress) +
|
|
lpDDHALData->dwYUY2Aperture);
|
|
|
|
lpInput->ddRVal = DD_OK;
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
#endif
|
|
|
|
lpInput->ddRVal = DD_OK;
|
|
return DDHAL_DRIVER_NOTHANDLED;
|
|
}
|
|
|
|
#if ENABLE_YUVPLANAR
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: SysToFBCopy()
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if 1
|
|
static INLINE VOID
|
|
SysToFBCopy ( BYTE *dst, LONG dstPitch, BYTE *src, LONG srcPitch, REG32 ext, LONG bpp )
|
|
{
|
|
int yext = ext.pt.Y;
|
|
int xext = ext.pt.X * bpp;
|
|
|
|
while (0 < yext--)
|
|
{
|
|
memcpy(dst,src,xext);
|
|
dst += dstPitch;
|
|
src += srcPitch;
|
|
}
|
|
}
|
|
#else
|
|
// writing the scanline from right to left shows the hwbug where roughly
|
|
// every other 4 dwords written to aperture3 is dropped
|
|
// and the video is generally display with a lovely flourescent green
|
|
// checkerboard pattern
|
|
//
|
|
// This duplicates the problem seen by allowing the Compcore MPEG player
|
|
// write directly to aperture3
|
|
#pragma optimize("", off)
|
|
// the compiler ignores __inline because of the inline assembly
|
|
static INLINE VOID
|
|
SysToFBCopy ( BYTE *dst, LONG dstPitch, BYTE *src, LONG srcPitch, REG32 ext, LONG bpp )
|
|
{
|
|
int yext = ext.pt.Y;
|
|
int xext = ext.pt.X * bpp;
|
|
|
|
_asm std
|
|
|
|
dst += dstPitch - sizeof(DWORD);
|
|
src += srcPitch - sizeof(DWORD);
|
|
|
|
while (0 < yext--)
|
|
{
|
|
_asm
|
|
{
|
|
mov eax,xext
|
|
mov edi,dst
|
|
mov esi,src
|
|
mov ecx,eax
|
|
shr ecx,2
|
|
rep movsd
|
|
mov ecx,eax
|
|
and ecx,3
|
|
rep movsb
|
|
}
|
|
dst += dstPitch;
|
|
src += srcPitch;
|
|
}
|
|
|
|
_asm cld
|
|
}
|
|
#pragma optimize("", on)
|
|
#endif
|
|
#endif
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: UnlockSurface
|
|
*
|
|
* DESCRIPTION: This function is called by DDHAL when it is finished accessing
|
|
* the frame buffer.
|
|
*
|
|
****************************************************************************/
|
|
|
|
STATIC VOID UnlockSurface
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
PDD_UNLOCKDATA lpInput
|
|
#else
|
|
LPDDHAL_UNLOCKDATA lpInput
|
|
#endif
|
|
)
|
|
{
|
|
#if ENABLE_YUVPLANAR
|
|
LPCLPLSURFACE lpCLPL; // pointer to our YUV planar
|
|
#endif
|
|
LP_SURFACE_DATA lpSurfaceData;
|
|
|
|
|
|
#ifndef WINNT_VER40
|
|
DBG_MESSAGE(("Overlay UnlockSurface (lpInput = 0x%08lX)", lpInput));
|
|
#endif
|
|
|
|
if (0 == lpInput->lpDDSurface->dwReserved1)
|
|
{
|
|
lpInput->ddRVal = DDERR_NOTAOVERLAYSURFACE;
|
|
return;
|
|
}
|
|
lpSurfaceData = GET_SURFACE_DATA_PTR(lpInput->lpDDSurface);
|
|
|
|
#if ENABLE_YUVPLANAR
|
|
if ((lpSurfaceData->dwOverlayFlags & FLG_YUVPLANAR) && bCLPLLobotomyMode)
|
|
{
|
|
REG32 ext;
|
|
LONG pitch;
|
|
|
|
lpCLPL = (LPCLPLSURFACE)lpSurfaceData->lpCLPLData;
|
|
|
|
ext.pt.X = lpInput->lpDDSurface->lpGbl->wWidth / 2;
|
|
ext.pt.Y = lpInput->lpDDSurface->lpGbl->wHeight / 2;
|
|
pitch = lpInput->lpDDSurface->lpGbl->lPitch / 2;
|
|
|
|
SysToFBCopy(lpCLPL->fpRealUSurface, pitch, lpCLPL->fpUSystemSurface, pitch, ext, 1);
|
|
SysToFBCopy(lpCLPL->fpRealVSurface, pitch, lpCLPL->fpVSystemSurface, pitch, ext, 1);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: SetColorKey
|
|
*
|
|
* DESCRIPTION: Looks at the color key for changes in the while
|
|
* overlay is active.
|
|
*
|
|
****************************************************************************/
|
|
|
|
STATIC VOID SetColorKey
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
PDD_SETCOLORKEYDATA lpInput
|
|
#else
|
|
LPDDHAL_SETCOLORKEYDATA lpInput
|
|
#endif
|
|
)
|
|
{
|
|
LP_SURFACE_DATA lpSurfaceData;
|
|
LP_SURFACE_DATA lpHWOwnerData;
|
|
DWORD dwVWIndex;
|
|
#ifndef WINNT_VER40
|
|
LPGLOBALDATA lpDDHALData = GetDDHALContext( lpInput->lpDD);
|
|
#endif
|
|
|
|
#ifndef WINNT_VER40
|
|
DBG_MESSAGE(("Overlay SetColorKey (lpInput = 0x%08lX)", lpInput));
|
|
#endif
|
|
|
|
if (0 == lpInput->lpDDSurface->dwReserved1)
|
|
{
|
|
lpInput->ddRVal = DDERR_NOTAOVERLAYSURFACE;
|
|
return;
|
|
}
|
|
lpSurfaceData = GET_SURFACE_DATA_PTR(lpInput->lpDDSurface);
|
|
|
|
dwVWIndex = GetVideoWindowIndex(lpSurfaceData->dwOverlayFlags);
|
|
ASSERT(dwNumVideoWindows > dwVWIndex);
|
|
|
|
if ((lpInput->dwFlags & DDCKEY_DESTOVERLAY) &&
|
|
(lpInput->lpDDSurface == lpColorSurfaceVW[dwVWIndex]))
|
|
{
|
|
// See if someone else is already using the colorkey.
|
|
if ((gdwDestColorKeyOwnerVW & FLG_VW_MASK) &&
|
|
(lpInput->lpDDSurface != lpColorSurfaceVW[dwVWIndex]))
|
|
{
|
|
// ColorKey already being used.
|
|
lpInput->ddRVal = DDERR_OUTOFCAPS;
|
|
return;
|
|
}
|
|
|
|
// You get here only when the call is issued AFTER UpdateOverlay.
|
|
gdwColorKey = lpInput->ckNew.dwColorSpaceLowValue;
|
|
|
|
if (0 == lpHardwareOwner[dwVWIndex]->dwReserved1)
|
|
{
|
|
lpInput->ddRVal = DDERR_NOTAOVERLAYSURFACE;
|
|
return;
|
|
}
|
|
lpHWOwnerData = GET_SURFACE_DATA_PTR(lpHardwareOwner[dwVWIndex]);
|
|
|
|
if ((lpInput->lpDDSurface == lpColorSurfaceVW[dwVWIndex]) &&
|
|
(lpHardwareOwner[dwVWIndex]) &&
|
|
(lpHWOwnerData->dwOverlayFlags & FLG_ENABLED))
|
|
{
|
|
gdwDestColorKeyOwnerVW = MakeVideoWindowFlag(dwVWIndex);
|
|
lpHWOwnerData->dwOverlayFlags |= FLG_COLOR_KEY;
|
|
#ifdef WINNT_VER40
|
|
RegInitVideoVW(ppdev, dwVWIndex, lpHardwareOwner[dwVWIndex]);
|
|
#else
|
|
RegInitVideoVW(dwVWIndex, lpHardwareOwner[dwVWIndex],lpDDHALData);
|
|
#endif
|
|
}
|
|
}
|
|
else if ((lpInput->dwFlags & DDCKEY_SRCOVERLAY) &&
|
|
(lpInput->lpDDSurface == lpSrcColorSurfaceVW[dwVWIndex]))
|
|
{
|
|
// See if someone else already uses the colorkey.
|
|
if ((gdwSrcColorKeyOwnerVW != 0 ) &&
|
|
!(gdwSrcColorKeyOwnerVW & lpSurfaceData->dwOverlayFlags))
|
|
{
|
|
// ColorKey already been used.
|
|
lpInput->ddRVal = DDERR_OUTOFCAPS;
|
|
return;
|
|
}
|
|
gdwSrcColorKeyLow = lpInput->ckNew.dwColorSpaceLowValue;
|
|
gdwSrcColorKeyHigh = lpInput->ckNew.dwColorSpaceHighValue;
|
|
if (gdwSrcColorKeyLow > gdwSrcColorKeyHigh)
|
|
{
|
|
gdwSrcColorKeyHigh = gdwSrcColorKeyLow;
|
|
}
|
|
|
|
if (0 == lpHardwareOwner[dwVWIndex]->dwReserved1)
|
|
{
|
|
lpInput->ddRVal = DDERR_NOTAOVERLAYSURFACE;
|
|
return;
|
|
}
|
|
lpHWOwnerData = GET_SURFACE_DATA_PTR(lpHardwareOwner[dwVWIndex]);
|
|
|
|
if ((lpSurfaceData->dwOverlayFlags & FLG_VW_MASK) &&
|
|
(lpHardwareOwner[dwVWIndex]) &&
|
|
(lpHWOwnerData->dwOverlayFlags & FLG_ENABLED))
|
|
{
|
|
gdwSrcColorKeyOwnerVW = MakeVideoWindowFlag(dwVWIndex);
|
|
lpHWOwnerData->dwOverlayFlags |= FLG_SRC_COLOR_KEY;
|
|
#ifdef WINNT_VER40
|
|
RegInitVideoVW(ppdev, dwVWIndex, lpHardwareOwner[dwVWIndex]);
|
|
#else
|
|
RegInitVideoVW(dwVWIndex, lpHardwareOwner[dwVWIndex],lpDDHALData);
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: SaveRectangles
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
****************************************************************************/
|
|
|
|
static INLINE BOOL SaveRectangles
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
#endif
|
|
DWORD dwVWIndex,
|
|
BOOL bCheckBandwidth,
|
|
DWORD dwBitCount,
|
|
#ifdef WINNT_VER40
|
|
PDD_UPDATEOVERLAYDATA lpInput
|
|
#else
|
|
LPDDHAL_UPDATEOVERLAYDATA lpInput,
|
|
LPGLOBALDATA lpDDHALData
|
|
#endif
|
|
)
|
|
{
|
|
SIZEL Dst;
|
|
SIZEL Src;
|
|
BWREGS bwregs;
|
|
|
|
// Is there sufficient bandwidth to work?
|
|
|
|
gvidConfig.sizSrc.cx = lpInput->rSrc.right - lpInput->rSrc.left;
|
|
gvidConfig.sizSrc.cy = lpInput->rSrc.bottom - lpInput->rSrc.top;
|
|
gvidConfig.sizDisp.cx = lpInput->rDest.right - lpInput->rDest.left;
|
|
gvidConfig.sizDisp.cy = lpInput->rDest.bottom - lpInput->rDest.top;
|
|
gvidConfig.uSrcDepth = dwBitCount;
|
|
gvidConfig.uDispDepth = dwBitCount; //video window has the same as source
|
|
gvidConfig.uGfxDepth = BITSPERPIXEL;
|
|
gvidConfig.dwFlags |= VCFLG_DISP;
|
|
#ifdef WINNT_VER40
|
|
ChipIOReadBWRegs(ppdev, &bwregs);
|
|
#else
|
|
ChipIOReadBWRegs(lpDDHALData, &bwregs);
|
|
#endif
|
|
if (bCheckBandwidth && bUseBWEqn &&
|
|
!ChipIsEnoughBandwidth(&gsProgRegs, &gvidConfig, &bwregs)
|
|
)
|
|
{
|
|
gvidConfig.dwFlags &= ~VCFLG_DISP;
|
|
lpInput->ddRVal = DDERR_OUTOFCAPS;
|
|
return FALSE;
|
|
}
|
|
|
|
// Save the rectangles
|
|
#ifndef WINNT_VER40
|
|
DBG_MESSAGE(("rSrc = %lX,%lX %lX,%lX",
|
|
lpInput->rSrc.left,lpInput->rSrc.top,
|
|
lpInput->rSrc.right,lpInput->rSrc.bottom));
|
|
|
|
DBG_MESSAGE(("rcOverlaySrc = %lX,%lX %lX,%lX",
|
|
lpInput->lpDDSrcSurface->rcOverlaySrc.left,
|
|
lpInput->lpDDSrcSurface->rcOverlaySrc.top,
|
|
lpInput->lpDDSrcSurface->rcOverlaySrc.right,
|
|
lpInput->lpDDSrcSurface->rcOverlaySrc.bottom));
|
|
#endif
|
|
|
|
grOverlaySrc[dwVWIndex].left = (int)lpInput->rSrc.left;
|
|
grOverlaySrc[dwVWIndex].right = (int)lpInput->rSrc.right;
|
|
grOverlaySrc[dwVWIndex].top = (int)lpInput->rSrc.top;
|
|
grOverlaySrc[dwVWIndex].bottom = (int)lpInput->rSrc.bottom;
|
|
|
|
#ifndef WINNT_VER40
|
|
DBG_MESSAGE(("rDest = %lX,%lX %lX,%lX",
|
|
lpInput->rDest.left,lpInput->rDest.top,
|
|
lpInput->rDest.right,lpInput->rDest.bottom));
|
|
|
|
DBG_MESSAGE(("rcOverlayDest = %lX,%lX %lX,%lX",
|
|
lpInput->lpDDSrcSurface->rcOverlayDest.left,
|
|
lpInput->lpDDSrcSurface->rcOverlayDest.top,
|
|
lpInput->lpDDSrcSurface->rcOverlayDest.right,
|
|
lpInput->lpDDSrcSurface->rcOverlayDest.bottom));
|
|
#endif
|
|
|
|
grOverlayDest[dwVWIndex].left = (int)lpInput->rDest.left;
|
|
grOverlayDest[dwVWIndex].right = (int)lpInput->rDest.right;
|
|
grOverlayDest[dwVWIndex].top = (int)lpInput->rDest.top;
|
|
grOverlayDest[dwVWIndex].bottom = (int)lpInput->rDest.bottom;
|
|
|
|
// make sure resize is within hw capabilities
|
|
// x can shrink down to 1/2 and stretch up to 8x
|
|
// y can stretch up to 8x
|
|
Dst.cx = grOverlayDest[dwVWIndex].right - grOverlayDest[dwVWIndex].left;
|
|
Dst.cy = grOverlayDest[dwVWIndex].bottom - grOverlayDest[dwVWIndex].top;
|
|
Src.cx = grOverlaySrc[dwVWIndex].right - grOverlaySrc[dwVWIndex].left;
|
|
Src.cy = grOverlaySrc[dwVWIndex].bottom - grOverlaySrc[dwVWIndex].top;
|
|
|
|
#ifdef WINNT_VER40
|
|
if (Dst.cx > (LONG)(lpDDHALData->dwMaxOverlayStretch * Src.cx / 1000))
|
|
#else
|
|
if (Dst.cx > (LONG)(lpDDHALData->HALInfo.ddCaps.dwMaxOverlayStretch * Src.cx / 1000))
|
|
#endif
|
|
{
|
|
lpInput->ddRVal = DDERR_TOOBIGWIDTH;
|
|
return FALSE;
|
|
}
|
|
#ifdef WINNT_VER40
|
|
else if (Dst.cy > (LONG)(lpDDHALData->dwMaxOverlayStretch * Src.cy / 1000))
|
|
#else
|
|
else if (Dst.cy > (LONG)(lpDDHALData->HALInfo.ddCaps.dwMaxOverlayStretch * Src.cy / 1000))
|
|
#endif
|
|
{
|
|
lpInput->ddRVal = DDERR_TOOBIGHEIGHT;
|
|
return FALSE;
|
|
}
|
|
#ifdef WINNT_VER40
|
|
else if (Dst.cx < (LONG)(lpDDHALData->dwMinOverlayStretch * Src.cx / 1000))
|
|
#else
|
|
else if (Dst.cx < (LONG)(lpDDHALData->HALInfo.ddCaps.dwMinOverlayStretch * Src.cx / 1000))
|
|
#endif
|
|
{
|
|
lpInput->ddRVal = DDERR_UNSUPPORTED; // too small width
|
|
return FALSE;
|
|
}
|
|
|
|
if (MIN_OLAY_WIDTH >= Src.cx)
|
|
{
|
|
lpInput->ddRVal = DDERR_OUTOFCAPS;
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: UpdateSurface
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
****************************************************************************/
|
|
|
|
STATIC DWORD UpdateSurface
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
PDD_UPDATEOVERLAYDATA lpInput
|
|
#else
|
|
LPDDHAL_UPDATEOVERLAYDATA lpInput
|
|
#endif
|
|
)
|
|
{
|
|
DWORD dwOldStatus;
|
|
DWORD dwFourcc;
|
|
BOOL bCheckBandwidth;
|
|
DWORD dwBitCount;
|
|
DWORD dwDestColorKey;
|
|
LP_SURFACE_DATA lpSrcSurfaceData;
|
|
DWORD dwVWIndex;
|
|
DWORD dwVWFlag;
|
|
BWREGS bwregs;
|
|
BOOL bShowOverlay = FALSE;
|
|
#ifndef WINNT_VER40
|
|
LPGLOBALDATA lpDDHALData = GetDDHALContext( lpInput->lpDD);
|
|
#endif
|
|
#ifndef WINNT_VER40
|
|
DBG_MESSAGE(("Overlay UpdateSurface (lpInput = 0x%08lX)", lpInput));
|
|
#endif
|
|
|
|
if (0 == lpInput->lpDDSrcSurface->dwReserved1)
|
|
{
|
|
lpInput->ddRVal = DDERR_NOTAOVERLAYSURFACE;
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
lpSrcSurfaceData = GET_SURFACE_DATA_PTR(lpInput->lpDDSrcSurface);
|
|
|
|
if (lpInput->lpDDSrcSurface->dwFlags & DDRAWISURF_HASPIXELFORMAT)
|
|
{
|
|
GetFormatInfo(&(lpInput->lpDDSrcSurface->lpGbl->ddpfSurface),
|
|
&dwFourcc, &dwBitCount);
|
|
}
|
|
else
|
|
{
|
|
dwBitCount = BITSPERPIXEL;
|
|
if (16 == dwBitCount)
|
|
dwFourcc = BI_BITFIELDS; // 5:6:5
|
|
else
|
|
dwFourcc = BI_RGB; // 8bpp, 5:5:5, 24bpp & 32bpp
|
|
}
|
|
|
|
gvidConfig.dwFlags &= ~(VCFLG_COLORKEY | VCFLG_CHROMAKEY |
|
|
VCFLG_DISP | VCFLG_420);
|
|
#if ENABLE_YUVPLANAR
|
|
if (lpSrcSurfaceData->dwOverlayFlags & FLG_YUVPLANAR)
|
|
gvidConfig.dwFlags |= VCFLG_420;
|
|
#endif
|
|
|
|
// Are we color keying?
|
|
bCheckBandwidth = TRUE;
|
|
dwOldStatus = lpSrcSurfaceData->dwOverlayFlags;
|
|
|
|
dwVWIndex = GetVideoWindowIndex(dwOldStatus);
|
|
ASSERT(dwNumVideoWindows > dwVWIndex);
|
|
dwVWFlag = MakeVideoWindowFlag(dwVWIndex);
|
|
|
|
lpColorSurfaceVW[dwVWIndex] = lpSrcColorSurfaceVW[dwVWIndex] = NULL;
|
|
#if ENABLE_MIRRORING
|
|
bIsVWMirrored[dwVWIndex] = FALSE;
|
|
#endif
|
|
|
|
if ((lpInput->dwFlags & (DDOVER_KEYDEST | DDOVER_KEYDESTOVERRIDE)) &&
|
|
(lpInput->dwFlags & (DDOVER_KEYSRC | DDOVER_KEYSRCOVERRIDE)))
|
|
{
|
|
// Cannot perform src colorkey and dest colorkey at the same time
|
|
lpInput->ddRVal = DDERR_NOCOLORKEYHW;
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
#if HWBUG_24BPP_DST_COLORKEY
|
|
if (
|
|
#ifdef WINNT_VER40
|
|
(24 == ppdev->ulBitCount) &&
|
|
#else
|
|
(24 == pPDevice->deBitsPixel) &&
|
|
#endif
|
|
(lpInput->dwFlags & (DDOVER_KEYDEST | DDOVER_KEYDESTOVERRIDE)))
|
|
{
|
|
// destination colorkeying at 24bpp is busted in hardware
|
|
lpInput->ddRVal = DDERR_NOCOLORKEYHW;
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
#endif
|
|
|
|
#ifdef WINNT_VER40
|
|
ChipIOReadBWRegs(ppdev, &bwregs);
|
|
#else
|
|
ChipIOReadBWRegs(lpDDHALData, &bwregs);
|
|
#endif
|
|
|
|
lpSrcSurfaceData->dwOverlayFlags &= ~(FLG_COLOR_KEY|FLG_SRC_COLOR_KEY);
|
|
|
|
#ifndef WINNT_VER40
|
|
if ( (lpInput->dwFlags == 0)
|
|
&& (lpHardwareOwner[dwVWIndex] == NULL)
|
|
&& (lpSrcSurfaceData->dwOverlayFlags & FLG_OVERLAY) )
|
|
{
|
|
bShowOverlay = TRUE;
|
|
}
|
|
#endif
|
|
|
|
if (lpInput->dwFlags & (DDOVER_KEYDEST | DDOVER_KEYDESTOVERRIDE))
|
|
{
|
|
dwDestColorKey = (lpInput->dwFlags & DDOVER_KEYDEST)
|
|
? lpInput->lpDDDestSurface->ddckCKDestOverlay.dwColorSpaceLowValue
|
|
: lpInput->overlayFX.dckDestColorkey.dwColorSpaceLowValue;
|
|
|
|
// Allow colorkey override only when it's the original
|
|
// colorkey owner, or no one owns the colorkey so far.
|
|
if (gdwDestColorKeyOwnerVW == 0)
|
|
{
|
|
gdwDestColorKeyOwnerVW = dwVWFlag;
|
|
}
|
|
else if ((dwDestColorKey != gdwColorKey) &&
|
|
(dwOldStatus & dwVWFlag) &&
|
|
!(gdwDestColorKeyOwnerVW & dwVWFlag))
|
|
{
|
|
// ColorKey already been used by someone else.
|
|
// It's not the original colorkey owner,
|
|
// and the key color is not the same as the other one.
|
|
lpInput->ddRVal = DDERR_OUTOFCAPS;
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
// Is there sufficient bandwidth to work?
|
|
gvidConfig.sizSrc.cx = lpInput->rSrc.right - lpInput->rSrc.left;
|
|
gvidConfig.sizSrc.cy = lpInput->rSrc.bottom - lpInput->rSrc.top;
|
|
gvidConfig.sizDisp.cx = lpInput->rDest.right - lpInput->rDest.left;
|
|
gvidConfig.sizDisp.cy = lpInput->rDest.bottom - lpInput->rDest.top;
|
|
gvidConfig.uSrcDepth = dwBitCount;
|
|
gvidConfig.uDispDepth = dwBitCount; //video window has the same depth as
|
|
//the source
|
|
gvidConfig.uGfxDepth = BITSPERPIXEL;
|
|
gvidConfig.dwFlags |= VCFLG_COLORKEY | VCFLG_DISP;
|
|
|
|
if (!bUseBWEqn ||
|
|
ChipIsEnoughBandwidth(&gsProgRegs, &gvidConfig, &bwregs)
|
|
)
|
|
{
|
|
bCheckBandwidth = FALSE;
|
|
lpSrcSurfaceData->dwOverlayFlags |= FLG_COLOR_KEY;
|
|
|
|
if (lpInput->dwFlags & DDOVER_KEYDEST)
|
|
{
|
|
gdwColorKey = lpInput->lpDDDestSurface->ddckCKDestOverlay.dwColorSpaceLowValue;
|
|
lpColorSurfaceVW[dwVWIndex] = lpInput->lpDDDestSurface;
|
|
}
|
|
else
|
|
{
|
|
gdwColorKey = lpInput->overlayFX.dckDestColorkey.dwColorSpaceLowValue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
gvidConfig.dwFlags &= ~(VCFLG_COLORKEY | VCFLG_DISP);
|
|
lpInput->ddRVal = DDERR_NOCOLORKEYHW;
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
}
|
|
else if (lpInput->dwFlags & (DDOVER_KEYSRC | DDOVER_KEYSRCOVERRIDE))
|
|
{
|
|
// Allow SrcColorKey override only when it's the original
|
|
// colorkey owner, or no one owns the colorkey so far.
|
|
if (gdwSrcColorKeyOwnerVW == 0)
|
|
{
|
|
gdwSrcColorKeyOwnerVW = dwVWFlag;
|
|
}
|
|
else if (!(dwOldStatus & gdwSrcColorKeyOwnerVW))
|
|
{
|
|
// It's not the original colorkey owner
|
|
lpInput->ddRVal = DDERR_OUTOFCAPS;
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
// Is there sufficient bandwidth to work?
|
|
gvidConfig.sizSrc.cx = lpInput->rSrc.right - lpInput->rSrc.left;
|
|
gvidConfig.sizSrc.cy = lpInput->rSrc.bottom - lpInput->rSrc.top;
|
|
gvidConfig.sizDisp.cx = lpInput->rDest.right - lpInput->rDest.left;
|
|
gvidConfig.sizDisp.cy = lpInput->rDest.bottom - lpInput->rDest.top;
|
|
gvidConfig.uSrcDepth = dwBitCount;
|
|
gvidConfig.uDispDepth = dwBitCount; //video window has the same as source
|
|
gvidConfig.uGfxDepth = BITSPERPIXEL;
|
|
gvidConfig.dwFlags |= VCFLG_CHROMAKEY | VCFLG_DISP;
|
|
|
|
if (!bUseBWEqn ||
|
|
ChipIsEnoughBandwidth(&gsProgRegs, &gvidConfig, &bwregs)
|
|
)
|
|
{
|
|
bCheckBandwidth = FALSE;
|
|
lpSrcSurfaceData->dwOverlayFlags |= FLG_SRC_COLOR_KEY;
|
|
|
|
lpSrcColorSurfaceVW[dwVWIndex] = lpInput->lpDDSrcSurface;
|
|
|
|
if (lpInput->dwFlags & DDOVER_KEYSRC)
|
|
{
|
|
gdwSrcColorKeyLow = lpInput->lpDDSrcSurface->ddckCKSrcOverlay.dwColorSpaceLowValue;
|
|
gdwSrcColorKeyHigh = lpInput->lpDDSrcSurface->ddckCKSrcOverlay.dwColorSpaceHighValue;
|
|
}
|
|
else
|
|
{
|
|
gdwSrcColorKeyLow = lpInput->overlayFX.dckSrcColorkey.dwColorSpaceLowValue;
|
|
gdwSrcColorKeyHigh = lpInput->overlayFX.dckSrcColorkey.dwColorSpaceHighValue;
|
|
}
|
|
if (gdwSrcColorKeyHigh < gdwSrcColorKeyHigh)
|
|
{
|
|
gdwSrcColorKeyHigh = gdwSrcColorKeyLow;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
gvidConfig.dwFlags &= ~(VCFLG_CHROMAKEY | VCFLG_DISP);
|
|
lpInput->ddRVal = DDERR_NOCOLORKEYHW;
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
}
|
|
|
|
#ifdef WINNT_VER40
|
|
#if 0
|
|
// The hardware is broken when using RGB32 data and ShrinkXBy2.
|
|
if ( (dwFourcc == BI_RGB) && (dwBitCount == 32)
|
|
&& (gvidConfig.sizSrc.cx > gvidConfig.sizDisp.cx)
|
|
&& (lpSrcSurfaceData->dwOverlayFlags & (FLG_ENABLED | 0x02000000)) )
|
|
{
|
|
if (lpSrcSurfaceData->dwOverlayFlags & FLG_ENABLED)
|
|
{
|
|
// Turn the video off.
|
|
DisableOverlay(ppdev, dwVWIndex);
|
|
lpHardwareOwner[dwVWIndex] = NULL;
|
|
lpSrcSurfaceData->dwOverlayFlags &= ~FLG_ENABLED;
|
|
lpSrcSurfaceData->dwOverlayFlags |= 0x02000000;
|
|
}
|
|
|
|
if (lpSrcSurfaceData->dwOverlayFlags & FLG_VW_MASK)
|
|
{
|
|
PVGAR pREG = (PVGAR) lpDDHALData->RegsAddress;
|
|
|
|
if (giOvlyCnt[dwVWIndex] > 0)
|
|
{
|
|
if (--giOvlyCnt[dwVWIndex] == 0)
|
|
{
|
|
// Get current DTTR, mask off FIFO threshold.
|
|
WORD CurrentDTTR = pREG->grDisplay_Threshold_and_Tiling
|
|
& 0xFFC0;
|
|
|
|
// Fix PDR 9574: Restore FIFO threshold value when overlay
|
|
// surface is destroyed, do not restore the tile size. If
|
|
// tile size has changed, we are likely in the middle of
|
|
// changing video mode. No need to restore FIFO in this
|
|
// case.
|
|
if ( CurrentDTTR == (gwNormalDTTR & 0xFFC0) )
|
|
{
|
|
pREG->grDisplay_Threshold_and_Tiling = CurrentDTTR
|
|
| (gwNormalDTTR & 0x003F);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (giOvlyCnt[dwVWIndex] > 0)
|
|
{
|
|
giOvlyCnt[dwVWIndex]--;
|
|
}
|
|
|
|
// Clear up the ownership of Dest ColorKey.
|
|
gdwDestColorKeyOwnerVW &= ~(lpSrcSurfaceData->dwOverlayFlags
|
|
& FLG_VW_MASK);
|
|
|
|
// Clear up the ownership of Src ColorKey.
|
|
gdwSrcColorKeyOwnerVW &= ~(lpSrcSurfaceData->dwOverlayFlags
|
|
& FLG_VW_MASK);
|
|
|
|
lpInput->ddRVal = DDERR_OUTOFCAPS;
|
|
return(DDHAL_DRIVER_HANDLED);
|
|
}
|
|
#else
|
|
// The hardware is broken when using RGB32 data and ShrinkXBy2.
|
|
if ( (dwFourcc == BI_RGB) && (dwBitCount == 32)
|
|
&& (gvidConfig.sizSrc.cx > gvidConfig.sizDisp.cx)
|
|
&& (lpSrcSurfaceData->dwOverlayFlags & FLG_ENABLED) )
|
|
{
|
|
// Turn the video off.
|
|
DisableOverlay(ppdev, dwVWIndex);
|
|
lpHardwareOwner[dwVWIndex] = NULL;
|
|
lpSrcSurfaceData->dwOverlayFlags &= ~FLG_ENABLED;
|
|
lpSrcSurfaceData->dwOverlayFlags |= 0x02000000;
|
|
|
|
if (lpSrcSurfaceData->dwOverlayFlags & FLG_VW_MASK)
|
|
{
|
|
PVGAR pREG = (PVGAR) lpDDHALData->RegsAddress;
|
|
|
|
if (giOvlyCnt[dwVWIndex] > 0)
|
|
{
|
|
if (--giOvlyCnt[dwVWIndex] == 0)
|
|
{
|
|
// Get current DTTR, mask off FIFO threshold.
|
|
WORD CurrentDTTR = pREG->grDisplay_Threshold_and_Tiling
|
|
& 0xFFC0;
|
|
|
|
// Fix PDR 9574: Restore FIFO threshold value when overlay
|
|
// surface is destroyed, do not restore the tile size. If
|
|
// tile size has changed, we are likely in the middle of
|
|
// changing video mode. No need to restore FIFO in this
|
|
// case.
|
|
if ( CurrentDTTR == (gwNormalDTTR & 0xFFC0) )
|
|
{
|
|
pREG->grDisplay_Threshold_and_Tiling = CurrentDTTR
|
|
| (gwNormalDTTR & 0x003F);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (giOvlyCnt[dwVWIndex] > 0)
|
|
{
|
|
giOvlyCnt[dwVWIndex]--;
|
|
}
|
|
|
|
// Clear up the ownership of Dest ColorKey.
|
|
gdwDestColorKeyOwnerVW &= ~(lpSrcSurfaceData->dwOverlayFlags
|
|
& FLG_VW_MASK);
|
|
|
|
// Clear up the ownership of Src ColorKey.
|
|
gdwSrcColorKeyOwnerVW &= ~(lpSrcSurfaceData->dwOverlayFlags
|
|
& FLG_VW_MASK);
|
|
|
|
lpInput->ddRVal = DDERR_OUTOFCAPS;
|
|
return(DDHAL_DRIVER_HANDLED);
|
|
}
|
|
else if (lpSrcSurfaceData->dwOverlayFlags & 0x02000000)
|
|
{
|
|
if (gvidConfig.sizSrc.cx > gvidConfig.sizDisp.cx)
|
|
{
|
|
lpInput->ddRVal = DDERR_OUTOFCAPS;
|
|
return(DDHAL_DRIVER_HANDLED);
|
|
}
|
|
lpSrcSurfaceData->dwOverlayFlags &= ~0x02000000;
|
|
}
|
|
#endif
|
|
#endif /* WINNT_VER40 */
|
|
|
|
// Because of Microsoft's Overfly bug we must ignore DDOVER_DDFX completely
|
|
// or Overfly reports DDERR_UNSUPPORTED at least in 1024x768x16
|
|
// So these guys can't even write a test app for WHQL that abides by their
|
|
// own rules?
|
|
if (lpInput->dwFlags & DDOVER_DDFX)
|
|
{
|
|
#ifndef WINNT_VER40
|
|
DBG_MESSAGE((" overlayFX.dwFlags = %08lX", lpInput->overlayFX.dwFlags));
|
|
DBG_MESSAGE((" overlayFX.dwDDFX = %08lX", lpInput->overlayFX.dwDDFX));
|
|
#endif
|
|
|
|
#if ENABLE_MIRRORING
|
|
if (lpInput->overlayFX.dwDDFX & DDOVERFX_MIRRORLEFTRIGHT)
|
|
{
|
|
bIsVWMirrored[dwVWIndex] = TRUE;
|
|
}
|
|
// For some bizarre reason, Microsoft's WHQL Overfly app sets the
|
|
// DDOVER_DDFX flag but sets overlayFX.dwDDFX with complete junk
|
|
// overlayFX.dwFlags also has junk
|
|
// so we must ignore dwDDFX flags we don't support rather than return an
|
|
// error. Gee that sound like good practice!
|
|
#if 0
|
|
else
|
|
{
|
|
lpInput->ddRVal = DDERR_UNSUPPORTED;
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
#if DDRAW_COMPAT >= 50
|
|
if( lpInput->dwFlags & DDOVER_AUTOFLIP)
|
|
{
|
|
if(lpInput->lpDDSrcSurface->lpSurfMore->lpVideoPort)
|
|
{
|
|
if(lpInput->lpDDSrcSurface->lpSurfMore->lpVideoPort->dwNumAutoflip
|
|
!= 2)
|
|
{
|
|
//Hardware only support autoflip between 2 surfaces
|
|
lpInput->ddRVal = DDERR_GENERIC;
|
|
return (DDHAL_DRIVER_HANDLED);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//Autoflip must use vport
|
|
lpInput->ddRVal = DDERR_INVALIDPARAMS;
|
|
return (DDHAL_DRIVER_HANDLED);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if ( (lpInput->dwFlags & DDOVER_SHOW) || bShowOverlay)
|
|
{
|
|
// Is somebody else using our hardware?
|
|
if (((lpHardwareOwner[dwVWIndex] != NULL) &&
|
|
(lpHardwareOwner[dwVWIndex] != lpInput->lpDDSrcSurface)) ||
|
|
((lpHardwareOwner[dwVWIndex] == NULL) &&
|
|
#ifdef WINNT_VER40
|
|
IsVWHardwareInUse(ppdev, dwVWIndex)
|
|
#else
|
|
IsVWHardwareInUse(lpDDHALData,dwVWIndex)
|
|
#endif
|
|
))
|
|
{
|
|
lpInput->ddRVal = DDERR_OUTOFCAPS;
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
// Is a valid destination surface specified?
|
|
if (!(lpInput->lpDDDestSurface->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
|
|
{
|
|
lpInput->ddRVal = DDERR_INVALIDPARAMS;
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
// Save the rectangles
|
|
#ifdef WINNT_VER40
|
|
if (! SaveRectangles(ppdev, dwVWIndex, bCheckBandwidth, dwBitCount, lpInput))
|
|
#else
|
|
if (! SaveRectangles(dwVWIndex, bCheckBandwidth, dwBitCount,lpInput,lpDDHALData))
|
|
#endif
|
|
{
|
|
// SaveRectangles sets lpInput->ddRVal on error
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
#if DDRAW_COMPAT >= 50
|
|
lpInput->lpDDSrcSurface->lpSurfMore->dwOverlayFlags = lpInput->dwFlags;
|
|
#endif
|
|
|
|
lpHardwareOwner[dwVWIndex] = lpInput->lpDDSrcSurface;
|
|
lpSrcSurfaceData->dwOverlayFlags |= FLG_ENABLED;
|
|
#ifdef WINNT_VER40
|
|
RegInitVideoVW(ppdev, dwVWIndex, lpInput->lpDDSrcSurface);
|
|
#else
|
|
RegInitVideoVW(dwVWIndex, lpInput->lpDDSrcSurface, lpDDHALData);
|
|
#endif
|
|
}
|
|
else if (lpInput->dwFlags & DDOVER_HIDE)
|
|
{
|
|
if (lpHardwareOwner[dwVWIndex] == lpInput->lpDDSrcSurface)
|
|
{
|
|
lpHardwareOwner[dwVWIndex] = NULL;
|
|
// clear panning show bit here
|
|
|
|
// Turn the video off
|
|
lpSrcSurfaceData->dwOverlayFlags &= ~FLG_ENABLED;
|
|
#ifdef WINNT_VER40
|
|
DisableOverlay(ppdev, dwVWIndex);
|
|
#else
|
|
DisableOverlay(lpDDHALData, dwVWIndex);
|
|
#endif
|
|
}
|
|
}
|
|
else if (lpHardwareOwner[dwVWIndex] == lpInput->lpDDSrcSurface)
|
|
{
|
|
//Save the rectangles
|
|
#ifdef WINNT_VER40
|
|
if (! SaveRectangles(ppdev, dwVWIndex, bCheckBandwidth, dwBitCount, lpInput))
|
|
#else
|
|
if (! SaveRectangles(dwVWIndex, bCheckBandwidth, dwBitCount,lpInput,lpDDHALData))
|
|
#endif
|
|
{
|
|
// SaveRectangles sets lpInput->ddRVal on error
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
#if DDRAW_COMPAT >= 50
|
|
lpInput->lpDDSrcSurface->lpSurfMore->dwOverlayFlags = lpInput->dwFlags;
|
|
#endif
|
|
|
|
#ifdef WINNT_VER40
|
|
RegInitVideoVW(ppdev, dwVWIndex, lpInput->lpDDSrcSurface);
|
|
#else
|
|
RegInitVideoVW(dwVWIndex, lpInput->lpDDSrcSurface, lpDDHALData);
|
|
#endif
|
|
}
|
|
|
|
lpInput->ddRVal = DD_OK;
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: SetPosition
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
****************************************************************************/
|
|
|
|
STATIC DWORD SetPosition
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
PDD_SETOVERLAYPOSITIONDATA lpInput
|
|
#else
|
|
LPDDHAL_SETOVERLAYPOSITIONDATA lpInput
|
|
#endif
|
|
)
|
|
{
|
|
LP_SURFACE_DATA lpSrcSurfaceData;
|
|
DWORD dwVWIndex;
|
|
#ifndef WINNT_VER40
|
|
LPGLOBALDATA lpDDHALData = GetDDHALContext( lpInput->lpDD);
|
|
#endif
|
|
|
|
#ifndef WINNT_VER40
|
|
DBG_MESSAGE(("Overlay SetPosition (lpInput = 0x%08lX)", lpInput));
|
|
#endif
|
|
|
|
if (0 == lpInput->lpDDSrcSurface->dwReserved1)
|
|
{
|
|
lpInput->ddRVal = DDERR_NOTAOVERLAYSURFACE;
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
lpSrcSurfaceData = GET_SURFACE_DATA_PTR(lpInput->lpDDSrcSurface);
|
|
|
|
dwVWIndex = GetVideoWindowIndex(lpSrcSurfaceData->dwOverlayFlags);
|
|
ASSERT(dwNumVideoWindows > dwVWIndex);
|
|
|
|
if (lpHardwareOwner[dwVWIndex] == lpInput->lpDDSrcSurface)
|
|
{
|
|
// Update the rectangles
|
|
grOverlayDest[dwVWIndex].right =
|
|
(int)(grOverlayDest[dwVWIndex].right - grOverlayDest[dwVWIndex].left)
|
|
+ (int)lpInput->lXPos;
|
|
grOverlayDest[dwVWIndex].left = (int) lpInput->lXPos;
|
|
grOverlayDest[dwVWIndex].bottom =
|
|
(int)(grOverlayDest[dwVWIndex].bottom - grOverlayDest[dwVWIndex].top)
|
|
+ (int)lpInput->lYPos;
|
|
grOverlayDest[dwVWIndex].top = (int) lpInput->lYPos;
|
|
|
|
#ifdef WINNT_VER40
|
|
RegMoveVideoVW(ppdev, dwVWIndex, lpInput->lpDDSrcSurface);
|
|
#else
|
|
RegMoveVideoVW(dwVWIndex, lpInput->lpDDSrcSurface, lpDDHALData);
|
|
#endif
|
|
}
|
|
|
|
lpInput->ddRVal = DD_OK;
|
|
return DDHAL_DRIVER_HANDLED;
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: GetOverlayFlipStatus
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
****************************************************************************/
|
|
|
|
STATIC DWORD GetOverlayFlipStatus
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
#else
|
|
LPGLOBALDATA lpDDHALData,
|
|
#endif
|
|
FLATPTR fpVidMem,
|
|
DWORD dwVWIndex
|
|
)
|
|
{
|
|
if (gsOverlayFlip.bFlipFlag &&
|
|
((fpVidMem == 0) || (fpVidMem == gsOverlayFlip.fpFlipFrom)))
|
|
{
|
|
#if 1
|
|
// if arm bit is set then some action is still pending
|
|
// so fail
|
|
ASSERT(dwNumVideoWindows > dwVWIndex);
|
|
if (VW_ARM & ((PVGAR)lpDDHALData->RegsAddress)->VideoWindow[dwVWIndex].grVW_CONTROL0)
|
|
return (DWORD)DDERR_WASSTILLDRAWING;
|
|
#else
|
|
__int64 ttime;
|
|
int iTemp;
|
|
|
|
|
|
DBG_MESSAGE(("GetOverlayFlipStatus (fpVidMem = 0x%08lX)", fpVidMem));
|
|
|
|
// If the current scanline is less than the flip scan line,
|
|
// we know that a VSYNC has occurred.
|
|
iTemp = CurrentVLine(lpDDHALData);
|
|
if (gsOverlayFlip.dwFlipScanline > (DWORD) iTemp)
|
|
{
|
|
// Don't allow access during the vertical retrace
|
|
if (iTemp == 0)
|
|
{
|
|
if (gsOverlayFlip.bWasEverInDisplay)
|
|
{
|
|
gsOverlayFlip.bHaveEverCrossedVBlank = TRUE;
|
|
}
|
|
return (DWORD)DDERR_WASSTILLDRAWING;
|
|
}
|
|
}
|
|
|
|
// Otherwise, we can check to see if 1) we have ever
|
|
// been in a vertical retrace or 2) if a fixed amount of time
|
|
// has expired.
|
|
else if (gsOverlayFlip.bHaveEverCrossedVBlank == FALSE)
|
|
{
|
|
gsOverlayFlip.bWasEverInDisplay = TRUE;
|
|
QueryPerformanceCounter((LARGE_INTEGER *)&ttime);
|
|
if ((ttime-gsOverlayFlip.liFlipTime) <= gsOverlayFlip.dwFlipDuration)
|
|
{
|
|
return (DWORD)DDERR_WASSTILLDRAWING;
|
|
}
|
|
}
|
|
#endif
|
|
gsOverlayFlip.bFlipFlag = FALSE;
|
|
}
|
|
|
|
return DD_OK;
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: ComputeVWZoomCodes
|
|
*
|
|
* DESCRIPTION: Computes HACCUM_STP, HACCUM_SD,
|
|
* VACCUM_STP, VACCUM_SDA and VACCUM_SDB
|
|
*
|
|
****************************************************************************/
|
|
|
|
STATIC VOID ComputeVWZoomCodes
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
#endif
|
|
DWORD dwVWIndex,
|
|
VWDATA *pVWData
|
|
)
|
|
{
|
|
SIZEL Dst;
|
|
SIZEL Src;
|
|
|
|
|
|
Dst.cx = grOverlayDest[dwVWIndex].right - grOverlayDest[dwVWIndex].left;
|
|
Src.cx = grOverlaySrc[dwVWIndex].right - grOverlaySrc[dwVWIndex].left;
|
|
|
|
if (Dst.cx == Src.cx)
|
|
{
|
|
// no horizontal resize
|
|
pVWData->HACCUM_STP = 0x00010000;
|
|
}
|
|
else if (Dst.cx > Src.cx)
|
|
{
|
|
// make sure we aren't going beyond hw capabilities
|
|
ASSERT(Dst.cx <= 8 * Src.cx);
|
|
|
|
// horizontal stretch
|
|
//
|
|
// ideally zoom code = 256 * (256 * Src.cx / Dst.cx)
|
|
// we always want to truncate (256 * Src.cy / Dst.cx)
|
|
// because truncating will give us back a Src.cx which is less than or
|
|
// equal to the actual width of the source and we will never overrun the
|
|
// source extent (and won't get the green stripe)
|
|
pVWData->HACCUM_STP = (256 * 256 * Src.cx) / Dst.cx;
|
|
}
|
|
else
|
|
{
|
|
// make sure we aren't going beyond hw capabilities
|
|
ASSERT(2 * Dst.cx >= Src.cx);
|
|
|
|
// horizontal shrink
|
|
//
|
|
// this is the zoom code for Src.cx/2 be stretched to Dst.cx
|
|
|
|
// using 128 seems to give a zoom code one too high
|
|
// then we get the green stripe on the right edge of the video
|
|
pVWData->HACCUM_STP = (256 * 127 * Src.cx) / Dst.cx;
|
|
pVWData->CONTROL0 |= VW_XShrinkBy2;
|
|
}
|
|
// Just set horizontal seeds to zero for now
|
|
pVWData->HACCUM_SD = 0;
|
|
|
|
Dst.cy = grOverlayDest[dwVWIndex].bottom - grOverlayDest[dwVWIndex].top;
|
|
Src.cy = grOverlaySrc[dwVWIndex].bottom - grOverlaySrc[dwVWIndex].top;
|
|
|
|
if (Dst.cy == Src.cy)
|
|
{
|
|
pVWData->VACCUM_STP = 0x00010000;
|
|
}
|
|
else if (Dst.cy > Src.cy)
|
|
{
|
|
// make sure we aren't going beyond hw capabilities
|
|
ASSERT(Dst.cy <= 8 * Src.cy);
|
|
|
|
// vertical stretch
|
|
//
|
|
// ideally zoom code = 256 * (256 * Src.cy / Dst.cy)
|
|
// we always want to truncate (256 * Src.cy / Dst.cy)
|
|
// because truncating will give us back a Src.cy which is less than or
|
|
// equal to the actual size of the source and we will never overrun the
|
|
// source extent (and won't get the green stripe)
|
|
|
|
// using 256 seems to give a zoom code one too high for full screen
|
|
// then we get garbage on the bottom of the screen
|
|
pVWData->VACCUM_STP = (256 * 255 * Src.cy) / Dst.cy;
|
|
}
|
|
else
|
|
{
|
|
// vertical shrink
|
|
//
|
|
// ideally zoom code = 256 * (256 * Dst.cy / Src.cy)
|
|
// we always want to round up (256 * Dst.cy / Src.cy)
|
|
// because rounding up will give us back a Src.cy which is less than or
|
|
// equal to the actual size of the source and we will never overrun the
|
|
// source extent (and won't get the green stripe)
|
|
pVWData->VACCUM_STP = (256 * 256 * Dst.cy + 256 * (Src.cy - 1)) / Src.cy;
|
|
pVWData->CONTROL1 |= VW_YShrinkEn;
|
|
}
|
|
// Just set vertical seeds to zero for now
|
|
pVWData->VACCUM_SDA = 0;
|
|
pVWData->VACCUM_SDB = 0;
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: ComputeVWPositionData
|
|
*
|
|
* DESCRIPTION: Computes HSTRT, HEND, HSDSZ, VSTRT, VEND,
|
|
* PD_STRT_ADDR and SD_PITCH
|
|
*
|
|
****************************************************************************/
|
|
|
|
STATIC VOID
|
|
ComputeVWPositionData ( PRECTL pVideoRect,
|
|
PRECTL pOverlaySrc,
|
|
PRECTL pOverlayDest,
|
|
#ifdef WINNT_VER40
|
|
PDD_SURFACE_GLOBAL pGbl,
|
|
#else
|
|
LPDDRAWI_DDRAWSURFACE_GBL pGbl,
|
|
LPGLOBALDATA lpDDHALData,
|
|
#endif
|
|
DWORD dwBitCount,
|
|
VWDATA *pVWData,
|
|
BOOL bCLPL )
|
|
{
|
|
DWORD dwSurfBase,dwSurfOffset;
|
|
|
|
|
|
pVWData->HSTRT = LOWORD(pVideoRect->left);
|
|
pVWData->HEND = LOWORD(pVideoRect->right) - 1;
|
|
pVWData->HSDSZ = (WORD)(pOverlaySrc->right - pOverlaySrc->left);
|
|
|
|
pVWData->VSTRT = LOWORD(pVideoRect->top);
|
|
pVWData->VEND = LOWORD(pVideoRect->bottom) - 1;
|
|
|
|
#ifdef WINNT_VER40
|
|
dwSurfBase = pGbl->fpVidMem;
|
|
#else
|
|
dwSurfBase = (pGbl->fpVidMem - lpDDHALData->ScreenAddress);
|
|
#endif
|
|
dwSurfOffset = pOverlaySrc->top * pGbl->lPitch +
|
|
pOverlaySrc->left * (dwBitCount / 8);
|
|
pVWData->PSD_STRT_ADDR = dwSurfBase + dwSurfOffset;
|
|
|
|
#if ENABLE_YUVPLANAR
|
|
if (bCLPL)
|
|
{
|
|
// qword aligned offset of UV interleaved data in aperture 0
|
|
// need same offset into UV data as offset into Y data
|
|
// so it's just PSD_STRT_ADDR plus area of Y data
|
|
pVWData->PSD_UVSTRT_ADDR = dwSurfBase +
|
|
(((pGbl->wHeight * pGbl->lPitch) + 7) & ~7) +
|
|
(dwSurfOffset / 2);
|
|
}
|
|
else
|
|
pVWData->PSD_UVSTRT_ADDR = 0;
|
|
#endif
|
|
|
|
#if ENABLE_MIRRORING
|
|
if (bIsVWMirrored[dwVWIndex])
|
|
{
|
|
// for mirroring
|
|
// point to the last byte of the last pixel on the right edge of the source
|
|
pVWData->PSD_STRT_ADDR += (DWORD)(pOverlaySrc->right - pOverlaySrc->left - 1);
|
|
}
|
|
#endif
|
|
|
|
pVWData->SD_PITCH = (WORD)(pGbl->lPitch);
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: RGBtoYCrCb
|
|
*
|
|
* DESCRIPTION: Conversion equations are from page 42 of the second edition
|
|
* of "Video Demystified" by Keith Jack
|
|
*
|
|
****************************************************************************/
|
|
|
|
STATIC DWORD INLINE
|
|
RGBtoYCbCr ( DWORD dwRGB )
|
|
{
|
|
long Y, Cr, Cb;
|
|
long r, g, b;
|
|
|
|
|
|
r = (dwRGB & 0xF800) >> 8;
|
|
g = (dwRGB & 0x07E0) >> 3;
|
|
b = (dwRGB & 0x001F) << 3;
|
|
|
|
Y = ( 77 * r + 150 * g + 29 * b) / 256;
|
|
// max value of Y from this is if r, g & b are all 255 then Y = 255
|
|
// min value of Y from this is if r, g & b are all 0 then Y = 0
|
|
// so don't need to clamp Y
|
|
|
|
Cb = (-44 * r - 87 * g + 131 * b) / 256 + 128;
|
|
// max value of Cb is if r & g are 0 and b is 255 then Cb = 258
|
|
// min value of Cb is if r & g are 255 and b is 0 then Cb = -2
|
|
// so need to clamp Cb between 0 and 255
|
|
if (255 < Cb)
|
|
Cb = 255;
|
|
else if (0 > Cb)
|
|
Cb = 0;
|
|
|
|
Cr = (131 * r - 110 * g - 21 * b) / 256 + 128;
|
|
// max value of Cr is if r is 255 and g & b are 0 then Cr = 258
|
|
// min value of Cr is if r is 0 and g & b are 255 then Cr = -2
|
|
// so need to clamp Cr between 0 and 255
|
|
if (255 < Cr)
|
|
Cr = 255;
|
|
else if (0 > Cr)
|
|
Cr = 0;
|
|
|
|
return (((Y & 0xFF) << 16) | ((Cb & 0xFF) << 8) | ((Cr & 0xFF)));
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: DetermineVWColorKeyData
|
|
*
|
|
* DESCRIPTION: Determines CLRKEY_MIN & CLRKEY_MAX or
|
|
* CHRMKEY_MIN & CHRMKEY_MAX
|
|
*
|
|
****************************************************************************/
|
|
|
|
STATIC VOID DetermineVWColorKeyData
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
#else
|
|
LPGLOBALDATA lpDDHALData,
|
|
#endif
|
|
DWORD dwOverlayFlags,
|
|
DWORD dwBitCount,
|
|
VWDATA *pVWData
|
|
)
|
|
{
|
|
if (FLG_COLOR_KEY & dwOverlayFlags)
|
|
{
|
|
// destination color key, uses color key on 5465
|
|
pVWData->CLRKEY_MIN = gdwColorKey;
|
|
pVWData->CLRKEY_MAX = gdwColorKey;
|
|
pVWData->CONTROL0 &= ~VW_OCCLUDE_MASK;
|
|
pVWData->CONTROL0 |= (COLOR_KEY << OCCLUDE_SHIFT);
|
|
}
|
|
else if (FLG_SRC_COLOR_KEY & dwOverlayFlags)
|
|
{
|
|
PVGAR pREG = (PVGAR)lpDDHALData->RegsAddress;
|
|
BYTE r,g,b;
|
|
|
|
// source color key, uses chroma key on 5465
|
|
switch (dwBitCount)
|
|
{
|
|
case 8:
|
|
// read colors from the DAC
|
|
LL8(grPalette_Read_Address,(BYTE)(gdwSrcColorKeyLow & 0xFF));
|
|
r = pREG->grPalette_Data;
|
|
g = pREG->grPalette_Data;
|
|
b = pREG->grPalette_Data;
|
|
pVWData->CHRMKEY_MIN = ((DWORD)(r) << 16) |
|
|
((DWORD)(g) << 8) |
|
|
((DWORD)(b));
|
|
LL8(grPalette_Read_Address,(BYTE)(gdwSrcColorKeyHigh & 0xFF));
|
|
r = pREG->grPalette_Data;
|
|
g = pREG->grPalette_Data;
|
|
b = pREG->grPalette_Data;
|
|
pVWData->CHRMKEY_MAX = ((DWORD)(r) << 16) |
|
|
((DWORD)(g) << 8) |
|
|
((DWORD)(b));
|
|
break;
|
|
|
|
case 16:
|
|
|
|
if ((FLG_UYVY | FLG_YUY2) & dwOverlayFlags)
|
|
{
|
|
// Since we are currently using ITU 601 compliant YUV data
|
|
// convert color key to YCrCb
|
|
pVWData->CHRMKEY_MIN = RGBtoYCbCr(gdwSrcColorKeyLow);
|
|
pVWData->CHRMKEY_MAX = RGBtoYCbCr(gdwSrcColorKeyHigh);
|
|
}
|
|
else
|
|
{
|
|
// convert 5:6:5 to true color
|
|
pVWData->CHRMKEY_MIN = ((gdwSrcColorKeyLow & 0xF800) << 8) | // red
|
|
((gdwSrcColorKeyLow & 0x07E0) << 5) | // green
|
|
((gdwSrcColorKeyLow & 0x001F) << 3); // blue
|
|
pVWData->CHRMKEY_MAX = ((gdwSrcColorKeyHigh & 0xF800) << 8) | // red
|
|
((gdwSrcColorKeyHigh & 0x07E0) << 5) | // green
|
|
((gdwSrcColorKeyHigh & 0x001F) << 3); // blue
|
|
}
|
|
break;
|
|
|
|
case 24:
|
|
case 32:
|
|
pVWData->CHRMKEY_MIN = (gdwSrcColorKeyLow & 0x00FFFFFF);
|
|
pVWData->CHRMKEY_MAX = (gdwSrcColorKeyHigh & 0x00FFFFFF);
|
|
break;
|
|
}
|
|
pVWData->CONTROL0 &= ~VW_OCCLUDE_MASK;
|
|
pVWData->CONTROL0 |= (CHROMA_KEY << OCCLUDE_SHIFT);
|
|
}
|
|
else
|
|
{
|
|
pVWData->CONTROL0 &= ~VW_OCCLUDE_MASK;
|
|
pVWData->CONTROL0 |= (NO_OCCLUSION << OCCLUDE_SHIFT);
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: ComputeVWFifoThreshold
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
****************************************************************************/
|
|
|
|
static INLINE VOID ComputeVWFifoThreshold
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
#else
|
|
LPGLOBALDATA lpDDHALData,
|
|
#endif
|
|
VWDATA *pVWData
|
|
)
|
|
{
|
|
PVGAR pREG = (PVGAR)lpDDHALData->RegsAddress;
|
|
|
|
|
|
pREG->grDisplay_Threshold_and_Tiling =
|
|
(pREG->grDisplay_Threshold_and_Tiling & 0xFFC0) |
|
|
(gsProgRegs.DispThrsTiming & 0x003F);
|
|
|
|
pVWData->FIFO_THRSH = gsProgRegs.VW0_FIFO_THRSH;
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: PanOverlay1_Init
|
|
*
|
|
* DESCRIPTION: Save data for panning overlay window one.
|
|
* Clip lpVideoRect to panning viewport.
|
|
*
|
|
****************************************************************************/
|
|
|
|
static INLINE VOID PanOverlay1_Init
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
#endif
|
|
LPRECTL lpVideoRect,
|
|
LPRECTL lpOverlaySrc,
|
|
LPRECTL lpOverlayDest
|
|
)
|
|
{
|
|
// This is not necessary on Laguna since we can't pan the screen
|
|
|
|
// clip left edge of destination
|
|
if (0 > (lpVideoRect->left = lpOverlayDest->left))
|
|
lpVideoRect->left = 0;
|
|
|
|
// clip right edge of destination
|
|
#ifdef WINNT_VER40
|
|
if ((LONG)ppdev->cxScreen < (lpVideoRect->right = lpOverlayDest->right))
|
|
lpVideoRect->right = (LONG)ppdev->cxScreen;
|
|
#else
|
|
if ((LONG)pPDevice->deWidth < (lpVideoRect->right = lpOverlayDest->right))
|
|
lpVideoRect->right = (LONG)pPDevice->deWidth;
|
|
#endif
|
|
|
|
// clip top edge of destination
|
|
if (0 > (lpVideoRect->top = lpOverlayDest->top))
|
|
lpVideoRect->top = 0;
|
|
|
|
// clip bottom edge of destination
|
|
#ifdef WINNT_VER40
|
|
if ((LONG)ppdev->cyScreen < (lpVideoRect->bottom = lpOverlayDest->bottom))
|
|
lpVideoRect->bottom = (LONG)ppdev->cyScreen;
|
|
#else
|
|
if ((LONG)pPDevice->deHeight < (lpVideoRect->bottom = lpOverlayDest->bottom))
|
|
lpVideoRect->bottom = (LONG)pPDevice->deHeight;
|
|
#endif
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: RegInitVideoVW
|
|
*
|
|
* DESCRIPTION: This function is called to program the video format and
|
|
* the physical offset of the Video Window video data
|
|
* in the frame buffer.
|
|
*
|
|
****************************************************************************/
|
|
|
|
STATIC BOOL RegInitVideoVW
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
DWORD dwVWIndex,
|
|
PDD_SURFACE_LOCAL lpSurface
|
|
#else
|
|
DWORD dwVWIndex,
|
|
LPDDRAWI_DDRAWSURFACE_LCL lpSurface,
|
|
LPGLOBALDATA lpDDHALData
|
|
#endif
|
|
)
|
|
{
|
|
LP_SURFACE_DATA lpSurfaceData = GET_SURFACE_DATA_PTR(lpSurface);
|
|
VWDATA VWData;
|
|
BOOL bOverlayTooSmall = FALSE;
|
|
DWORD dwFourcc;
|
|
LONG lPitch;
|
|
DWORD dwBitCount;
|
|
RECTL rVideoRect;
|
|
PVGAR pREG = (PVGAR)lpDDHALData->RegsAddress;
|
|
#if DDRAW_COMPAT >= 50
|
|
DWORD dwSrfFlags = FALSE;
|
|
#endif
|
|
DWORD width;
|
|
//////#ifndef WINNT_VER40
|
|
PDD_ATTACHLIST lpSurfaceAttached;
|
|
LP_SURFACE_DATA lpSurfaceDataTmp;
|
|
//////#endif
|
|
|
|
ASSERT(dwNumVideoWindows > dwVWIndex);
|
|
|
|
// Determine the format of the video data
|
|
if (lpSurface->dwFlags & DDRAWISURF_HASPIXELFORMAT)
|
|
{
|
|
GetFormatInfo(&(lpSurface->lpGbl->ddpfSurface), &dwFourcc, &dwBitCount);
|
|
}
|
|
else
|
|
{
|
|
dwBitCount = BITSPERPIXEL;
|
|
if (16 == dwBitCount)
|
|
dwFourcc = BI_BITFIELDS; // 5:6:5
|
|
else
|
|
dwFourcc = BI_RGB; // 8bpp, 5:5:5, 24bpp & 32bpp
|
|
}
|
|
|
|
#ifdef WINNT_VER40
|
|
PanOverlay1_Init(ppdev,&rVideoRect,&grOverlaySrc[dwVWIndex],&grOverlayDest[dwVWIndex]);
|
|
#else
|
|
PanOverlay1_Init(&rVideoRect,&grOverlaySrc[dwVWIndex],&grOverlayDest[dwVWIndex]);
|
|
#endif
|
|
|
|
// rVideoRect is now adjusted and clipped to the panning viewport.
|
|
// Disable overlay if totally clipped by viewport.
|
|
if (((rVideoRect.right - rVideoRect.left) <= 0) ||
|
|
((rVideoRect.bottom- rVideoRect.top ) <= 0))
|
|
{
|
|
#ifdef WINNT_VER40
|
|
DisableOverlay(ppdev, dwVWIndex);
|
|
#else
|
|
DisableOverlay(lpDDHALData,dwVWIndex);
|
|
#endif
|
|
return TRUE;
|
|
}
|
|
|
|
memset(&VWData, 0, sizeof(VWData));
|
|
|
|
lPitch = lpSurface->lpGbl->lPitch;
|
|
|
|
#ifdef WINNT_VER40
|
|
ComputeVWZoomCodes(ppdev, dwVWIndex, &VWData);
|
|
#else
|
|
ComputeVWZoomCodes(dwVWIndex, &VWData);
|
|
#endif
|
|
|
|
ComputeVWPositionData(&rVideoRect,
|
|
&grOverlaySrc[dwVWIndex],
|
|
&grOverlayDest[dwVWIndex],
|
|
lpSurface->lpGbl,
|
|
#ifndef WINNT_VER40
|
|
lpDDHALData,
|
|
#endif
|
|
dwBitCount,
|
|
&VWData,
|
|
FOURCC_YUVPLANAR == dwFourcc);
|
|
|
|
lpSurfaceData->dwOverlayOffset = //This offset will be used in FlipOverlay
|
|
VWData.PSD_STRT_ADDR - // and VPE
|
|
lpSurface->lpGbl->fpVidMem
|
|
#ifndef WINNT_VER40
|
|
+ lpDDHALData->ScreenAddress
|
|
#endif
|
|
;
|
|
|
|
/////////#ifndef WINNT_VER40
|
|
|
|
//Update all the attached surfaces
|
|
lpSurfaceAttached = lpSurface->lpAttachListFrom;
|
|
|
|
while( lpSurfaceAttached)
|
|
{
|
|
if(lpSurfaceAttached->lpAttached)
|
|
{
|
|
lpSurfaceDataTmp = GET_SURFACE_DATA_PTR(lpSurfaceAttached->lpAttached);
|
|
lpSurfaceDataTmp->dwOverlayOffset = lpSurfaceData->dwOverlayOffset;
|
|
lpSurfaceAttached = lpSurfaceAttached->lpAttached->lpAttachListFrom;
|
|
}
|
|
else
|
|
break;
|
|
|
|
}
|
|
|
|
lpSurfaceAttached = lpSurface->lpAttachList;
|
|
|
|
while( lpSurfaceAttached)
|
|
{
|
|
if(lpSurfaceAttached->lpAttached)
|
|
{
|
|
lpSurfaceDataTmp = GET_SURFACE_DATA_PTR(lpSurfaceAttached->lpAttached);
|
|
lpSurfaceDataTmp->dwOverlayOffset = lpSurfaceData->dwOverlayOffset;
|
|
lpSurfaceAttached = lpSurfaceAttached->lpAttached->lpAttachList;
|
|
}
|
|
else
|
|
break;
|
|
|
|
}
|
|
|
|
//////////#endif
|
|
|
|
#if ENABLE_MIRRORING
|
|
// Mirror Video Windows support.
|
|
if (bIsVWMirrored[dwVWIndex])
|
|
VWData.CONTROL0 |= VW_HMIRR_EN;
|
|
#endif
|
|
// Xing, isn't the memset above enough?
|
|
VWData.SSD_STRT_ADDR = 0L;
|
|
#if DDRAW_COMPAT >= 50
|
|
if (gwNotify & VPE_ON)
|
|
{
|
|
if((lpSurface->lpSurfMore->lpVideoPort != NULL)&&
|
|
(lpSurface->ddsCaps.dwCaps & DDSCAPS_VIDEOPORT))
|
|
{
|
|
if((lpSurface->lpSurfMore->dwOverlayFlags & DDOVER_BOB)
|
|
&&(lpSurface->lpSurfMore->lpVideoPort->ddvpInfo.dwVPFlags
|
|
& DDVP_INTERLEAVE))
|
|
{
|
|
dwSrfFlags = DDOVER_BOB;
|
|
}
|
|
else if((lpSurface->lpSurfMore->lpVideoPort->ddvpInfo.dwVPFlags
|
|
&DDVP_AUTOFLIP)
|
|
&&(lpSurface->lpSurfMore->dwOverlayFlags & DDOVER_AUTOFLIP)
|
|
&& (lpSurface->lpAttachListFrom != NULL)
|
|
&& (lpSurface->lpAttachListFrom->lpAttached != NULL))
|
|
{
|
|
dwSrfFlags = DDOVER_AUTOFLIP;
|
|
}
|
|
}
|
|
}
|
|
|
|
if((dwSrfFlags & DDOVER_BOB)
|
|
||(!dwSrfFlags
|
|
&&(lpSurface->lpSurfMore->dwOverlayFlags & DDOVER_INTERLEAVED)))
|
|
{
|
|
RECTL rcTemp;
|
|
rcTemp = grOverlaySrc[dwVWIndex];
|
|
grOverlaySrc[dwVWIndex].top >>=1;
|
|
grOverlaySrc[dwVWIndex].bottom >>=1; //use half source size to
|
|
VWData.CONTROL1 &= ~VW_YShrinkEn; //find zoom factor
|
|
ComputeVWZoomCodes(dwVWIndex, &VWData);
|
|
grOverlaySrc[dwVWIndex] = rcTemp;
|
|
|
|
VWData.SD_PITCH <<= 1;
|
|
VWData.CONTROL0 &= ~0x30000ul;
|
|
if(dwSrfFlags & DDOVER_BOB)
|
|
{
|
|
VWData.SSD_STRT_ADDR = VWData.PSD_STRT_ADDR + lPitch;
|
|
VWData.CONTROL0 |= 0x20000ul; //enable buffer two
|
|
}
|
|
|
|
}
|
|
else if(dwSrfFlags & DDOVER_AUTOFLIP)
|
|
{
|
|
|
|
VWData.SSD_STRT_ADDR = lpSurfaceData->dwAutoBaseAddr2 +
|
|
lpSurfaceData->dwOverlayOffset;
|
|
if( VWData.PSD_STRT_ADDR == VWData.SSD_STRT_ADDR )
|
|
{
|
|
VWData.PSD_STRT_ADDR = lpSurfaceData->dwAutoBaseAddr1 +
|
|
lpSurfaceData->dwOverlayOffset;
|
|
}
|
|
|
|
VWData.CONTROL0 &= ~0x30000ul;
|
|
VWData.CONTROL0 |= 0x20000ul; //enable the second buffer
|
|
if(!(lpSurface->lpSurfMore->dwOverlayFlags & DDOVER_BOB))
|
|
{
|
|
//For non-smooth-interlaced auto-flip these two address need
|
|
// to be switched. HW BUG
|
|
DWORD dwTmp = VWData.PSD_STRT_ADDR;
|
|
VWData.PSD_STRT_ADDR = VWData.SSD_STRT_ADDR;
|
|
VWData.SSD_STRT_ADDR = dwTmp;
|
|
}
|
|
}
|
|
|
|
if(lpSurface->lpSurfMore->dwOverlayFlags & DDOVER_BOB)
|
|
{
|
|
BOOL fSDAHalf = TRUE;
|
|
#if ENABLE_MIRRORING
|
|
if (lpInput->overlayFX.dwDDFX & DDOVERFX_MIRRORLEFTRIGHT)
|
|
fSDAHalf = !fSDAHalf;
|
|
#endif
|
|
if(VWData.VACCUM_STP >= 0x8000ul)
|
|
fSDAHalf = !fSDAHalf;
|
|
|
|
if(fSDAHalf)
|
|
{
|
|
VWData.VACCUM_SDA = 0x8000ul;
|
|
VWData.VACCUM_SDB = 0ul;
|
|
}
|
|
else
|
|
{
|
|
VWData.VACCUM_SDA = 0ul;
|
|
VWData.VACCUM_SDB = 0x8000ul;
|
|
}
|
|
VWData.CONTROL0 |= 0x8ul;
|
|
}
|
|
#endif
|
|
|
|
if (lpSurfaceData->dwOverlayFlags & FLG_ENABLED)
|
|
VWData.CONTROL0 |= (VW_VWE | VW_ARM);
|
|
|
|
// set source data format
|
|
if (dwFourcc == BI_RGB)
|
|
{
|
|
if (dwBitCount == 16)
|
|
{
|
|
VWData.CONTROL0 |= (SD_RGB16_555 << SD_FRMT_SHIFT);
|
|
}
|
|
#if ENABLE_SD_RGB32
|
|
else if (dwBitCount == 32)
|
|
{
|
|
VWData.CONTROL0 |= (SD_RGB32 << SD_FRMT_SHIFT);
|
|
}
|
|
#endif
|
|
}
|
|
else if (dwFourcc == BI_BITFIELDS)
|
|
{
|
|
VWData.CONTROL0 |= (SD_RGB16_565 << SD_FRMT_SHIFT);
|
|
}
|
|
#if ENABLE_YUVPLANAR
|
|
else if (dwFourcc == FOURCC_YUVPLANAR)
|
|
{
|
|
VWData.CONTROL0 |= (SD_YUV420 << SD_FRMT_SHIFT);
|
|
}
|
|
#endif
|
|
else if (FOURCC_UYVY == dwFourcc)
|
|
{
|
|
VWData.CONTROL0 |= (SD_YUV422 << SD_FRMT_SHIFT);
|
|
}
|
|
|
|
#ifdef WINNT_VER40
|
|
DetermineVWColorKeyData(ppdev, lpSurfaceData->dwOverlayFlags, dwBitCount, &VWData);
|
|
#else
|
|
DetermineVWColorKeyData(lpDDHALData,lpSurfaceData->dwOverlayFlags, dwBitCount, &VWData);
|
|
#endif
|
|
|
|
#ifdef WINNT_VER40
|
|
ComputeVWFifoThreshold(ppdev, &VWData);
|
|
#else
|
|
ComputeVWFifoThreshold(lpDDHALData,&VWData);
|
|
#endif
|
|
|
|
// Now start programming the registers
|
|
#ifdef WINNT_VER40
|
|
WaitForVWArmToClear(ppdev, dwVWIndex);
|
|
#else
|
|
WaitForVWArmToClear(lpDDHALData, dwVWIndex);
|
|
#endif
|
|
ASSERT(! (pREG->VideoWindow[dwVWIndex].grVW_TEST0 & VW_PostImed));
|
|
|
|
LL16(VideoWindow[dwVWIndex].grVW_HSTRT, VWData.HSTRT);
|
|
LL16(VideoWindow[dwVWIndex].grVW_HEND, VWData.HEND);
|
|
LL16(VideoWindow[dwVWIndex].grVW_HSDSZ, VWData.HSDSZ);
|
|
LL32(VideoWindow[dwVWIndex].grVW_HACCUM_STP, VWData.HACCUM_STP);
|
|
LL32(VideoWindow[dwVWIndex].grVW_HACCUM_SD, VWData.HACCUM_SD);
|
|
LL16(VideoWindow[dwVWIndex].grVW_VSTRT, VWData.VSTRT);
|
|
LL16(VideoWindow[dwVWIndex].grVW_VEND, VWData.VEND);
|
|
LL32(VideoWindow[dwVWIndex].grVW_VACCUM_STP, VWData.VACCUM_STP);
|
|
LL32(VideoWindow[dwVWIndex].grVW_VACCUM_SDA, VWData.VACCUM_SDA);
|
|
LL32(VideoWindow[dwVWIndex].grVW_VACCUM_SDB, VWData.VACCUM_SDB);
|
|
LL32(VideoWindow[dwVWIndex].grVW_PSD_STRT_ADDR, VWData.PSD_STRT_ADDR);
|
|
LL32(VideoWindow[dwVWIndex].grVW_SSD_STRT_ADDR, VWData.SSD_STRT_ADDR);
|
|
#if ENABLE_YUVPLANAR
|
|
if (dwFourcc == FOURCC_YUVPLANAR)
|
|
{
|
|
LL32(VideoWindow[dwVWIndex].grVW_PSD_UVSTRT_ADDR, VWData.PSD_UVSTRT_ADDR);
|
|
LL32(VideoWindow[dwVWIndex].grVW_SSD_UVSTRT_ADDR, VWData.SSD_UVSTRT_ADDR);
|
|
}
|
|
#endif
|
|
LL16(VideoWindow[dwVWIndex].grVW_SD_PITCH, VWData.SD_PITCH);
|
|
|
|
if (FLG_SRC_COLOR_KEY & lpSurfaceData->dwOverlayFlags)
|
|
{
|
|
LL32(VideoWindow[dwVWIndex].grVW_CHRMKEY_MIN, VWData.CHRMKEY_MIN);
|
|
LL32(VideoWindow[dwVWIndex].grVW_CHRMKEY_MAX, VWData.CHRMKEY_MAX);
|
|
}
|
|
else if (FLG_COLOR_KEY & lpSurfaceData->dwOverlayFlags)
|
|
{
|
|
LL32(VideoWindow[dwVWIndex].grVW_CLRKEY_MIN, VWData.CLRKEY_MIN);
|
|
LL32(VideoWindow[dwVWIndex].grVW_CLRKEY_MAX, VWData.CLRKEY_MAX);
|
|
}
|
|
|
|
LL16(VideoWindow[dwVWIndex].grVW_FIFO_THRSH, VWData.FIFO_THRSH);
|
|
LL32(VideoWindow[dwVWIndex].grVW_CONTROL1, VWData.CONTROL1);
|
|
|
|
// fix for PDR #10815
|
|
// if src width >= 1536 bytes (or 3072 bytes for shrink)
|
|
// disable vertical interpolation
|
|
width = (grOverlaySrc[dwVWIndex].right - grOverlaySrc[dwVWIndex].left) * (dwBitCount / 8);
|
|
if (VW_YShrinkEn & VWData.CONTROL1)
|
|
width /= 2;
|
|
if (width >= 1536)
|
|
{
|
|
// set replication bit in TEST0 reg
|
|
pREG->VideoWindow[dwVWIndex].grVW_TEST0 |= VWVRepEnable;
|
|
}
|
|
else
|
|
{
|
|
// clear replication bit in TEST0 reg
|
|
pREG->VideoWindow[dwVWIndex].grVW_TEST0 &= ~VWVRepEnable;
|
|
}
|
|
|
|
// write last to arm
|
|
LL32(VideoWindow[dwVWIndex].grVW_CONTROL0, VWData.CONTROL0);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: RegMoveVideoVW
|
|
*
|
|
* DESCRIPTION: This function is called to move the video window that has
|
|
* already been programed.
|
|
*
|
|
****************************************************************************/
|
|
|
|
STATIC VOID RegMoveVideoVW
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
DWORD dwVWIndex,
|
|
PDD_SURFACE_LOCAL lpSurface
|
|
#else
|
|
DWORD dwVWIndex,
|
|
LPDDRAWI_DDRAWSURFACE_LCL lpSurface,
|
|
LPGLOBALDATA lpDDHALData
|
|
#endif
|
|
)
|
|
{
|
|
LP_SURFACE_DATA lpSurfaceData = GET_SURFACE_DATA_PTR(lpSurface);
|
|
VWDATA VWData;
|
|
DWORD dwFourcc;
|
|
LONG lPitch;
|
|
DWORD dwBitCount;
|
|
RECTL rVideoRect;
|
|
PVGAR pREG = (PVGAR)lpDDHALData->RegsAddress;
|
|
|
|
|
|
ASSERT(dwNumVideoWindows > dwVWIndex);
|
|
|
|
// Determine the format of the video data
|
|
if (lpSurface->dwFlags & DDRAWISURF_HASPIXELFORMAT)
|
|
{
|
|
GetFormatInfo (&(lpSurface->lpGbl->ddpfSurface), &dwFourcc, &dwBitCount);
|
|
}
|
|
else
|
|
{
|
|
dwBitCount = BITSPERPIXEL;
|
|
if (16 == dwBitCount)
|
|
dwFourcc = BI_BITFIELDS; // 5:6:5
|
|
else
|
|
dwFourcc = BI_RGB; // 8bpp, 5:5:5, 24bpp & 32bpp
|
|
}
|
|
|
|
#ifdef WINNT_VER40
|
|
PanOverlay1_Init(ppdev,&rVideoRect,&grOverlaySrc[dwVWIndex],&grOverlayDest[dwVWIndex]);
|
|
#else
|
|
PanOverlay1_Init(&rVideoRect,&grOverlaySrc[dwVWIndex],&grOverlayDest[dwVWIndex]);
|
|
#endif
|
|
|
|
// rVideoRect is now adjusted and clipped to the panning viewport.
|
|
// Disable overlay if totally clipped by viewport.
|
|
if (((rVideoRect.right - rVideoRect.left) <= 0) ||
|
|
((rVideoRect.bottom- rVideoRect.top ) <= 0))
|
|
{
|
|
#ifdef WINNT_VER40
|
|
DisableOverlay(ppdev, dwVWIndex);
|
|
#else
|
|
DisableOverlay(lpDDHALData, dwVWIndex);
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
memset(&VWData, 0, sizeof(VWData));
|
|
VWData.CONTROL0 = pREG->VideoWindow[dwVWIndex].grVW_CONTROL0;
|
|
if (lpSurfaceData->dwOverlayFlags & FLG_ENABLED)
|
|
VWData.CONTROL0 |= VW_VWE;
|
|
VWData.CONTROL0 |= VW_ARM;
|
|
|
|
lPitch = lpSurface->lpGbl->lPitch;
|
|
|
|
// if shrink in x, set shrink x by 2 bit in CONTROL0
|
|
// shrink in y is okay, because that bit is in CONTROL1 and
|
|
// we aren't touching CONTROL1 here
|
|
if ((grOverlayDest[dwVWIndex].right - grOverlayDest[dwVWIndex].left) <
|
|
(grOverlaySrc[dwVWIndex].right - grOverlaySrc[dwVWIndex].left))
|
|
{
|
|
VWData.CONTROL0 |= VW_XShrinkBy2;
|
|
}
|
|
|
|
ComputeVWPositionData(&rVideoRect,
|
|
&grOverlaySrc[dwVWIndex],
|
|
&grOverlayDest[dwVWIndex],
|
|
lpSurface->lpGbl,
|
|
#ifndef WINNT_VER40
|
|
lpDDHALData,
|
|
#endif
|
|
dwBitCount,
|
|
&VWData,
|
|
FOURCC_YUVPLANAR == dwFourcc);
|
|
|
|
#if ENABLE_MIRRORING
|
|
if (bIsVWMirrored[dwVWIndex])
|
|
VWData.CONTROL0 |= VW_HMIRR_EN;
|
|
#endif
|
|
// Xing, isn't the memset above enough?
|
|
VWData.SSD_STRT_ADDR = 0;
|
|
#if DDRAW_COMPAT >= 50
|
|
if( gwNotify & VPE_ON)
|
|
{
|
|
if(lpSurface->lpSurfMore->lpVideoPort != NULL)
|
|
{
|
|
if((lpSurface->lpSurfMore->lpVideoPort->ddvpInfo.dwVPFlags
|
|
&DDVP_AUTOFLIP)
|
|
&& (lpSurface->lpSurfMore->dwOverlayFlags & DDOVER_AUTOFLIP)
|
|
&& (lpSurface->lpAttachListFrom != NULL)
|
|
&& (lpSurface->lpAttachListFrom->lpAttached != NULL))
|
|
{
|
|
|
|
VWData.SSD_STRT_ADDR = lpSurfaceData->dwAutoBaseAddr2 +
|
|
lpSurfaceData->dwOverlayOffset;
|
|
if( VWData.PSD_STRT_ADDR == VWData.SSD_STRT_ADDR )
|
|
{
|
|
VWData.PSD_STRT_ADDR = lpSurfaceData->dwAutoBaseAddr1 +
|
|
lpSurfaceData->dwOverlayOffset;
|
|
}
|
|
VWData.CONTROL0 &= ~0x30000ul;
|
|
VWData.CONTROL0 |= 0x20000ul; //enable the second buffer
|
|
|
|
if(!(lpSurface->lpSurfMore->dwOverlayFlags & DDOVER_BOB))
|
|
{
|
|
//For non-smooth-interlaced auto-flip these two address need
|
|
// to be switched. HW BUG
|
|
DWORD dwTmp = VWData.PSD_STRT_ADDR;
|
|
VWData.PSD_STRT_ADDR = VWData.SSD_STRT_ADDR;
|
|
VWData.SSD_STRT_ADDR = dwTmp;
|
|
}
|
|
}
|
|
else if((lpSurface->lpSurfMore->dwOverlayFlags & DDOVER_BOB)
|
|
&&(lpSurface->lpSurfMore->lpVideoPort->ddvpInfo.dwVPFlags
|
|
& DDVP_INTERLEAVE))
|
|
{
|
|
VWData.SSD_STRT_ADDR = VWData.PSD_STRT_ADDR + lPitch;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// Now start programming the registers
|
|
ASSERT(! (pREG->VideoWindow[dwVWIndex].grVW_TEST0 & VW_PostImed));
|
|
#ifdef WINNT_VER40
|
|
WaitForVWArmToClear(ppdev, dwVWIndex);
|
|
#else
|
|
WaitForVWArmToClear(lpDDHALData, dwVWIndex);
|
|
#endif
|
|
|
|
LL16(VideoWindow[dwVWIndex].grVW_HSTRT, VWData.HSTRT);
|
|
LL16(VideoWindow[dwVWIndex].grVW_HEND, VWData.HEND);
|
|
LL16(VideoWindow[dwVWIndex].grVW_HSDSZ, VWData.HSDSZ);
|
|
LL16(VideoWindow[dwVWIndex].grVW_VSTRT, VWData.VSTRT);
|
|
LL16(VideoWindow[dwVWIndex].grVW_VEND, VWData.VEND);
|
|
LL32(VideoWindow[dwVWIndex].grVW_PSD_STRT_ADDR, VWData.PSD_STRT_ADDR);
|
|
LL32(VideoWindow[dwVWIndex].grVW_SSD_STRT_ADDR, VWData.SSD_STRT_ADDR);
|
|
#if ENABLE_YUVPLANAR
|
|
if (dwFourcc == FOURCC_YUVPLANAR)
|
|
{
|
|
LL32(VideoWindow[dwVWIndex].grVW_PSD_UVSTRT_ADDR, VWData.PSD_UVSTRT_ADDR);
|
|
LL32(VideoWindow[dwVWIndex].grVW_SSD_UVSTRT_ADDR, VWData.SSD_UVSTRT_ADDR);
|
|
}
|
|
#endif
|
|
LL16(VideoWindow[dwVWIndex].grVW_SD_PITCH, VWData.SD_PITCH);
|
|
LL32(VideoWindow[dwVWIndex].grVW_CONTROL0, VWData.CONTROL0);
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: ChipIOReadBWRegs
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
****************************************************************************/
|
|
|
|
BOOL ChipIOReadBWRegs
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
#else
|
|
LPGLOBALDATA lpDDHALData,
|
|
#endif
|
|
LPBWREGS pBWRegs
|
|
)
|
|
{
|
|
PVGAR pREG = (PVGAR)lpDDHALData->RegsAddress;
|
|
|
|
|
|
#ifdef WINNT_VER40
|
|
pBWRegs->BCLK_Mult = pREG->grBCLK_Multiplier;
|
|
#else
|
|
pBWRegs->BCLK_Mult = pREG->grBCLK_numerator;
|
|
#endif
|
|
pBWRegs->MISCOutput = pREG->grMISC;
|
|
pBWRegs->VCLK3Denom = pREG->grSRE;
|
|
pBWRegs->VCLK3Num = pREG->grSR1E;
|
|
pBWRegs->DispThrsTiming = pREG->grDisplay_Threshold_and_Tiling;
|
|
pBWRegs->RIFControl = pREG->grRIF_CONTROL;
|
|
pBWRegs->GfVdFormat = pREG->grFormat;
|
|
|
|
#ifdef WINNT_VER40
|
|
pBWRegs->BCLK_Denom = pREG->grBCLK_Denominator;
|
|
#else
|
|
pBWRegs->BCLK_Denom = pREG->grBCLK_denom;
|
|
#endif
|
|
pBWRegs->Control2 = pREG->grCONTROL2;
|
|
pBWRegs->CR1 = pREG->grCR1;
|
|
pBWRegs->CR1E = pREG->grCR1E;
|
|
|
|
#if ENABLE_256_BYTE_FETCH
|
|
// if we are disabling 256 byte fetch when overlay or videoport
|
|
// surfaces are created, then wipe out the 256 byte fetch related
|
|
// bits in CONTROL2
|
|
// clear MONO_SAFETY_256 & BYTE_REQ_256 bits of CONTROL2 register
|
|
pBWRegs->Control2 &= ~(MONO_SAFETY_256 | BYTE_REQ_256);
|
|
#endif
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
#ifdef USE_OLD_BWEQ
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: KillOverlay
|
|
*
|
|
* DESCRIPTION: Disable overlay in the following cases
|
|
*
|
|
****************************************************************************/
|
|
|
|
BOOL KillOverlay
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
#endif
|
|
WORD wScreenX,
|
|
UINT uScreenDepth
|
|
)
|
|
{
|
|
BWREGS bwregs;
|
|
DWORD dwMCLK, dwVCLK;
|
|
|
|
#ifdef WINNT_VER40
|
|
if(!ChipIOReadBWRegs(ppdev, &bwregs))
|
|
#else
|
|
if(!ChipIOReadBWRegs(&bwregs))
|
|
#endif
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
if(!ChipCalcMCLK(&bwregs, &dwMCLK))
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
if(!ChipCalcVCLK(&bwregs, &dwVCLK))
|
|
{
|
|
return TRUE;
|
|
}
|
|
if(dwMCLK < 75000000)
|
|
{
|
|
if(uScreenDepth == 32 )
|
|
{
|
|
if(wScreenX == 640 )
|
|
{
|
|
if(dwVCLK > 32000000)
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
return FALSE;
|
|
|
|
}
|
|
#endif // USE_OLD_BWEQ
|
|
|
|
#endif // WINNT_VER35
|
|
|