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

4303 lines
136 KiB

/***************************************************************************
*
* ******************************************
* * Copyright (c) 1996, Cirrus Logic, Inc. *
* * All Rights Reserved *
* ******************************************
*
* PROJECT: Laguna I (CL-GD546x) -
*
* FILE: ddblt.c
*
* AUTHOR: Benny Ng
*
* DESCRIPTION:
* This module implements the DirectDraw BLT components
* for the Laguna NT driver.
*
* MODULES:
* WINNT WIN95
* DdGetBltStatus() GetBltStatus32()
* SetGamma()
* DrvStretch64() DrvStretch64()
* DrvStretch62() DrvStretch62()
* DdBlt() Blt32()
* DupColor() DupColor()
* EnoughFifoForBlt() EnoughFifoForBlt()
* RGBResizeBOF64()
* RGB16ShrinkBOF64()
*
* REVISION HISTORY:
* 7/12/96 Benny Ng Initial version
*
* $Log: X:/log/laguna/ddraw/src/ddblt.c $
*
* Rev 1.25 Feb 16 1998 16:20:02 frido
* Fixed a NT 4.0 compilation bug (lpData is called lpGbl).
*
* Rev 1.24 14 Jan 1998 06:18:58 eleland
*
* support for display list page-flipping: calls to UpdateFlipStatus are
* thru pointer to function pfnUpdateFlipStatus
*
* Rev 1.23 07 Jan 1998 17:45:30 xcong
* Fix the change for WIN95 which breaks NT in DUP_COLOR macro.
*
* Rev 1.22 06 Jan 1998 14:31:28 xcong
* Change all the macros to use lpDDHALData instead of pDriverData.
*
* Rev 1.21 06 Jan 1998 11:44:42 xcong
* Change pDriverData into local lpDDHALData for multi-monitor support.
*
* Rev 1.20 03 Oct 1997 14:46:50 RUSSL
* Initial changes for use of hw clipped blts
* All changes wrapped in #if ENABLE_CLIPPEDBLTS/#endif blocks and
* ENABLE_CLIPPEDBLTS defaults to 0 (so the code is disabled)
*
* Rev 1.19 01 Oct 1997 17:44:24 eleland
* added check in blt32() to detect blts to host texture surfaces and
* punt those blts back to the ddraw HEL
*
* Rev 1.18 30 Jul 1997 20:56:22 RANDYS
*
* Added code to check for zero extent blts
*
* Rev 1.17 18 Jul 1997 10:23:34 RUSSL
* Modified StretchColor to use function ptr to blt routines rather than
* directly program registers. This is for compatiblity with display lists
*
* Rev 1.16 14 Jul 1997 14:49:32 RUSSL
* Modified BltInit's initialization of pfnDrvStrBlt for Win95
*
* Rev 1.15 08 Jul 1997 11:15:20 RUSSL
* Removed an ASSERT that is no longer valid in StretchColor
*
* Rev 1.14 07 Jul 1997 10:57:14 dzenz
* Added check of DRVSEM_DISPLAY_LIST semaphore to ascertain if
* qmRequestDirectAccess needs to be called.
*
* Rev 1.13 08 Apr 1997 12:17:06 einkauf
* WINNT_VER40 affected only: add SYNC_W_3D to coordinate MCD/2D HW access
*
* Rev 1.12 03 Apr 1997 15:24:48 RUSSL
* Added pfnDrvDstMBlt global var
* Added initializing pfnDrvDstMBlt in BltInit
* Modified DDBLT_DEPTHFILL case in Blt32 to blt based on surface colordepth
* it was clearing 16bit zbuffers in 32bit modes with pixel blts so would
* wipe out everything to the right of the actual zbuffer
* Fixes at least PDRs #9152, 9150 & 8789 (maybe others as well)
*
* Rev 1.11 01 Apr 1997 09:15:24 RUSSL
* Added calls to SyncWithQueueManager in GetBltStatus32
*
* Rev 1.10 26 Mar 1997 14:08:22 RUSSL
* Added pfnDrvSrcMBlt global var
* Added initializing pfnDrvSrcMBlt in BltInit
* Moved sync with queue manager in Blt32 in front of updateFlipStatus since
* updateFlipStatus may access the hardware
*
* Rev 1.9 18 Mar 1997 07:50:24 bennyn
* Resolved NT compiling error by #ifdef queue manager sync call
*
* Rev 1.8 12 Mar 1997 15:02:02 RUSSL
* replaced a block of includes with include of precomp.h for
* precompiled headers
*
* Rev 1.7 07 Mar 1997 12:51:38 RUSSL
* Modified DDRAW_COMPAT usage
*
* Rev 1.6 03 Mar 1997 10:32:34 eleland
* modified queue manager sync call to check 2d display list
* flag; removed USE_QUEUE_MANAGER #ifdef
*
* Rev 1.5 07 Feb 1997 13:22:36 KENTL
* Merged in Evan Leland's modifications to get Display List mode working:
* * include qmgr.h
* * Call qmRequesetDirectAcces() if 3D is busy (Disabled)
*
* Rev 1.4 21 Jan 1997 14:45:42 RUSSL
* Added include of ddinline.h
*
* Rev 1.3 15 Jan 1997 10:45:20 RUSSL
* Made Win95 function ptr vars global
* Moved following inline functions to bltP.h: DupZFill, DupColor &
* EnoughFifoForBlt
*
* Rev 1.2 13 Dec 1996 15:28:32 CRAIGN
* Added a Frido YUV move fix.
*
* Rev 1.1 25 Nov 1996 16:16:10 bennyn
* Fixed misc compiling errors for NT
*
* Rev 1.0 25 Nov 1996 14:43:02 RUSSL
* Initial revision.
*
* Rev 1.6 25 Nov 1996 14:40:02 RUSSL
* Yet another merge of winNT & win95 code
*
* Rev 1.5 25 Nov 1996 11:39:02 RUSSL
* Added TransparentStretch function
*
* Rev 1.4 18 Nov 1996 16:16:18 RUSSL
* Added file logging for DDraw entry points and register writes
*
* Rev 1.3 12 Nov 1996 09:42:02 CRAIGN
* Frido 1112s2 release... fixes TDDRAW case 26.
* Changed transparency for DDBLT_KEYDESTOVERRIDE to "not equal."
*
* Rev 1.2 11 Nov 1996 12:36:48 CRAIGN
* Frido 1112 release - added software color key stretch.
*
* Rev 1.1 06 Nov 1996 12:28:42 CRAIGN
* Frido 1106 - added check for rectangle movement.
*
* Rev 1.0 01 Nov 1996 13:09:30 RUSSL
* Merge WIN95 & WINNT code for Blt32
*
* Rev 1.9 01 Nov 1996 09:23:24 BENNYN
* Initial copy of shareable DD blt code
*
* COMBINED WINNT & WIN95 VERSIONS OF BLT CODE
*
* Rev 1.17 25 Oct 1996 11:55:54 RUSSL
* Forgot to remove the undef RDRAM_8BIT
*
* Rev 1.16 25 Oct 1996 11:50:16 RUSSL
* Added use of function pointers for all the short blt functions (like
* DrvDstBlt, DrvSrcBlt, etc.). Moved the short blt functions to a
* separate file (blt_dir.c). Modified DrvStretch64, DrvStretch62,
* RGBResizeBOF64 & RGB16ShrinkBOF64 to use the blt function pointers
* rather than directly call one of the short blt functions or write
* directly to the registers. This enables the short blt functions to
* be written as display lists rather than directly writing to the
* registers (in fact, that's whats in blt_dl.c)
*
* Added BltInit function to initialize the function pointers. BltInit
* needs to be called by buildHALInfo32.
*
* Rev 1.15 21 Oct 1996 11:56:08 RUSSL
* Added RGB16ShrinkBOF64 to handle 16bpp shrink blts on the 5464
* Now RGBResizeBOF64 only handles 8bpp stretches, 8bpp shrinks and
* 16bpp stretches on the 5464
* Added QFREE checking before blts in both RGB???BOF64 functions
*
* Rev 1.14 16 Oct 1996 16:10:40 RUSSL
* Added RGBResizeBOF64 to handle resize blts on 5464
* 8bpp stretches, 8bpp shrinks and 16bpp stretches ain't perfect but
* hopefully they're acceptable
* 16bpp shrinks are still broken
*
* Rev 1.13 07 Oct 1996 09:03:04 RUSSL
* Modified DDRAW_COMPAT_xx conditionally compiled stuff
*
* Rev 1.12 04 Oct 1996 11:39:10 KENTL
* Fixed PDR#6799 - playing two AVI's result in first window replicated in
* second. Changed the way Blt32 does an x-coordinate computation.
*
* Rev 1.11 04 Oct 1996 10:46:50 KENTL
* Added fix for 32bpp video bug: we were trying to do stretches in 32bpp,
* which a) is not supported in HW and b) was being interpreted as 16bpp
* which cause really lousy things to happen on the screen.
*
* Rev 1.9 04 Sep 1996 17:32:06 MARTINB
* Corrected shrink by 8 bug in odd sized mpegs.
* Corrected multiple mpeg sources corrupting working stroage.
*
* Rev 1.8 22 Aug 1996 10:37:14 MARTINB
* Corrected a number of QFREE check constants for the strech62 routines that
* were causing sound breakup on moving / resizing a video window.
*
* Rev 1.7 14 Aug 1996 16:53:20 MARTINB
* Yet another last minute fix to the last minute fix. This one fixes
* the banding in 422 video caused by doing the blt twice. The second time
* incorrectly !!
*
* Rev 1.6 13 Aug 1996 13:25:02 MARTINB
* Moved shrink rejection for 565/8bit formats to correct place in blt32 logic
*
* Rev 1.5 13 Aug 1996 08:31:12 MARTINB
* Added stretch routines for CL-GD5464 support
* renamed previous stretch logic to DrvStretch62.
*
* Rev 1.4 23 Jul 1996 11:20:04 KENTL
* Merged in Jeff Orts D3D integration changes.
* * Created DupZFill()
* * Added code to do Z-Fill blits.
*
* Rev 1.3 19 Jul 1996 16:24:38 CRAIGN
* Removed two int 3s that I left in the code.
*
* Rev 1.2 19 Jul 1996 09:31:20 CRAIGN
* Added workaround for Stretch Bug o' Death.
* Instead of doing SRAM blts to make sure that PTAG is set/reset,
* use a destcopy blt to PTAGFooPixel. This x/y coordinate is set by the
* display driver to be one pixel below the bottom of the screen (where the
* scratch buffer lives).
*
* Rev 1.1 15 Jul 1996 16:58:40 RUSSL
* Added support for DirectDraw 3.0
*
* Rev 1.0 26 Jun 1996 11:05:06 RUSSL
* Initial revision.
*
****************************************************************************
****************************************************************************/
/*----------------------------- INCLUDES ----------------------------------*/
#include "precomp.h"
// If WinNT 3.5 skip all the source code
#if defined WINNT_VER35 // WINNT_VER35
#else
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#ifndef WINNT_VER40 // Not WINNT_VER40
#include "flip.h"
#include "surface.h"
#include "blt.h"
#include "palette.h"
#include "qmgr.h"
#include "bltP.h"
#include "ddinline.h"
#include "ddshared.h"
#endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
/*----------------------------- DEFINES -----------------------------------*/
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#ifdef WINNT_VER40 // WINNT_VER40
// DBGBREAKPOINT();
#define AFPRINTF(n)
#define DBGLVL 1
#define DBGLVL1 1
#define DBGLVL2 1 // DrvSrcBlt & SrvDstBlt
#define DBGLVL3 1 // DrvStretchBlt
#define LGDEVID ppdev->dwLgDevID
#define OFFSCR_YUV_VAR ppdev->offscr_YUV
#define MEMCMP(A,B) memcmp(&ppdev->offscr_YUV.SrcRect, (A),(B))
#define DRAW_ENGINE_BUSY DrawEngineBusy(lpDDHALData)
#define ENOUGH_FIFO_FOR_BLT EnoughFifoForBlt(DRIVERDATA* lpDDHALData)
#define SET_GAMMA SetGamma(PDEV* ppdev, DRIVERDATA* lpDDHALData)
#define UPDATE_FLIP_STATUS(arg) vUpdateFlipStatus(&ppdev->flipRecord, (arg))
#define DRVSTRETCH64 DrvStretch64(PDEV* ppdev, DRIVERDATA* lpDDHALData,
#define DRVSTRETCH62 DrvStretch62(PDEV* ppdev, DRIVERDATA* lpDDHALData,
#define DUP_COLOR DupColor(PDEV* ppdev,
#define RGB_RESIZEBOF64 RGBResizeBOF64(PDEV* ppdev, DRIVERDATA* lpDDHALData,
#define RGB_16SHRINKBOF64 RGB16ShrinkBOF64(PDEV* ppdev, DRIVERDATA* lpDDHALData,
#define DUPZFILL DupZFill(PDEV* ppdev,
#define CALL_ENOUGH_FIFO_FOR_BLT EnoughFifoForBlt(lpDDHALData)
#define CALL_DELAY_9BIT_BLT(arg) ppdev->pfnDelay9BitBlt(ppdev,lpDDHALData, (arg))
#define CALL_EDGE_FILL_BLT(A,B,C,D,E,F) ppdev->pfnEdgeFillBlt(ppdev,lpDDHALData, (A),(B),(C),(D),(E),(F))
#define CALL_MEDGE_FILL_BLT(A,B,C,D,E,F) ppdev->pfnMEdgeFillBlt(ppdev,lpDDHALData, (A),(B),(C),(D),(E),(F))
#define CALL_DRV_DST_BLT(A,B,C,D) ppdev->pfnDrvDstBlt(ppdev,lpDDHALData, (A),(B),(C),(D))
#define CALL_DRV_DST_MBLT(A,B,C,D) ppdev->pfnDrvDstMBlt(ppdev,lpDDHALData, (A),(B),(C),(D))
#define CALL_DRV_SRC_BLT(A,B,C,D,E,F) ppdev->pfnDrvSrcBlt(ppdev,lpDDHALData, (A),(B),(C),(D),(E),(F))
#define CALL_DRV_STR_BLT(A) ppdev->pfnDrvStrBlt(ppdev,lpDDHALData, (A))
#define CALL_DRV_STR_MBLT(A) ppdev->pfnDrvStrMBlt(ppdev,lpDDHALData, (A))
#define CALL_DRV_STR_MBLTX(A) ppdev->pfnDrvStrMBltX(ppdev,lpDDHALData, (A))
#define CALL_DRV_STR_MBLTY(A) ppdev->pfnDrvStrMBltY(ppdev,lpDDHALData, (A))
#define CALL_DRV_STR_BLTY(A) ppdev->pfnDrvStrBltY(ppdev,lpDDHALData, (A))
#define CALL_DRV_STR_BLTX(A) ppdev->pfnDrvStrBltX(ppdev,lpDDHALData, (A))
#define CALL_DIR_DELAY_9BIT_BLT(arg) DIR_Delay9BitBlt(ppdev,lpDDHALData, (arg))
#define CALL_DIR_EDGE_FILL_BLT(A,B,C,D,E,F) DIR_EdgeFillBlt(ppdev,lpDDHALData, (A),(B),(C),(D),(E),(F))
#define CALL_DIR_MEDGE_FILL_BLT(A,B,C,D,E,F) DIR_MEdgeFillBlt(ppdev,lpDDHALData, (A),(B),(C),(D),(E),(F))
#define CALL_DIR_DRV_DST_BLT(A,B,C,D) DIR_DrvDstBlt(ppdev,lpDDHALData, (A),(B),(C),(D))
#define CALL_DIR_DRV_STR_BLT(A) DIR_DrvStrBlt(ppdev,lpDDHALData, (A))
#define CALL_DIR_DRV_STR_MBLT(A) DIR_DrvStrMBlt(ppdev,lpDDHALData, (A))
#define CALL_DIR_DRV_STR_MBLTX(A) DIR_DrvStrMBltX(ppdev,lpDDHALData, (A))
#define CALL_DIR_DRV_STR_MBLTY(A) DIR_DrvStrMBltY(ppdev,lpDDHALData, (A))
#define CALL_DRVSTRETCH64(A,B,C,D,E,F,G,H,I,J,K,L) DrvStretch64(ppdev,lpDDHALData,(A),(B),(C),(D),(E),(F),(G),(H),(I),(J),(K),(L))
#define CALL_DRVSTRETCH62(A,B,C,D,E,F,G,H,I,J,K,L) DrvStretch62(ppdev,lpDDHALData,(A),(B),(C),(D),(E),(F),(G),(H),(I),(J),(K),(L))
#define CALL_DUP_COLOR(A) DupColor(ppdev, (A))
#define CALL_RGB_RESIZEBOF64(A,B,C,D,E,F,G,H) RGBResizeBOF64(ppdev,lpDDHALData,(A),(B),(C),(D),(E),(F),(G),(H))
#define CALL_RGB_16SHRINKBOF64(A,B,C,D,E,F,G,H) RGB16ShrinkBOF64(ppdev,lpDDHALData,(A),(B),(C),(D),(E),(F),(G),(H))
#define CALL_DUPZFILL(A,B) DupZFill(ppdev, (A),(B))
#define STRETCHCOLOR StretchColor(PDEV* ppdev, DRIVERDATA* lpDDHALData,
#define CALL_STRETCHCOLOR(A,B,C,D,E,F,G,H,I) StretchColor(ppdev,lpDDHALData,(A),(B),(C),(D),(E),(F),(G),(H),(I))
#define TRANSPARENTSTRETCH TransparentStretch(PDEV* ppdev, DRIVERDATA* lpDDHALData,
#define CALL_TRANSPARENTSTRETCH(A,B,C,D,E,F,G,H,I) TransparentStretch(ppdev,lpDDHALData,(A),(B),(C),(D),(E),(F),(G),(H),(I))
#else // ----- #elseif WINNT_VER40-----
#define TRACE_STRETCH 1
#define TRACE_ALL 1
#define LGDEVID lpDDHALData->dwLgVenDevID
#define OFFSCR_YUV_VAR offscr_YUV
#define MEMCMP(A,B) memcmp(&offscr_YUV.SrcRect, (A),(B))
#define ENOUGH_FIFO_FOR_BLT EnoughFifoForBlt(lpDDHALData)
#define SET_GAMMA SetGamma(lpDDHALData)
#define UPDATE_FLIP_STATUS(arg) updateFlipStatus((arg), lpDDHALData)
#define DRVSTRETCH64 DrvStretch64(
#define DRVSTRETCH62 DrvStretch62(
#define DUP_COLOR DupColor(
#define RGB_RESIZEBOF64 RGBResizeBOF64(
#define RGB_16SHRINKBOF64 RGB16ShrinkBOF64(
#define DUPZFILL DupZFill(
#define CALL_ENOUGH_FIFO_FOR_BLT EnoughFifoForBlt(lpDDHALData)
#define CALL_DELAY_9BIT_BLT(arg) pfnDelay9BitBlt(lpDDHALData,(arg))
#define CALL_EDGE_FILL_BLT(A,B,C,D,E,F) pfnEdgeFillBlt(lpDDHALData,(A),(B),(C),(D),(E),(F))
#define CALL_MEDGE_FILL_BLT(A,B,C,D,E,F) pfnMEdgeFillBlt(lpDDHALData,(A),(B),(C),(D),(E),(F))
#define CALL_DRV_DST_BLT(A,B,C,D) pfnDrvDstBlt(lpDDHALData,(A),(B),(C),(D))
#define CALL_DRV_DST_MBLT(A,B,C,D) pfnDrvDstMBlt(lpDDHALData,(A),(B),(C),(D))
#define CALL_DRV_SRC_BLT(A,B,C,D,E,F) pfnDrvSrcBlt(lpDDHALData,(A),(B),(C),(D),(E),(F))
#define CALL_DRV_STR_BLT(A) pfnDrvStrBlt(lpDDHALData,(A))
#define CALL_DRV_STR_MBLT(A) pfnDrvStrMBlt(lpDDHALData,(A))
#define CALL_DRV_STR_MBLTX(A) pfnDrvStrMBltX(lpDDHALData,(A))
#define CALL_DRV_STR_MBLTY(A) pfnDrvStrMBltY(lpDDHALData,(A))
#define CALL_DRV_STR_BLTY(A) pfnDrvStrBltY(lpDDHALData,(A))
#define CALL_DRV_STR_BLTX(A) pfnDrvStrBltX(lpDDHALData,(A))
#define CALL_DIR_DELAY_9BIT_BLT(arg) DIR_Delay9BitBlt(lpDDHALData,(arg))
#define CALL_DIR_EDGE_FILL_BLT(A,B,C,D,E,F) DIR_EdgeFillBlt(lpDDHALData,(A),(B),(C),(D),(E),(F))
#define CALL_DIR_MEDGE_FILL_BLT(A,B,C,D,E,F) DIR_MEdgeFillBlt(lpDDHALData,(A),(B),(C),(D),(E),(F))
#define CALL_DIR_DRV_DST_BLT(A,B,C,D) DIR_DrvDstBlt(lpDDHALData,(A),(B),(C),(D))
#define CALL_DIR_DRV_STR_BLT(A) DIR_DrvStrBlt(lpDDHALData,(A))
#define CALL_DIR_DRV_STR_MBLT(A) DIR_DrvStrMBlt(lpDDHALData,(A))
#define CALL_DIR_DRV_STR_MBLTX(A) DIR_DrvStrMBltX(lpDDHALData,(A))
#define CALL_DIR_DRV_STR_MBLTY(A) DIR_DrvStrMBltY(lpDDHALData,(A))
#define CALL_DRVSTRETCH64(A,B,C,D,E,F,G,H,I,J,K,L) DrvStretch64(lpDDHALData,(A),(B),(C),(D),(E),(F),(G),(H),(I),(J),(K),(L))
#define CALL_DRVSTRETCH62(A,B,C,D,E,F,G,H,I,J,K,L) DrvStretch62(lpDDHALData,(A),(B),(C),(D),(E),(F),(G),(H),(I),(J),(K),(L))
#define CALL_DUP_COLOR(A) DupColor(lpDDHALData,(A))
#define CALL_RGB_RESIZEBOF64(A,B,C,D,E,F,G,H) RGBResizeBOF64(lpDDHALData,(A),(B),(C),(D),(E),(F),(G),(H))
#define CALL_RGB_16SHRINKBOF64(A,B,C,D,E,F,G,H) RGB16ShrinkBOF64(lpDDHALData,(A),(B),(C),(D),(E),(F),(G),(H))
#define CALL_DUPZFILL(A,B) DupZFill(lpDDHALData,(A),(B))
#define STRETCHCOLOR StretchColor(
#define CALL_STRETCHCOLOR(A,B,C,D,E,F,G,H,I) StretchColor(lpDDHALData,(A),(B),(C),(D),(E),(F),(G),(H),(I))
#define TRANSPARENTSTRETCH TransparentStretch(
#define CALL_TRANSPARENTSTRETCH(A,B,C,D,E,F,G,H,I) TransparentStretch(lpDDHALData,(A),(B),(C),(D),(E),(F),(G),(H),(I))
#endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
typedef short DDAX;
typedef struct {DDAX accum; DDAX maj; DDAX min;} AXIS;
#define EDGE_CLIP // Trim excess pixels from edges (>= 10%) in 8Bpp Mode
#define EDGE_CLIP_16 // Trim excess pixels from edges (>= 10%) in 8Bpp Mode
#define BOGUS_YUV 0x0081 // Top of palette below Windows reserved area
//#define BOGUS_8BIT
#define LOCK_HW_SEMAPHORE() (lpDDHALData->DrvSemaphore |= DRVSEM_IN_USE)
#define UNLOCK_HW_SEMAPHORE() (lpDDHALData->DrvSemaphore &= ~ DRVSEM_IN_USE)
/*--------------------- STATIC FUNCTION PROTOTYPES ------------------------*/
#ifdef WINNT_VER40
static __inline DWORD DUP_COLOR DWORD dwColor );
#else
static __inline DWORD DUP_COLOR LPGLOBALDATA lpDDHALData, DWORD dwColor );
#endif
static __inline BOOL ENOUGH_FIFO_FOR_BLT;
/*--------------------------- ENUMERATIONS --------------------------------*/
/*----------------------------- TYPEDEFS ----------------------------------*/
/*-------------------------- STATIC VARIABLES -----------------------------*/
static const WORD lncntl[] = {LN_8BIT, LN_RGB565, LN_24PACK, LN_24ARGB,};
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#ifndef WINNT_VER40 // Not WINNT_VER40
ASSERTFILE("blt.c");
OFFSCR_YUV offscr_YUV = {{ 0, 0, 0, 0}, FALSE};
PFN_DELAY9BLT pfnDelay9BitBlt;
PFN_EDGEFILLBLT pfnEdgeFillBlt;
PFN_MEDGEFILLBLT pfnMEdgeFillBlt;
PFN_DRVDSTBLT pfnDrvDstBlt;
PFN_DRVDSTMBLT pfnDrvDstMBlt;
PFN_DRVSRCBLT pfnDrvSrcBlt;
PFN_DRVSRCMBLT pfnDrvSrcMBlt;
PFN_DRVSTRBLT pfnDrvStrBlt;
PFN_DRVSTRMBLT pfnDrvStrMBlt;
PFN_DRVSTRMBLTY pfnDrvStrMBltY;
PFN_DRVSTRMBLTX pfnDrvStrMBltX;
PFN_DRVSTRBLTY pfnDrvStrBltY;
PFN_DRVSTRBLTX pfnDrvStrBltX;
extern PFN_UPDATEFLIPSTATUS pfnUpdateFlipStatus;
#if ENABLE_CLIPPEDBLTS
PFN_CLIPPEDDRVDSTBLT pfnClippedDrvDstBlt;
PFN_CLIPPEDDRVDSTMBLT pfnClippedDrvDstMBlt;
PFN_CLIPPEDDRVSRCBLT pfnClippedDrvSrcBlt;
#endif
#endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
/*-------------------------- GLOBAL FUNCTIONS -----------------------------*/
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#ifdef WINNT_VER40 // WINNT_VER40
//***** SetGamma ********************************************************
// Use only for YUV 8BPP
//
#define LOWER_YUV 16
#define UPPER_YUV 240
#define LOWER_PALETTE 0
#define UPPER_PALETTE 255
void SetGamma(PDEV* ppdev, DRIVERDATA* lpDDHALData)
{
int indx;
PVGAR pREG = (PVGAR) lpDDHALData->RegsAddress;
DISPDBG((DBGLVL, "DDraw - SetGamma\n"));
for ( indx = LOWER_PALETTE ; indx <= UPPER_PALETTE ; indx++ )
{ // Initialise gamma palette
int value;
value = ((indx - LOWER_YUV) * UPPER_PALETTE) / (UPPER_YUV - LOWER_YUV);
if ( value < LOWER_PALETTE )
value = LOWER_PALETTE;
if ( value > UPPER_PALETTE )
value = UPPER_PALETTE;
LL8(grPalette_Write_Address, (BYTE)(indx));
LL8(grPalette_Data, (BYTE)(value)); // Red
LL8(grPalette_Data, (BYTE)(value)); // Grn
LL8(grPalette_Data, (BYTE)(value)); // Blu
};
} // SetGamma
#endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
/***************************************************************************
*
* FUNCTION: RGBResizeBOF64
*
* DESCRIPTION: Handles 8bpp RGB stretches, 8bpp RGB shrinks and
* 16bpp RGB stretches on the 5464
*
****************************************************************************/
#define SRAM_SIZE 128
void RGB_RESIZEBOF64
#ifndef WINNT_VER40
LPGLOBALDATA lpDDHALData,
#endif
int xDst, int yDst, int cxDst, int cyDst,
int xSrc, int ySrc, int cxSrc, int cySrc )
{
const int nBytesPixel = BYTESPERPIXEL;
// setting nSRAMPixels to the number of pixels that fit in sram divided
// by two gives better shrinks at 8bpp and doesn't lock up the chip on
// stretches at 16bpp
const int nSRAMPixels = (SRAM_SIZE / nBytesPixel) / 2;
const int nSRAMMask = nSRAMPixels - 1;
autoblt_regs bltr;
AXIS axis[2];
int nDst[2];
int nSrc[2];
int i;
DDAX accx;
int srcxext;
int dstxext;
int srcx;
int xext;
DD_LOG(("RGBResizeBOF64 - %d bpp %s in X\r\n", nBytesPixel,
(cxDst < cxSrc) ? "shrink" : "stretch"));
DD_LOG(("dst=%08lX dstext=%08lX src=%08lX srcext=%08lX\r\n",
MAKELONG(xDst,yDst),MAKELONG(cxDst,cyDst),
MAKELONG(xSrc,ySrc),MAKELONG(cxSrc,cySrc)));
#ifndef WINNT_VER40
// Verify this is an 8bpp shrink or stretch
// or its a 16bpp stretch
ASSERT((1 == nBytesPixel) || (cxSrc <= cxDst));
DBG_MESSAGE((" RGBResizeBOF64 - Dst %08lXh,%08lXh %08lX,%08lX",xDst,yDst,cxDst,cyDst));
DBG_MESSAGE((" Src %08lXh,%08lXh %08lX,%08lX",xSrc,ySrc,cxSrc,cySrc));
#endif
// initialize auto blt struct
bltr.DRAWBLTDEF.DW = MAKELONG(ROP_OP1_copy, (BD_RES+BD_OP1)*IS_VRAM);
bltr.OP0_opRDRAM.DW = MAKELONG(LOWORD(xDst),LOWORD(yDst));
bltr.OP1_opRDRAM.DW = MAKELONG(LOWORD(xSrc),LOWORD(ySrc));
bltr.BLTEXT.DW = MAKELONG(LOWORD(cxDst),LOWORD(cyDst));
bltr.LNCNTL.W = lncntl[nBytesPixel-1] << LN_YUV_SHIFT;
bltr.SRCX = cxSrc * nBytesPixel;
// Enable interpolation unless we have a palette (8bpp)
if (1 < nBytesPixel)
bltr.LNCNTL.W |= (LN_XINTP_EN | LN_YINTP_EN);
bltr.SHRINKINC.W = 0x0000;
if (cxDst < cxSrc)
{
bltr.LNCNTL.W |= LN_XSHRINK;
bltr.LNCNTL.W &= ~LN_XINTP_EN;
bltr.SHRINKINC.pt.X = (cxSrc / cxDst);
}
if ( cyDst < cySrc )
{
bltr.LNCNTL.W |= LN_YSHRINK;
bltr.LNCNTL.W &= ~LN_YINTP_EN;
bltr.SHRINKINC.pt.Y = (cySrc / cyDst);
}
// Compute DDA terms.
nDst[0] = cxDst;
nDst[1] = cyDst;
nSrc[0] = cxSrc;
nSrc[1] = cySrc;
for (i = 0; i < 2; i++)
{
int kDst = 1;
if (bltr.LNCNTL.W & ((i==0) ? LN_XINTP_EN : LN_YINTP_EN))
{
nDst[i] *= 4;
nSrc[i] *= 4;
nSrc[i] -= 3;
kDst = 0x8000 / nDst[i];
}
if (bltr.LNCNTL.W & ((i==0) ? LN_XSHRINK : LN_YSHRINK))
{ /* Shrink Terms */
axis[i].maj = (short)nDst[i];
axis[i].min = - (nSrc[i] % nDst[i]);
axis[i].accum = axis[i].maj - 1
- ((nSrc[i] % nDst[i]) / (nSrc[i]/nDst[i] + 1));
}
else
{ /* Stretch Terms */
axis[i].maj = kDst * nDst[i];
axis[i].min = -kDst * nSrc[i];
axis[i].accum = axis[i].maj - 1
- ((axis[i].maj % -axis[i].min) / (nDst[i]/nSrc[i] + 1));
}
}
bltr.MAJ_X = axis[0].maj;
bltr.MIN_X = axis[0].min;
bltr.ACCUM_X = axis[0].accum;
bltr.MAJ_Y = axis[1].maj;
bltr.MIN_Y = axis[1].min;
bltr.ACCUM_Y = axis[1].accum;
// write settings that don't vary over stripes to the chip
CALL_DRV_STR_BLTY(&bltr);
if (bltr.LNCNTL.W & LN_XSHRINK)
{
// 8bpp shrink in X
accx = bltr.ACCUM_X;
while (cxDst > 0)
{
// walk DDA to determine number of src & dst pixels to blt in
// current stripe
// computes error term (accx) for next stripe also
srcxext = 0;
dstxext = 0;
for (;;)
{
// check for worst case srcxext larger than num pixels that
// fit in sram
if ((srcxext + bltr.SHRINKINC.pt.X + 1) > nSRAMPixels)
break;
accx += bltr.MIN_X;
srcxext += bltr.SHRINKINC.pt.X;
if (0 > accx)
{
accx += bltr.MAJ_X;
srcxext++;
}
dstxext++;
if (dstxext >= cxDst)
break;
}
// adjust dst extent
bltr.BLTEXT.pt.X = (USHORT)dstxext;
// blt current stripe
CALL_DRV_STR_BLTX(&bltr);
// adjust dst extent remaining
cxDst -= dstxext;
// update auto blt struct settings
// increment xDst & xSrc
// store error term for next stripe
bltr.OP0_opRDRAM.pt.X += (USHORT)dstxext;
bltr.OP1_opRDRAM.pt.X += (USHORT)srcxext;
bltr.ACCUM_X = accx;
}
}
else
{
// stretch in X
// set values for initial stripe
xext = ((xDst + nSRAMPixels) & (~nSRAMMask)) - xDst;
accx = bltr.ACCUM_X;
srcx = xSrc;
while (cxDst > xext)
{
// update auto blt struct settings
bltr.OP0_opRDRAM.pt.X = (USHORT)xDst;
bltr.OP1_opRDRAM.pt.X = (USHORT)srcx;
bltr.ACCUM_X = accx;
bltr.BLTEXT.pt.X = (USHORT)xext;
// blt current stripe
CALL_DRV_STR_BLTX(&bltr);
// increment xDst and decrement remaining dst extent
xDst += xext;
cxDst -= xext;
// walk DDA to compute error term (accx) and xSrc for next stripe
for (i = 0; i < xext; i++)
{
accx += bltr.MIN_X;
if (0 > accx)
{
accx += bltr.MAJ_X;
srcx++;
}
}
// set dst ext of current stripe
xext = nSRAMPixels;
}
// if there's some area left to blt, then do it
if (0 < cxDst)
{
// update auto blt struct settings
bltr.OP0_opRDRAM.pt.X = (USHORT)xDst;
bltr.OP1_opRDRAM.pt.X = (USHORT)srcx;
bltr.ACCUM_X = accx;
bltr.BLTEXT.pt.X = (USHORT)cxDst;
// blt final stripe
CALL_DRV_STR_BLTX(&bltr);
}
}
}
/***************************************************************************
*
* FUNCTION: RGB16ShrinkBOF64
*
* DESCRIPTION: Handles 16bpp RGB shrinks on the 5464
*
****************************************************************************/
#define ENABLE_INTERPOLATED_BLTS 1
void RGB_16SHRINKBOF64
#ifndef WINNT_VER40
LPGLOBALDATA lpDDHALData,
#endif
int xDst, int yDst, int cxDst, int cyDst,
int xSrc, int ySrc, int cxSrc, int cySrc )
{
const int nBytesPixel = BYTESPERPIXEL;
const int nSRAMPixels = (SRAM_SIZE / nBytesPixel) / 2;
const int nSRAMMask = nSRAMPixels - 1;
autoblt_regs SrcToScratch;
autoblt_regs ScratchToDst;
int xScratch, yScratch;
int cxScratch, cyScratch;
AXIS axis[2];
int nDst[2];
int nSrc[2];
int i;
DDAX accx;
int srcx;
int xext;
int nSRAMext;
int cxTemp;
int xTemp;
DD_LOG(("RGB16ResizeBOF64 - 16 bpp shrink in X\r\n"));
DD_LOG(("dst=%08lX dstext=%08lX src=%08lX srcext=%08lX\r\n",
MAKELONG(xDst,yDst),MAKELONG(cxDst,cyDst),
MAKELONG(xSrc,ySrc),MAKELONG(cxSrc,cySrc)));
#ifndef WINNT_VER40
// Verify this is a 16bpp shrink!
ASSERT(cxSrc > cxDst);
ASSERT(nBytesPixel == 2);
DBG_WARNING((" RGB16ShrinkBOF64 - Dst %08lXh,%08lXh %08lX,%08lX",xDst,yDst,cxDst,cyDst));
DBG_WARNING((" Src %08lXh,%08lXh %08lX,%08lX",xSrc,ySrc,cxSrc,cySrc));
#endif
xScratch = LOWORD(lpDDHALData->ScratchBufferOrg);
yScratch = HIWORD(lpDDHALData->ScratchBufferOrg);
cyScratch = cyDst;
// initialize auto blt struct for src to scratch buffer
SrcToScratch.DRAWBLTDEF.DW = MAKELONG(ROP_OP1_copy, (BD_RES+BD_OP1)*IS_VRAM);
SrcToScratch.OP0_opRDRAM.DW = MAKELONG(LOWORD(xScratch),LOWORD(yScratch));
SrcToScratch.OP1_opRDRAM.DW = MAKELONG(LOWORD(xSrc),LOWORD(ySrc));
SrcToScratch.LNCNTL.W = lncntl[nBytesPixel-1] << LN_YUV_SHIFT;
SrcToScratch.SRCX = cxSrc * nBytesPixel;
#if ENABLE_INTERPOLATED_BLTS
// Enable interpolation unless we have a palette (8bpp)
if (1 < nBytesPixel)
SrcToScratch.LNCNTL.W |= (LN_XINTP_EN | LN_YINTP_EN);
#endif
SrcToScratch.SHRINKINC.W = 0x0000;
// THIS IS A SHRINK IN X!
cxScratch = cxSrc & ~1;
nSRAMext = 0x38;
while (cxScratch > cxDst)
{
cxScratch >>= 1;
nSRAMext >>= 1;
}
/* Check for zero extent blt */
if (nSRAMext == 0)
return;
SrcToScratch.BLTEXT.DW = MAKELONG(LOWORD(cxScratch),1);
// Yes, the following line doesn't make any sense but using
// half the dest x ext on a 16bpp rgb shrink to compute the
// minor, major and initial accumulator terms appears to get
// the hw to work correctly
cxScratch /= 2;
SrcToScratch.LNCNTL.W |= LN_XSHRINK;
#if ENABLE_INTERPOLATED_BLTS
SrcToScratch.LNCNTL.W &= ~LN_XINTP_EN;
#endif
SrcToScratch.SHRINKINC.pt.X = (cxSrc / cxScratch);
if ( cyDst < cySrc )
{
SrcToScratch.LNCNTL.W |= LN_YSHRINK;
#if ENABLE_INTERPOLATED_BLTS
SrcToScratch.LNCNTL.W &= ~LN_YINTP_EN;
#endif
SrcToScratch.SHRINKINC.pt.Y = (cySrc / cyScratch);
}
// Compute DDA terms
nDst[0] = cxScratch;
nDst[1] = cyScratch;
nSrc[0] = cxSrc;
nSrc[1] = cySrc;
for (i = 0; i < 2; i++)
{
int kDst = 1;
#if ENABLE_INTERPOLATED_BLTS
if (SrcToScratch.LNCNTL.W & ((i==0) ? LN_XINTP_EN : LN_YINTP_EN))
{
nDst[i] *= 4;
nSrc[i] *= 4;
nSrc[i] -= 3;
kDst = 0x8000 / nDst[i];
}
#endif
if (SrcToScratch.LNCNTL.W & ((i==0) ? LN_XSHRINK : LN_YSHRINK))
{ /* Shrink Terms */
axis[i].maj = (short)nDst[i];
axis[i].min = - (nSrc[i] % nDst[i]);
axis[i].accum = axis[i].maj - 1
- ((nSrc[i] % nDst[i]) / (nSrc[i]/nDst[i] + 1));
}
else
{ /* Stretch Terms */
axis[i].maj = kDst * nDst[i];
axis[i].min = -kDst * nSrc[i];
axis[i].accum = axis[i].maj - 1
- ((axis[i].maj % -axis[i].min) / (nDst[i]/nSrc[i] + 1));
}
}
SrcToScratch.MAJ_X = axis[0].maj;
SrcToScratch.MIN_X = axis[0].min;
SrcToScratch.ACCUM_X = axis[0].accum;
SrcToScratch.MAJ_Y = axis[1].maj;
SrcToScratch.MIN_Y = axis[1].min;
SrcToScratch.ACCUM_Y = axis[1].accum;
// Now that we have the major, minor and initial accumulator terms
// computed, adjust dest x ext back to full width so we do the full
// width of the blt below
cxScratch *= 2;
// initialize auto blt struct for scratch buffer to dst
ScratchToDst.DRAWBLTDEF.DW = MAKELONG(ROP_OP1_copy, (BD_RES+BD_OP1)*IS_VRAM);
ScratchToDst.OP0_opRDRAM.DW = MAKELONG(LOWORD(xDst),LOWORD(yDst));
ScratchToDst.OP1_opRDRAM.DW = MAKELONG(LOWORD(xScratch),LOWORD(yScratch));
ScratchToDst.BLTEXT.DW = MAKELONG(LOWORD(cxDst),1);
ScratchToDst.LNCNTL.W = lncntl[nBytesPixel-1] << LN_YUV_SHIFT;
ScratchToDst.SRCX = cxScratch * nBytesPixel;
#if ENABLE_INTERPOLATED_BLTS
// Enable interpolation unless we have a palette (8bpp)
if (1 < nBytesPixel)
ScratchToDst.LNCNTL.W |= (LN_XINTP_EN | LN_YINTP_EN);
#endif
ScratchToDst.SHRINKINC.W = 0x0000;
// THIS IS A STRETCH IN X!
// THIS IS 1:1 IN Y
// Compute DDA terms
nDst[0] = cxDst;
nDst[1] = cyDst;
nSrc[0] = cxScratch;
nSrc[1] = cyScratch;
for (i = 0; i < 2; i++)
{
int kDst = 1;
#if ENABLE_INTERPOLATED_BLTS
if (ScratchToDst.LNCNTL.W & ((i==0) ? LN_XINTP_EN : LN_YINTP_EN))
{
nDst[i] *= 4;
nSrc[i] *= 4;
nSrc[i] -= 3;
kDst = 0x8000 / nDst[i];
}
#endif
if (ScratchToDst.LNCNTL.W & ((i==0) ? LN_XSHRINK : LN_YSHRINK))
{ /* Shrink Terms */
axis[i].maj = (short)nDst[i];
axis[i].min = - (nSrc[i] % nDst[i]);
axis[i].accum = axis[i].maj - 1
- ((nSrc[i] % nDst[i]) / (nSrc[i]/nDst[i] + 1));
}
else
{ /* Stretch Terms */
axis[i].maj = kDst * nDst[i];
axis[i].min = -kDst * nSrc[i];
axis[i].accum = axis[i].maj - 1
- ((axis[i].maj % -axis[i].min) / (nDst[i]/nSrc[i] + 1));
}
}
ScratchToDst.MAJ_X = axis[0].maj;
ScratchToDst.MIN_X = axis[0].min;
ScratchToDst.ACCUM_X = axis[0].accum;
ScratchToDst.MAJ_Y = axis[1].maj;
ScratchToDst.MIN_Y = axis[1].min;
ScratchToDst.ACCUM_Y = axis[1].accum;
// loop over scanlines in dst
// do two blts for each, one from src to scratch buffer
// then one from scratch buffer to dst
while (0 < cyDst)
{
// blt one scanline high from src to scratch buffer
// set values for initial stripe
xext = nSRAMext;
accx = SrcToScratch.ACCUM_X;
srcx = xSrc;
// write settings that don't vary over stripes to the chip
CALL_DRV_STR_BLTY(&SrcToScratch);
cxTemp = cxScratch;
xTemp = xScratch;
while (cxTemp > xext)
{
// update auto blt struct settings
SrcToScratch.OP0_opRDRAM.pt.X = (USHORT)xTemp;
SrcToScratch.OP1_opRDRAM.pt.X = (USHORT)srcx;
SrcToScratch.BLTEXT.pt.X = (USHORT)xext;
// blt current stripe
CALL_DRV_STR_BLTX(&SrcToScratch);
// increment xDst and decrement remaining dst extent
xTemp += xext;
cxTemp -= xext;
// walk DDA to compute error term (accx) and xSrc for next stripe
for (i = 0; i < xext; i++)
{
SrcToScratch.ACCUM_X += SrcToScratch.MIN_X;
// Even though the following line should be correct
// the hw doesn't work correctly so we'll skip it
// here and adjust srcx after the for loop
//srcx += SrcToScratch.SHRINKINC.pt.X;
if (0 > (short)SrcToScratch.ACCUM_X)
{
SrcToScratch.ACCUM_X += SrcToScratch.MAJ_X;
srcx++;
}
}
// now adjust srcx with a bizarre equation that appears to get
// the hw to work correctly
srcx += ((nSRAMext / 2) * SrcToScratch.SHRINKINC.pt.X);
}
// if there's some area left to blt, then do it
if (0 < cxTemp)
{
// update auto blt struct settings
SrcToScratch.OP0_opRDRAM.pt.X = (USHORT)xTemp;
SrcToScratch.OP1_opRDRAM.pt.X = (USHORT)srcx;
SrcToScratch.BLTEXT.pt.X = (USHORT)cxTemp;
// blt final stripe
CALL_DRV_STR_BLTX(&SrcToScratch);
}
// reset ACCUM_X for beginning of next scanline
SrcToScratch.ACCUM_X = accx;
// walk Y DDA for src to scratch buffer blt
SrcToScratch.ACCUM_Y += SrcToScratch.MIN_Y;
SrcToScratch.OP1_opRDRAM.pt.Y += SrcToScratch.SHRINKINC.pt.Y;
if (0 > (short)SrcToScratch.ACCUM_Y)
{
SrcToScratch.ACCUM_Y += SrcToScratch.MAJ_Y;
SrcToScratch.OP1_opRDRAM.pt.Y++;
}
// blt from scratch buffer to dst
// stretch in X, 1:1 in Y
// set values for initial stripe
xext = ((xDst + nSRAMPixels) & (~nSRAMMask)) - xDst;
accx = ScratchToDst.ACCUM_X;
srcx = xScratch;
// write settings that don't vary over stripes to the chip
CALL_DRV_STR_BLTY(&ScratchToDst);
xTemp = xDst;
cxTemp = cxDst;
while (cxTemp > xext)
{
// update auto blt struct settings
ScratchToDst.OP0_opRDRAM.pt.X = (USHORT)xTemp;
ScratchToDst.OP1_opRDRAM.pt.X = (USHORT)srcx;
ScratchToDst.BLTEXT.pt.X = (USHORT)xext;
// blt current stripe
CALL_DRV_STR_BLTX(&ScratchToDst);
// increment xDst and decrement remaining dst extent
xTemp += xext;
cxTemp -= xext;
// walk DDA to compute error term (accx) and xSrc for next stripe
for (i = 0; i < xext; i++)
{
ScratchToDst.ACCUM_X += ScratchToDst.MIN_X;
if (0 > (short)ScratchToDst.ACCUM_X)
{
ScratchToDst.ACCUM_X += ScratchToDst.MAJ_X;
srcx++;
}
}
// set dst ext of current stripe
xext = nSRAMPixels;
}
// if there's some area left to blt, then do it
if (0 < cxTemp)
{
// update auto blt struct settings
ScratchToDst.OP0_opRDRAM.pt.X = (USHORT)xTemp;
ScratchToDst.OP1_opRDRAM.pt.X = (USHORT)srcx;
ScratchToDst.BLTEXT.pt.X = (USHORT)cxTemp;
// blt final stripe
CALL_DRV_STR_BLTX(&ScratchToDst);
}
// reset ACCUM_X for beginning of next scanline
ScratchToDst.ACCUM_X = accx;
// adjust dst ptr and dst extent
ScratchToDst.OP0_opRDRAM.pt.Y++;
cyDst--;
}
}
/****************************************************************************
* FUNCTION NAME: DdGetBltStatus (NT)
* GetBltStatus32 (Win95)
*
* DESCRIPTION: Doesn't currently really care what surface is specified,
* just checks and goes.
****************************************************************************/
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#ifdef WINNT_VER40 // WINNT_VER40
DWORD DdGetBltStatus(PDD_GETBLTSTATUSDATA lpGetBltStatus)
{
DRIVERDATA* lpDDHALData;
PDEV* ppdev;
HRESULT ddRVal;
DISPDBG((DBGLVL, "DDraw - DdGetBltStatus\n"));
ppdev = (PDEV*) lpGetBltStatus->lpDD->dhpdev;
lpDDHALData = (DRIVERDATA*) &ppdev->DriverData;
#else // ----- #elseif WINNT_VER40 -----
DWORD __stdcall GetBltStatus32( LPDDHAL_GETBLTSTATUSDATA lpGetBltStatus)
{
LPGLOBALDATA lpDDHALData = GetDDHALContext( lpGetBltStatus->lpDD);
HRESULT ddRVal;
#endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
DD_LOG(("GetBltStatus32 Entry\r\n"));
#ifndef WINNT_VER40
SyncWithQueueManager(lpDDHALData);
#endif
#ifdef WINNT_VER40
SYNC_W_3D(ppdev); // if 3D context(s) active, make sure 3D engine idle before continuing...
#endif
// DDGBS_CANBLT: can we add a blt?
ddRVal = DD_OK;
if (lpGetBltStatus->dwFlags == DDGBS_CANBLT)
{
// is a flip in progress?
#ifdef WINNT_VER40
ddRVal = vUpdateFlipStatus(
&ppdev->flipRecord,
lpGetBltStatus->lpDDSurface->lpGbl->fpVidMem);
#else
#if defined(DDRAW_COMPAT_10)
ddRVal = pfnUpdateFlipStatus(
lpGetBltStatus->lpDDSurface->lpData->fpVidMem,
lpDDHALData);
#else
ddRVal = pfnUpdateFlipStatus(
lpGetBltStatus->lpDDSurface->lpGbl->fpVidMem,
lpDDHALData);
#endif
#endif
if (ddRVal == DD_OK)
{
// so there was no flip going on, is there room in the fifo
// to add a blt?
if (!CALL_ENOUGH_FIFO_FOR_BLT)
ddRVal = DDERR_WASSTILLDRAWING;
else
ddRVal = DD_OK;
};
}
else
{
// DDGBS_ISBLTDONE case: is a blt in progress?
if (DRAW_ENGINE_BUSY)
ddRVal = DDERR_WASSTILLDRAWING;
else
ddRVal = DD_OK;
};
lpGetBltStatus->ddRVal = ddRVal;
DD_LOG(("GetBltStatus32 Exit\r\n"));
return(DDHAL_DRIVER_HANDLED);
} // DDGetBltStatus or GetBltStatus32
/***************************************************************************
*
* FUNCTION: DrvStretch64
*
* DESCRIPTION:
*
****************************************************************************/
void DRVSTRETCH64
#ifndef WINNT_VER40
LPGLOBALDATA lpDDHALData,
#endif
int xDst, int yDst, int cxDst, int cyDst,
int xSrc, int ySrc, int cxSrc, int cySrc,
int nBytesPixel, int SrcType, int BaseOffset,
int OnScreen)
{
int cxClip = cxDst;
int cyClip = cyDst;
int cxFill = 0;
int cyFill = cyDst;
int xFill = xDst;
int yFill = yDst;
int cxTrim = 0;
int iratio, i;
#ifdef RDRAM_8BIT
PVGAR pREG = (PVGAR) lpDDHALData->RegsAddress;
#endif
autoblt_regs bltr;
AXIS axis[2];
int nDst[2];
int nSrc[2];
#ifdef RDRAM_8BIT
RECTL SrcRectl;
int nFound = FALSE;
#endif
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#ifdef WINNT_VER40 // WINNT_VER40
DISPDBG((DBGLVL3, "DDraw - DrvStretch64 xD=%x, yD=%x, cxD=%x, cyD=%x, xS=%x, yS=%x, cxS=%x, cyS=%x, bpp=%x, t=%x, bo=%x, scn=%x\n",
xDst, yDst, cxDst, cyDst,
xSrc, ySrc, cxSrc, cySrc,
nBytesPixel, SrcType, BaseOffset, OnScreen));
#endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
DD_LOG(("DrvStretch64 - dst=%08lX dstext=%08lX src=%08lX srcext=%08lX\r\n",
MAKELONG(xDst,yDst),MAKELONG(cxDst,cyDst),
MAKELONG(xSrc,ySrc),MAKELONG(cxSrc,cySrc)));
#ifdef RDRAM_8BIT
if (!lpDDHALData->fNineBitRDRAMS)
{
if (SrcType == LN_YUV422)
{
SrcRectl.left = xSrc;
SrcRectl.top = ySrc;
SrcRectl.right = xSrc+cxSrc;
SrcRectl.bottom = ySrc+cySrc;
if (MEMCMP(&SrcRectl, sizeof(SrcRectl)) == 0)
nFound = TRUE;
if (nFound)
{
#if 0
DBG_MESSAGE(("Stretch: Found Offscreen Area P1(%x,%x) P2(%x,%x) Dst(%x, %x) Dst(%x %x)\n",
SrcRectl.left,
SrcRectl.top,
SrcRectl.right,
SrcRectl.bottom,
xDst,
yDst,
xDst+cxDst,
yDst+cyDst));
#endif
LL16(grX_Start_2, xDst + ((4 - (xDst & 3)) & 3));
LL16(grY_Start_2, yDst);
LL16(grX_End_2, xDst+(cxDst>>3<<3));
LL16(grY_End_2, yDst+cyDst);
}
else
{
#if 0
DBG_MESSAGE(("Stretch: Not Found Offscreen Area P1(%x,%x) P2(%x,%x)\n",
SrcRectl.left,
SrcRectl.top,
SrcRectl.right,
SrcRectl.bottom));
#endif
LL16(grX_Start_2, 0);
LL16(grY_Start_2, 0);
LL16(grX_End_2, 0);
LL16(grY_End_2, 0);
// Black Blit Here
CALL_DRV_DST_BLT(0x107000CC,MAKELONG(xDst,yDst),0,MAKELONG(cxDst,cyDst));
return ;
}
} // endif (SrcType == LN_YUV422)
} // endif (!lpDDHALData->fNineBitRDRAMS)
#endif
#ifdef TRACE_STRETCH
DBG_MESSAGE(("DrvStretch64: %4d,%4d %4dx%4d -> %4d,%4d %4dx%4d (%d %d) %d",
xSrc, ySrc, cxSrc, cySrc,
xDst, yDst, cxDst, cyDst,
nBytesPixel, SrcType, BaseOffset));
#endif
if ((SrcType == LN_YUV422) ||
((SrcType == LN_RGB565) && (nBytesPixel == 1)))
{ // Force alignment of output to QWORD ( it is documented as DWORD but broken)
if (nBytesPixel == 2)
{ // 16 bit frame buffer ( Note all ptrs/extents in terms of 16 bpp )
// The X portions will be mutiplied by 2 by chip on being written )
if (cxDst > cxSrc)
iratio = cxDst / cxSrc; // integer ratio of stretch
else
iratio = cxSrc / cxDst; // integer ratio of shrink
if (xDst & 3) // This should be for LN_YUV422 only
{
cxFill = 4 - (xDst & 3);
cxTrim = cxFill; // save trim count for source clipping if required
if ( cxFill > cxClip )
cxFill = cxClip; // check for no stretch left
cxClip -= cxFill; // reduce size
cxDst -= cxFill; // reduce size
xDst += cxFill; // force alignment to next even DWORD boundary
CALL_EDGE_FILL_BLT(xFill, yFill, cxFill, cyFill,
MAKELONG(BOGUS_YUV, BOGUS_YUV),
FALSE);
} // endif (xDst & 3)
cxFill = cxClip & 3;
if (OnScreen && cxFill )
{
cxClip -= cxFill; // force size to next smaller even DWORD count
xFill = xDst + cxClip;
if ( cxClip >= cxSrc)
{ // If shrink defer edge fill to later as there may be more
CALL_EDGE_FILL_BLT(xFill, yFill, cxFill, cyFill,
MAKELONG(BOGUS_YUV, BOGUS_YUV), FALSE);
}
} // endif ( cxFill )
if ( (cxClip < cxSrc) )
{ // Edge Clip on shrinks only ( add config flag check here )
// extra pixels to discard above integer ratio
int excess = (cxSrc / iratio) - cxClip;
#ifdef TRACE_STRETCH
DBG_MESSAGE((" Edge Clip iratio = %d excess = %d Trim %% = %d", iratio, excess, lpDDHALData->EdgeTrim));
#endif
if ( excess && cxTrim )
{ // These excess pixels are caused by our Dest alignment
// problems on the Left edge
if ( excess < (cxTrim * iratio) )
{
cxSrc -= excess;
xSrc += excess;
excess = 0;
}
else
{
cxSrc -= cxTrim * iratio;
xSrc += cxTrim * iratio;
excess -= cxTrim * iratio;
}
} // endif ( (cxClip < cxSrc) )
if ( excess && cxFill)
{ // These excess pixels are caused by our Dest alignment
// problems on the Right edge
if ( excess < (cxFill * iratio) )
{
cxSrc -= excess;
excess = 0;
}
else
{
cxSrc -= cxFill * iratio;
excess -= cxFill * iratio;
}
} // endif ( excess && cxFill)
if ( excess && (excess <= (lpDDHALData->EdgeTrim * cxSrc)/100 ))
{ // if excess is less than % of frame trim edges
int trim = excess / 2; // half the excess of pixels
xSrc += trim; // offset pixel pointer
cxSrc -= excess; // all the excess in pixels
#ifdef TRACE_STRETCH
DBG_MESSAGE((" Edge Clip Left = %d, xSrc = %d, cxSrc = %d", trim, xSrc, cxSrc));
#endif
}
if ( iratio == 1 )
{ // we may have just changed a shrink to a 1 : 1
// if excess is zero do edge fill now
// extra pixels to discard above integer ratio
excess = ( cxSrc / iratio ) - cxClip;
if ( !excess && cxFill )
{
xFill = xDst + cxClip;
CALL_EDGE_FILL_BLT(xFill, yFill, cxFill, cyFill,
MAKELONG(BOGUS_YUV, BOGUS_YUV), FALSE);
}
} // endif ( iratio == 1 )
}
else
{ // Stretch adjustments
if ( xSrc - BaseOffset )
{ // if we are not starting from left edge of source image
if ( cxTrim )
{ // And we were forced to offset for left edge alignment
#ifdef TRACE_STRETCH
DBG_MESSAGE((" Edge Trim for stretch iratio = %d , cxTrim = %d xSrc %d", iratio, cxTrim, xSrc));
#endif
cxSrc -= cxTrim / iratio;
xSrc += cxTrim / iratio;
}
}
} // endif ( (cxClip < cxSrc) )
// Global adjustments
if ( xSrc & 1 ) // HW bug workaound for clipping
{
xSrc += 1; // Align to SRC DWORD Boundary
cxSrc -= 1; // Account for smaller size
}
}
else
{ // 8 Bit frame buffer.
// Force alignment of output to QWORD ( it is documented as DWORD but broken)
if ( cxDst >= (cxSrc*2) )
iratio = cxDst / (2 * cxSrc); // integer ratio of stretch
else
iratio = (2 * cxSrc ) / cxDst; // integer ratio of shrink
if ( xDst & 7 ) /* This should be for LN_YUV422 only */
{
cxFill = 8 - (xDst & 7);
if ( cxFill > cxClip )
cxFill = cxClip; // check for no stretch left
cxClip -= cxFill; // reduce size
cxDst -= cxFill; // reduce size
xDst += cxFill; // force alignment to next even WORD boundary
CALL_EDGE_FILL_BLT(xFill, yFill, cxFill, cyFill,
0x00000000, FALSE);
} // endif ( xDst & 7 )
cxFill = cxClip & 7;
if (OnScreen && cxFill )
{
cxClip -= cxFill; /* force size to next smaller even DWORD count */
if ( cxClip >= (cxSrc * 2))
{ // If shrink defer edge fill to later as there may be more
xFill = xDst + cxClip;
CALL_EDGE_FILL_BLT(xFill, yFill, cxFill, cyFill,
0x00000000, FALSE);
}
} // endif ( cxFill )
// change pixel pointer to byte pointer
// taking account of X origin of buffer
xSrc = BaseOffset + (xSrc - BaseOffset) * 2;
cxSrc *= 2; // change pixel count to byte count
#ifdef EDGE_CLIP
if ( (cxClip < cxSrc) && lpDDHALData->EdgeTrim)
{ // Edge Clip on shrinks only ( add config flag check here )
int excess;
excess = ( cxSrc / iratio ) - cxClip; // extra pixels to discard
// above integer ratio
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#ifdef WINNT_VER40 // WINNT_VER40
DISPDBG((DBGLVL1,
"DDraw - Edge Clip iratio = %d excess = %d Trim %% = %d",
iratio, excess, lpDDHALData->EdgeTrim));
#else // ----- #elseif WINNT_VER40 -----
DBG_MESSAGE((" Edge Clip iratio = %d excess = %d Trim %% = %d",
iratio, excess, lpDDHALData->EdgeTrim));
#endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
if ( excess && cxTrim )
{ // These excess pixels are caused by our Dest alignment
// problems on the Left edge
if ( excess < (cxTrim * iratio) )
{
cxSrc -= excess;
xSrc += excess;
excess = 0;
}
else
{
cxSrc -= cxTrim * iratio;
xSrc += cxTrim * iratio;
excess -= cxTrim * iratio;
}
} // endif ( excess && cxTrim )
if ( excess && cxFill)
{ // These excess pixels are caused by our Dest alignment
// problems on the Right edge
if ( excess < (cxFill * iratio) )
{
cxSrc -= excess;
excess = 0;
}
else
{
cxSrc -= cxFill * iratio;
excess -= cxFill * iratio;
}
} // endif ( excess && cxFill)
if ( excess && ( excess <= (lpDDHALData->EdgeTrim * cxSrc)/100 ) )
{ // if excess is less than specific % of frame trim edges
int trim = excess / 2; // half the excess as pixels
xSrc += trim; // offset pixel pointer
cxSrc -= excess; // all the excess in bytes
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#ifdef WINNT_VER40 // WINNT_VER40
DISPDBG((DBGLVL1,
"DDraw - Edge Clip Left = %d, xSrc = %d, cxSrc = %d",
trim, xSrc, cxSrc));
#else // ----- #elseif WINNT_VER40 -----
DBG_MESSAGE((" Edge Clip Left = %d, xSrc = %d, cxSrc = %d",
trim, xSrc, cxSrc));
#endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
} // endif (excess && ( excess <= (lpDDHALData->EdgeTrim * cxSrc)/100))
if ( iratio == 1 )
{ // we may have just changed a shrink to a 1 : 1
// if excess is no zero do edge fill now
// extra pixels to discard above integer ratio
excess = ( cxSrc / iratio ) - cxClip;
if ( !excess && cxFill )
{
xFill = xDst + cxClip;
CALL_EDGE_FILL_BLT(xFill, yFill, cxFill, cyFill,
0x00000000, FALSE);
}
} // endif ( iratio == 1 )
} // endif ( (cxClip < cxSrc) && lpDDHALData->EdgeTrim)
#endif
if ( xSrc & 3 ) /* HW bug workaound for clipping */
{
cxSrc -= 4 - (xSrc & 3); /* reduce size */
xSrc = (xSrc + 3) & ~ 3; /* Align to SRC DWORD Boundary */
}
} // endif (nBytesPixel == 2)
}
if ( cxClip == 0 )
return; // discard zero extent stretchs
if (nBytesPixel == 1 && ((SrcType == LN_YUV422) || (SrcType == LN_RGB565))
|| ((nBytesPixel == 2) && (SrcType == LN_YUV422)))
{
CALL_DELAY_9BIT_BLT(FALSE);
bltr.DRAWBLTDEF.DW = MAKELONG(0x04CC, BD_RES | BD_OP1);
lpDDHALData->YUVLeft = (USHORT)xDst; // Save 9th bit rect coords for main
lpDDHALData->YUVTop = (USHORT)yDst; // driver for exclusion purposes.
lpDDHALData->YUVXExt = (USHORT)cxClip;
lpDDHALData->YUVYExt = (USHORT)cyClip;
// tell main driver the rectangle is valid
lpDDHALData->DrvSemaphore |= DRVSEM_YUV_RECT_VALID;
}
else
bltr.DRAWBLTDEF.DW = MAKELONG(0x00CC, BD_RES | BD_OP1);
bltr.OP0_opRDRAM.DW = MAKELONG(xDst, yDst);
bltr.OP1_opRDRAM.DW = MAKELONG(xSrc, ySrc);
bltr.BLTEXT.DW = MAKELONG(cxClip, cyClip);
bltr.LNCNTL.W = SrcType << LN_YUV_SHIFT;
// Enable interpolation unless we have a palette (8bpp).
if (SrcType != LN_8BIT )
bltr.LNCNTL.W |= LN_XINTP_EN | LN_YINTP_EN;
bltr.SHRINKINC.w = 0x0000;
if ( cxClip < cxSrc )
{
bltr.LNCNTL.W |= LN_XSHRINK;
bltr.LNCNTL.W &= ~LN_XINTP_EN; // Clear Average bit for ALL shrinks
bltr.SHRINKINC.pt.X = (cxSrc / cxClip);
}
if ( cyDst < cySrc )
{
bltr.LNCNTL.W |= LN_YSHRINK;
bltr.LNCNTL.W &= ~LN_YINTP_EN;
bltr.SHRINKINC.pt.Y = (cySrc / cyDst);
}
if ( SrcType == LN_YUV422 || SrcType == LN_RGB565 )
{
if ( nBytesPixel == 1 )
bltr.SRCX = (USHORT)cxSrc; // If mixed mode is *2 already
else
bltr.SRCX = cxSrc * 2;
}
else
bltr.SRCX = cxSrc * nBytesPixel;
#ifdef TRACE_STRETCH
DBG_MESSAGE((" cSrc = %d , %d : cDst = %d , %d : cClip = %d , %d",
cxSrc, cySrc, cxDst, cyDst, cxClip, cyClip));
#endif
// Compute DDA terms.
nDst[0] = cxClip; nDst[1] = cyDst;
nSrc[0] = cxSrc; nSrc[1] = cySrc;
for (i = 0; i < 2; i++)
{
int kDst = 1;
if (bltr.LNCNTL.W & ((i==0) ? LN_XINTP_EN : LN_YINTP_EN))
{
nDst[i] *= 4;
nSrc[i] *= 4;
nSrc[i] -= 3;
kDst = 0x8000 / nDst[i];
}
if (bltr.LNCNTL.W & ((i==0) ? LN_XSHRINK : LN_YSHRINK))
{ /* Shrink Terms */
axis[i].maj = (short)nDst[i];
axis[i].min = - (nSrc[i] % nDst[i]);
axis[i].accum = axis[i].maj - 1
- ((nSrc[i] % nDst[i]) / (nSrc[i]/nDst[i] + 1));
}
else
{ /* Stretch Terms */
axis[i].maj = kDst * nDst[i];
axis[i].min = -kDst * nSrc[i];
axis[i].accum = axis[i].maj - 1
- ((axis[i].maj % -axis[i].min) / (nDst[i]/nSrc[i] + 1));
}
} // endfor
bltr.MAJ_X = axis[0].maj;
bltr.MIN_X = axis[0].min;
bltr.ACCUM_X = axis[0].accum;
bltr.MAJ_Y = axis[1].maj;
bltr.MIN_Y = axis[1].min;
bltr.ACCUM_Y = axis[1].accum;
if ( ((SrcType == LN_8BIT) || (SrcType == LN_YUV422))
&& !(bltr.LNCNTL.W & LN_XSHRINK) )
{
// Put DDA parameter check/adjust (Optional for 5462/required for 5464)
const short maj_x = bltr.MAJ_X;
const short min_x = bltr.MIN_X;
short xaccum = bltr.ACCUM_X;
short copy_xDst = bltr.BLTEXT.pt.X;
short src_ext;
short inc_dx = 1;
short inc_sx = 0;
short SrcDstSz;
SrcDstSz = ( SrcType == LN_8BIT ) ? 1 : 2 ;
if ( (bltr.LNCNTL.W & LN_XSHRINK) )
inc_sx = bltr.SHRINKINC.pt.X;
inc_sx *= SrcDstSz;
inc_dx *= SrcDstSz;
copy_xDst *= (short)nBytesPixel;
src_ext = SrcDstSz; // Source size starts with a pixel !!
do
{ // Step through the X DDA accounting for src pixels consumed
copy_xDst -= inc_dx;
src_ext += inc_sx;
xaccum += min_x;
if ( xaccum < 0 )
{
xaccum += maj_x;
src_ext += SrcDstSz;
}
} while ( copy_xDst > 0 );
bltr.SRCX = src_ext;
// End DDA parameter check / adjust.
CALL_DRV_STR_BLT(&bltr); // Single stretch
if ( (SrcType == LN_YUV422) )
CALL_DELAY_9BIT_BLT(TRUE);
}
// else if (SrcType == LN_RGB565 && !(bltr.LNCNTL.W & LN_XSHRINK))
else if (SrcType == LN_RGB565)
{
// HWBUG !!! -- Break into sram-aligned vertical tiles
// based on destination alignment
// dword and tile masks
const int mdwrd = 4 ;
const int mtile_s = 128 - 1; // sram is 128 bytes
int mtile_d = 128 - 1 ; // 5464 Dest Workaround half tile size mask
int endx = xDst + cxClip; // last x, exclusive
int dstxe = endx & ~mtile_d; // start of last tile
int accx = axis[0].accum;
int dstx = xDst;
int srcx = xSrc;
int src_ext = 0;
int sav_accx;
int sav_dstx;
int sav_srcx;
int sav_src_ext;
int copy_srcx;
int xext;
int inc_sx;
#ifndef WINNT_VER40
ASSERT( BITSPERPIXEL != 24 ); // HWBUG !!!
#endif
if (bltr.LNCNTL.W & LN_XSHRINK)
{
mtile_d = 128 - 1;
dstxe = endx & ~mtile_d;
}
if ( nBytesPixel == 2 )
{
cxSrc *= 2; /* convert size to Bytes from pixels */
cxDst *= 2;
srcx = (xSrc *= 2);
dstx = (xDst *= 2);
bltr.OP0_opRDRAM.pt.X *= 2;
bltr.OP1_opRDRAM.pt.X *= 2;
endx *= 2;
dstxe = endx & ~mtile_d;
}
if (LGDEVID == CL_GD5464)
{
bltr.SHRINKINC.pt.X *= 2;
CALL_DRV_STR_MBLTY(&bltr); // Load the invariant registers
bltr.SHRINKINC.pt.X /= 2;
}
else
CALL_DRV_STR_MBLTY(&bltr); // Load the invariant registers
copy_srcx = bltr.SRCX;
while (dstx < dstxe)
{
bltr.OP0_opRDRAM.PT.X = (USHORT)dstx;
bltr.OP1_opRDRAM.PT.X = (USHORT)srcx;
bltr.ACCUM_X = (USHORT)accx;
xext = 0;
src_ext = 0;
inc_sx = bltr.SHRINKINC.pt.X * 2;
if ( bltr.LNCNTL.W & LN_XSHRINK )
{ // We have to treat the stretch / shrink cases differently
// because of the need to handle both SRC & DST aligned cases.
do
{
dstx += 2;
xext += 2;
accx += axis[0].min;
srcx += inc_sx;
src_ext += inc_sx;
if ( !(srcx & mtile_s) )
break; // Try double striping !!
if (accx < 0)
{
accx += axis[0].maj;
srcx += 2;
src_ext += 2;
if ( !(srcx & mtile_s) )
break; // Try double striping !!
}
} while ((dstx + 4 ) & mtile_d);
sav_dstx = dstx;
sav_accx = accx;
sav_srcx = srcx;
sav_src_ext = src_ext;
do
{
dstx += 2;
xext += 2;
accx += axis[0].min;
srcx += inc_sx;
src_ext += inc_sx;
if ( !(srcx & mtile_s) )
break; // Try double striping !!
if (accx < 0)
{
accx += axis[0].maj;
srcx += 2;
src_ext += 2;
if ( !(srcx & mtile_s) )
break; // Try double striping !!
}
} while ((dstx) & mtile_d);
bltr.SRCX = (USHORT)src_ext;
}
else
{
do
{
dstx += 2;
xext += 2;
accx += axis[0].min;
if (accx < 0)
{
accx += axis[0].maj;
srcx += 2;
src_ext += 2;
if ( !(srcx & mtile_s) )
break; // Try double striping !!
}
} while (dstx & mtile_d);
bltr.SRCX = src_ext + 2;
sav_dstx = dstx;
sav_accx = accx;
sav_srcx = srcx;
sav_src_ext = src_ext;
}
bltr.BLTEXT.PT.X = (USHORT)xext;
CALL_DRV_STR_MBLTX(&bltr);
dstx = sav_dstx;
accx = sav_accx;
srcx = sav_srcx;
src_ext = sav_src_ext;
copy_srcx -= src_ext;
} // end while (dstx < dstxe)
// do the last tile
if (dstx < endx)
{
bltr.OP0_opRDRAM.PT.X = (USHORT)dstx;
bltr.OP1_opRDRAM.PT.X = (USHORT)srcx;
bltr.ACCUM_X = (USHORT)accx;
bltr.SRCX = (USHORT)copy_srcx;
bltr.BLTEXT.PT.X = endx - dstx;
CALL_DRV_STR_MBLTX(&bltr);
}
if ((SrcType == LN_YUV422) || (SrcType == LN_RGB565 && nBytesPixel == 1))
CALL_DELAY_9BIT_BLT(TRUE);
}
else
{
// HWBUG !!! -- Break into sram-aligned vertical tiles
// based on source alignment
// tile mask
const int mtile = 128; /* sram is 128 bytes */
const int mtile_mask = mtile - 1;
const short maj_x = bltr.MAJ_X;
const short min_x = bltr.MIN_X;
int endx = xDst + cxClip; // last x, exclusive, in pixels
short xaccum;
int dstx = xDst;
int srcx = xSrc;
int dst_ext;
int src_ext;
int copy_src_ext;
#ifndef WINNT_VER40
ASSERT( BITSPERPIXEL != 24 ); // HWBUG !!!
#endif
if ( nBytesPixel == 2 )
{
cxSrc *= 2; /* convert size to Bytes from pixels */
cxDst *= 2;
srcx = (xSrc *= 2);
dstx = (xDst *= 2);
bltr.OP0_opRDRAM.pt.X *= 2;
bltr.OP1_opRDRAM.pt.X *= 2;
endx *= 2; /* convert end marker to bytes */
}
#ifdef TRACE_STRETCH
#ifdef TRACE_ALL
DBG_MESSAGE((" mtile = %d maj = %d min = %d accum = %d shrinkinc = %04x",
mtile, maj_x, min_x, bltr.ACCUM_X, bltr.SHRINKINC));
#endif
#endif
if (LGDEVID == CL_GD5464 && SrcType != LN_8BIT)
{
bltr.SHRINKINC.pt.X *= 2;
CALL_DRV_STR_MBLTY(&bltr); // Load the invariant registers
bltr.SHRINKINC.pt.X /= 2;
}
else
CALL_DRV_STR_MBLTY(&bltr); // Load the invariant registers
do
{
// get alignment to first src tile / sram break;
if ( srcx & mtile_mask ) // initial alignment
{
src_ext = mtile - (srcx & mtile_mask);
if ( src_ext > cxSrc )
src_ext = cxSrc;
}
else
{
if ( cxSrc < mtile )
src_ext = cxSrc; // last partial tile
else
src_ext = mtile; // complete tile
}
srcx += src_ext; // account for amount of src consumed
cxSrc -= src_ext;
// calculate how many destination pixels == src_ext
xaccum = bltr.ACCUM_X;
dst_ext = 0;
copy_src_ext = src_ext;
do
{
dst_ext += 2;
copy_src_ext -= 2 * bltr.SHRINKINC.pt.X;
xaccum += min_x;
if ( xaccum < 0 )
{
xaccum += maj_x;
copy_src_ext -= 2;
}
} while ( copy_src_ext > 0 && (dstx + dst_ext <= endx) );
dst_ext &= ~3; /* force destination extent to DWORDs */
dstx += dst_ext;
#ifdef TRACE_STRETCH
#ifdef TRACE_ALL
DBG_MESSAGE((" srcx = %d src_ext = %d cxSrc = %d dstx = %d dst_ext = %d end = %d",
srcx, src_ext, cxSrc, dstx, dst_ext, endx ));
#endif
#endif
if ( SrcType == LN_RGB565 )
bltr.SRCX = src_ext + 2;
else
bltr.SRCX = (USHORT)src_ext;
bltr.BLTEXT.pt.X = (USHORT)dst_ext;
if ( dst_ext > 0 )
CALL_DRV_STR_MBLTX(&bltr);
bltr.ACCUM_X = xaccum;
bltr.OP0_opRDRAM.pt.X += (USHORT)dst_ext;
bltr.OP1_opRDRAM.pt.X += (USHORT)src_ext;
} while ( (dstx < endx) && ( cxSrc > 0));
xFill = bltr.OP0_opRDRAM.pt.X;
cxFill = (xDst + cxDst) - xFill;
#ifdef TRACE_STRETCH
DBG_MESSAGE((" srcx=%d src_ext=%d cxSrc=%d dstx=%d dst_ext=%d end=%d xFill=%d cxFill=%d",
srcx, src_ext, cxSrc, dstx, dst_ext, endx, xFill, cxFill ));
#endif
// Edge Fill for trailing edge was deferred. Calculate correct amount
// Taking into account pixels skipped above for alignment.
//
if ((cxFill > 0) && (cxClip = (xFill & 7)) &&
((SrcType == LN_YUV422)||((nBytesPixel == 1) && (SrcType == LN_RGB565))))
{ // these must be extra pixels. They must be filled using
// the same 9th bit and in the same format as the stretch
if ( SrcType == LN_YUV422 )
CALL_MEDGE_FILL_BLT(xFill, yFill, cxFill, cyFill,
MAKELONG(BOGUS_YUV, BOGUS_YUV), TRUE);
else
CALL_MEDGE_FILL_BLT(xFill, yFill, cxFill, cyFill,
0x00000000, TRUE);
xFill = bltr.OP0_opRDRAM.pt.X + cxClip;
cxFill -= cxClip;
}
if ((SrcType == LN_YUV422) || (SrcType == LN_RGB565 && nBytesPixel == 1))
CALL_DELAY_9BIT_BLT(TRUE);
if ( cxFill > 0 )
{
/* perform edge fill Blt */
if ( nBytesPixel == 2 )
CALL_MEDGE_FILL_BLT(xFill, yFill, cxFill, cyFill,
MAKELONG(BOGUS_YUV, BOGUS_YUV), FALSE);
else
CALL_EDGE_FILL_BLT(xFill, yFill, cxFill, cyFill,
0x00000000, FALSE);
}
}
} // DrvStretch64
/***************************************************************************
*
* FUNCTION: DrvStretch62
*
* DESCRIPTION: The 5462 doesn't do display list programming, so
* all blts must be direct (call the DIR_XXX functions)
*
****************************************************************************/
void DRVSTRETCH62
#ifndef WINNT_VER40
LPGLOBALDATA lpDDHALData,
#endif
int xDst, int yDst, int cxDst, int cyDst,
int xSrc, int ySrc, int cxSrc, int cySrc,
int nBytesPixel, int SrcType, int BaseOffset,
int OnScreen)
{
int cxClip = cxDst;
int cyClip = cyDst;
int cxFill = 0;
int cyFill = cyDst;
int xFill = xDst;
int yFill = yDst;
int cxTrim = 0;
int iratio, i;
#ifdef RDRAM_8BIT
PVGAR pREG = (PVGAR) lpDDHALData->RegsAddress;
#endif
autoblt_regs bltr;
AXIS axis[2];
int nDst[2];
int nSrc[2];
#ifdef RDRAM_8BIT
RECTL SrcRectl;
int nFound = FALSE;
#endif
DD_LOG(("DrvStretch62 - dst=%08lX dstext=%08lX src=%08lX srcext=%08lX\r\n",
MAKELONG(xDst,yDst),MAKELONG(cxDst,cyDst),
MAKELONG(xSrc,ySrc),MAKELONG(cxSrc,cySrc)));
#ifdef RDRAM_8BIT
if (!lpDDHALData->fNineBitRDRAMS)
{
if (SrcType == LN_YUV422)
{
SrcRectl.left = xSrc;
SrcRectl.top = ySrc;
SrcRectl.right = xSrc+cxSrc;
SrcRectl.bottom = ySrc+cySrc;
if (MEMCMP(&SrcRectl, sizeof(SrcRectl)) == 0)
nFound = TRUE;
if (nFound)
{
#if 0
DBG_MESSAGE(("Stretch: Found Offscreen Area P1(%x,%x) P2(%x,%x) Dst(%x, %x) Dst(%x %x)\n",
SrcRectl.left,
SrcRectl.top,
SrcRectl.right,
SrcRectl.bottom,
xDst,
yDst,
xDst+cxDst,
yDst+cyDst));
#endif
LL16(grX_Start_2, xDst + ((4 - (xDst & 3)) & 3));
LL16(grY_Start_2, yDst);
LL16(grX_End_2, xDst+(cxDst>>3<<3));
LL16(grY_End_2, yDst+cyDst);
}
else
{
#if 0
DBG_MESSAGE(("Stretch: Not Found Offscreen Area P1(%x,%x) P2(%x,%x)\n",
SrcRectl.left,
SrcRectl.top,
SrcRectl.right,
SrcRectl.bottom));
#endif
LL16(grX_Start_2, 0);
LL16(grY_Start_2, 0);
LL16(grX_End_2, 0);
LL16(grY_End_2, 0);
// Black Blit Here
CALL_DIR_DRV_DST_BLT(0x107000CC,MAKELONG(xDst,yDst),0,MAKELONG(cxDst,cyDst));
return ;
}
} // endif (SrcType == LN_YUV422)
} // endif (!lpDDHALData->fNineBitRDRAMS)
#endif
#ifdef TRACE_STRETCH
DBG_MESSAGE(("DrvStretch62: %4d,%4d %4dx%4d -> %4d,%4d %4dx%4d (%d %d) %d",
xSrc, ySrc, cxSrc, cySrc,
xDst, yDst, cxDst, cyDst,
nBytesPixel, SrcType, BaseOffset));
#endif
if ((SrcType == LN_YUV422) ||
((SrcType == LN_RGB565) && (nBytesPixel == 1)))
{ // Force alignment of output to QWORD ( it is documented as DWORD but broken)
if ( nBytesPixel == 2 )
{ // 16 bit frame buffer ( Note all ptrs/extents in terms of 16 bpp )
// The X portions will be mutiplied by 2 by chip on being written )
if ( cxDst > cxSrc )
iratio = cxDst / cxSrc; // integer ratio of stretch
else
iratio = cxSrc / cxDst; // integer ratio of shrink
if ( xDst & 3 ) /* This should be for LN_YUV422 only */
{
cxFill = 4 - (xDst & 3);
cxTrim = cxFill; // save trim count for source clipping if required
if ( cxFill > cxClip )
cxFill = cxClip; // check for no stretch left
cxClip -= cxFill; /* reduce size */
cxDst -= cxFill; /* reduce size */
xDst += cxFill; /* force alignment to next even DWORD boundary */
CALL_DIR_DRV_DST_BLT(MAKELONG(0x0000,BD_RES),MAKELONG(xFill,yFill),
0,MAKELONG(cxFill,cyFill));
#ifdef TRACE_STRETCH
DBG_MESSAGE((" Edge Fill(1) %d,%d %d x %d", xFill, yFill, cxFill, cyFill));
#endif
} //endif ( xDst & 3 )
cxFill = cxClip & 3;
if ( cxFill )
{
cxClip -= cxFill; /* force size to next smaller even DWORD count */
xFill = xDst + cxClip;
if ( cxClip >= cxSrc)
{ // If shrink defer edge fill to later as there may be more
CALL_DIR_EDGE_FILL_BLT(xFill, yFill, cxFill, cyFill,
MAKELONG(BOGUS_YUV, BOGUS_YUV), FALSE);
#ifdef TRACE_STRETCH
DBG_MESSAGE((" Edge Fill(2) %d,%d %d x %d", xFill, yFill, cxFill, cyFill));
#endif
} // endif ( cxClip >= cxSrc)
} // endif ( cxFill )
if ( (cxClip < cxSrc) )
{ // Edge Clip on shrinks only ( add config flag check here )
int excess;
// extra pixels to discard above integer ratio
excess = ( cxSrc / iratio ) - cxClip;
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#ifdef WINNT_VER40 // WINNT_VER40
DISPDBG((DBGLVL1,
"DDraw - Edge Clip iratio = %d excess = %d Trim %% = %d",
iratio, excess, 2));
#else // ----- #elseif WINNT_VER40 -----
DBG_MESSAGE((" Edge Clip iratio = %d excess = %d Trim %% = %d", iratio, excess, 2));
#endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
if ( excess && cxTrim )
{ // These excess pixels are caused by our Dest alignment
// problems on the Left edge
if ( excess < (cxTrim * iratio) )
{
cxSrc -= excess;
xSrc += excess;
excess = 0;
}
else
{
cxSrc -= cxTrim * iratio;
xSrc += cxTrim * iratio;
excess -= cxTrim * iratio;
}
} // endif ( excess && cxTrim )
if ( excess && cxFill)
{ // These excess pixels are caused by our Dest alignment
// problems on the Right edge
if ( excess < (cxFill * iratio) )
{
cxSrc -= excess;
excess = 0;
}
else
{
cxSrc -= cxFill * iratio;
excess -= cxFill * iratio;
}
} // endif ( excess < (cxFill * iratio) )
if ( excess && (excess < (2 * cxClip)/100 ))
{ // if excess is less than 2% of frame trim edges
int trim = excess / 2; // half the excess of pixels
xSrc += trim; // offset pixel pointer
cxSrc -= excess; // all the excess in pixels
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#ifdef WINNT_VER40 // WINNT_VER40
DISPDBG((DBGLVL1,
"DDraw - Edge Clip Left = %d, xSrc = %d, cxSrc = %d",
trim, xSrc, cxSrc));
#else // ----- #elseif WINNT_VER40 -----
DBG_MESSAGE((" Edge Clip Left = %d, xSrc = %d, cxSrc = %d", trim, xSrc, cxSrc));
#endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
}
if ( iratio == 1 )
{ // we may have just changed a shrink to a 1 : 1
// if excess is zero do edge fill now
// extra pixels to discard above integer ratio
excess = ( cxSrc / iratio ) - cxClip;
if ( !excess && cxFill )
{
xFill = xDst + cxClip;
CALL_DIR_EDGE_FILL_BLT(xFill, yFill, cxFill, cyFill,
MAKELONG(BOGUS_YUV, BOGUS_YUV), FALSE);
#ifdef TRACE_STRETCH
DBG_MESSAGE((" Edge Fill(7) %d,%d %d x %d", xFill, yFill, cxFill, cyFill));
#endif
}
} // endif ( iratio == 1 )
}
else
{ // Stretch adjustments
if ( xSrc - BaseOffset )
{ // if we are not starting from left edge of source image
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#ifdef WINNT_VER40 // WINNT_VER40
DISPDBG((DBGLVL1,
"DDraw - Edge Trim for stretch iratio = %d , cxTrim = %d xSrc %d",
iratio, cxTrim, xSrc));
#else // ----- #elseif WINNT_VER40 -----
DBG_MESSAGE((" Edge Trim for stretch iratio = %d , cxTrim = %d xSrc %d", iratio, cxTrim, xSrc));
#endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
if ( cxTrim )
{ // And we were forced to offset for left edge alignment
cxSrc -= cxTrim / iratio;
xSrc += cxTrim / iratio;
}
}
} // endif ( (cxClip < cxSrc) )
// Global adjustments
if ( xSrc & 1 ) /* HW bug workaound for clipping */
{
xSrc += 1; /* Align to SRC DWORD Boundary */
cxSrc -= 1; /* Account for smaller size */
}
}
else
{ // 8 Bit frame buffer.
// Force alignment of output to QWORD ( it is documented as DWORD but broken)
if ( cxDst >= (cxSrc*2) )
iratio = cxDst / (2 * cxSrc); // integer ratio of stretch
else
iratio = (2 * cxSrc ) / cxDst; // integer ratio of shrink
if ( xDst & 7 ) /* This should be for LN_YUV422 only */
{
cxFill = 8 - (xDst & 7);
if ( cxFill > cxClip )
cxFill = cxClip; // check for no stretch left
cxClip -= cxFill; /* reduce size */
cxDst -= cxFill; /* reduce size */
xDst += cxFill; /* force alignment to next even WORD boundary */
CALL_DIR_DRV_DST_BLT(MAKELONG(0x0000,BD_RES),MAKELONG(xFill,yFill),
0,MAKELONG(cxFill,cyFill));
#ifdef TRACE_STRETCH
DBG_MESSAGE((" Edge Fill(3) %d,%d %d x %d", xFill, yFill, cxFill, cyFill));
#endif
} // endif ( xDst & 7 )
cxFill = cxClip & 7;
if ( cxFill )
{
cxClip -= cxFill; /* force size to next smaller even DWORD count */
if ( cxClip >= (cxSrc * 2))
{ // If shrink defer edge fill to later as there may be more
xFill = xDst + cxClip;
#ifdef BOGUS_8BIT
CALL_DIR_EDGE_FILL_BLT(xFill, yFill, cxFill, cyFill,
MAKELONG(BOGUS_YUV, BOGUS_YUV), FALSE);
#else
CALL_DIR_DRV_DST_BLT(MAKELONG(0x0000,BD_RES),MAKELONG(xFill,yFill),
0,MAKELONG(cxFill,cyFill));
#endif
#ifdef TRACE_STRETCH
DBG_MESSAGE((" Edge Fill(4) %d,%d %d x %d", xFill, yFill, cxFill, cyFill));
#endif
}
} // endif ( cxFill )
// change pixel pointer to byte pointer
// taking account of X origin of buffer
xSrc = BaseOffset + (xSrc - BaseOffset) * 2;
cxSrc *= 2; /* change pixel count to byte count */
#ifdef EDGE_CLIP
if ( (cxClip < cxSrc) && lpDDHALData->EdgeTrim)
{ // Edge Clip on shrinks only ( add config flag check here )
int excess;
// extra pixels to discard above integer ratio
excess = ( cxSrc / iratio ) - cxClip;
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#ifdef WINNT_VER40 // WINNT_VER40
DISPDBG((DBGLVL1,
"DDraw - Edge Clip iratio = %d excess = %d Trim %% = %d",
iratio, excess, lpDDHALData->EdgeTrim));
#else // ----- #elseif WINNT_VER40 -----
DBG_MESSAGE((" Edge Clip iratio = %d excess = %d Trim %% = %d",
iratio, excess, lpDDHALData->EdgeTrim));
#endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
if ( excess && cxTrim )
{ // These excess pixels are caused by our Dest alignment
// problems on the Left edge
if ( excess < (cxTrim * iratio) )
{
cxSrc -= excess;
xSrc += excess;
excess = 0;
}
else
{
cxSrc -= cxTrim * iratio;
xSrc += cxTrim * iratio;
excess -= cxTrim * iratio;
}
} // endif ( excess && cxTrim )
if ( excess && cxFill)
{ // These excess pixels are caused by our Dest alignment
// problems on the Right edge
if ( excess < (cxFill * iratio) )
{
cxSrc -= excess;
excess = 0;
}
else
{
cxSrc -= cxFill * iratio;
excess -= cxFill * iratio;
}
} // endif ( excess && cxFill)
if ( excess && ( excess < (lpDDHALData->EdgeTrim * cxClip)/100 ) )
{ // if excess is less than specific % of frame trim edges
int trim = excess / 2; // half the excess as pixels
xSrc += trim; // offset pixel pointer
cxSrc -= excess; // all the excess in bytes
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#ifdef WINNT_VER40 // WINNT_VER40
DISPDBG((DBGLVL1,
"DDraw - Edge Clip Left = %d, xSrc = %d, cxSrc = %d",
trim, xSrc, cxSrc));
#else // ----- #elseif WINNT_VER40 -----
DBG_MESSAGE((" Edge Clip Left = %d, xSrc = %d, cxSrc = %d",
trim, xSrc, cxSrc));
#endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
}
if ( iratio == 1 )
{ // we may have just changed a shrink to a 1 : 1
// if excess is no zero do edge fill now
// extra pixels to discard above integer ratio
excess = ( cxSrc / iratio ) - cxClip;
if ( !excess && cxFill )
{
xFill = xDst + cxClip;
#ifdef BOGUS_8BIT
CALL_DIR_EDGE_FILL_BLT(xFill, yFill, cxFill, cyFill,
MAKELONG(BOGUS_YUV, BOGUS_YUV), FALSE);
#else
CALL_DIR_DRV_DST_BLT(MAKELONG(0x0000,BD_RES),MAKELONG(xFill,yFill),
0,MAKELONG(cxFill,cyFill));
#endif
#ifdef TRACE_STRETCH
DBG_MESSAGE((" Edge Fill(6) %d,%d %d x %d", xFill, yFill, cxFill, cyFill));
#endif
} // endif ( !excess && cxFill )
} // endif ( iratio == 1 )
} // endif ( (cxClip < cxSrc) && lpDDHALData->EdgeTrim)
#endif
if ( xSrc & 3 ) /* HW bug workaound for clipping */
{
cxSrc -= 4 - (xSrc & 3); // reduce size
xSrc = (xSrc + 3) & ~ 3; // Align to SRC DWORD Boundary
}
} // endif ( nBytesPixel == 2 )
}
if ( cxClip == 0 )
return; // discard zero extent stretchs
if ( nBytesPixel == 1 &&
((SrcType == LN_YUV422) || (SrcType == LN_RGB565 )) ||
((nBytesPixel == 2) && (SrcType == LN_YUV422) ) )
{
/* This is to ensure that the last packet of any previous blt */
/* does no go out with 9th bit set */
CALL_DIR_DELAY_9BIT_BLT(FALSE);
bltr.DRAWBLTDEF.DW = MAKELONG(0x04CC, BD_RES | BD_OP1);
lpDDHALData->YUVLeft = (USHORT)xDst; // Save 9th bit rect coords for main
lpDDHALData->YUVTop = (USHORT)yDst; // driver for exclusion purposes.
lpDDHALData->YUVXExt = (USHORT)cxClip;
lpDDHALData->YUVYExt = (USHORT)cyClip;
// tell main driver the rectangle is valid
lpDDHALData->DrvSemaphore |= DRVSEM_YUV_RECT_VALID;
}
else
bltr.DRAWBLTDEF.DW = MAKELONG(0x00CC, BD_RES | BD_OP1);
bltr.OP0_opRDRAM.DW = MAKELONG(xDst, yDst);
bltr.OP1_opRDRAM.DW = MAKELONG(xSrc, ySrc);
bltr.BLTEXT.DW = MAKELONG(cxClip, cyClip);
bltr.LNCNTL.W = SrcType << LN_YUV_SHIFT;
// Enable interpolation unless we have a palette (8bpp).
if (SrcType != LN_8BIT )
bltr.LNCNTL.W |= LN_XINTP_EN | LN_YINTP_EN;
bltr.SHRINKINC.w = 0x0000;
if ( cxClip < cxSrc )
{
bltr.LNCNTL.W |= LN_XSHRINK;
bltr.LNCNTL.W &= ~LN_XINTP_EN;
bltr.SHRINKINC.pt.X = (cxSrc / cxClip);
}
if ( cyDst < cySrc )
{
bltr.LNCNTL.W |= LN_YSHRINK;
bltr.LNCNTL.W &= ~LN_YINTP_EN;
bltr.SHRINKINC.pt.Y = (cySrc / cyDst);
}
if ( SrcType == LN_YUV422 || SrcType == LN_RGB565 )
{
if ( nBytesPixel == 1 )
bltr.SRCX = (USHORT)cxSrc; // If mixed mode is *2 already
else
bltr.SRCX = cxSrc * 2;
}
else
bltr.SRCX = cxSrc * nBytesPixel;
#ifdef TRACE_STRETCH
DBG_MESSAGE((" cSrc = %d , %d : cDst = %d , %d : cClip = %d , %d",
cxSrc, cySrc, cxDst, cyDst, cxClip, cyClip));
#endif
// Compute DDA terms.
nDst[0] = cxClip; nDst[1] = cyDst;
nSrc[0] = cxSrc; nSrc[1] = cySrc;
for (i = 0; i < 2; i++)
{
int kDst = 1;
if (bltr.LNCNTL.W & ((i==0) ? LN_XINTP_EN : LN_YINTP_EN))
{
nDst[i] *= 4;
nSrc[i] *= 4;
nSrc[i] -= 3;
kDst = 0x8000 / nDst[i];
}
if (bltr.LNCNTL.W & ((i==0) ? LN_XSHRINK : LN_YSHRINK))
{ /* Shrink Terms */
axis[i].maj = (short)nDst[i];
axis[i].min = - (nSrc[i] % nDst[i]);
axis[i].accum = axis[i].maj - 1
- ((nSrc[i] % nDst[i]) / (nSrc[i]/nDst[i] + 1));
}
else
{ /* Stretch Terms */
axis[i].maj = kDst * nDst[i];
axis[i].min = -kDst * nSrc[i];
axis[i].accum = axis[i].maj - 1
- ((axis[i].maj % -axis[i].min) / (nDst[i]/nSrc[i] + 1));
}
} // endfor (i = 0; i < 2; i++)
bltr.MAJ_X = axis[0].maj;
bltr.MIN_X = axis[0].min;
bltr.ACCUM_X = axis[0].accum;
bltr.MAJ_Y = axis[1].maj;
bltr.MIN_Y = axis[1].min;
bltr.ACCUM_Y = axis[1].accum;
if ((SrcType == LN_8BIT) ||
((SrcType == LN_YUV422) && !(bltr.LNCNTL.W & LN_XSHRINK)) )
{
CALL_DIR_DRV_STR_BLT(&bltr); // Single stretch
if ( (SrcType == LN_YUV422) )
{
// This is to ensure that the last packet of blt does no go out with
// 9th bit clear It is cheaper than waiting, especially on single
// stripe BLTs
CALL_DIR_DELAY_9BIT_BLT(TRUE);
}
}
else if (SrcType == LN_RGB565 && !(bltr.LNCNTL.W & LN_XSHRINK))
#if 1
{
// HWBUG !!! -- Break into sram-aligned vertical tiles
// based on destination alignment
// dword and tile masks
const int mdwrd = 4 ;
const int tile = 128 ; /* sram is 128 bytes */
const int mtile = 128 - 1 ; /* sram is 128 bytes */
int endx = xDst + cxClip; // last x, exclusive
int dstxe = endx & ~mtile; // start of last tile
DDAX accx = axis[0].accum;
int dstx = xDst;
int srcx = xSrc;
int src_ext = 0;
int xext;
#ifndef WINNT_VER40
ASSERT( BITSPERPIXEL != 24 ); // HWBUG !!!
#endif
if ( nBytesPixel == 2 )
{
cxSrc *= 2; /* convert size to Bytes from pixels */
cxDst *= 2;
srcx = (xSrc *= 2);
dstx = (xDst *= 2);
bltr.OP0_opRDRAM.pt.X *= 2;
bltr.OP1_opRDRAM.pt.X *= 2;
endx *= 2;
dstxe = endx & ~mtile;
}
CALL_DIR_DRV_STR_MBLTY(&bltr); // load the invariant sections of the engine
// step to the next tile
xext = 0;
while ((dstx & mtile) && (dstx < endx))
{
dstx += 2;
xext += 2;
accx += axis[0].min;
if (accx < 0)
{
accx += axis[0].maj;
srcx += 2;
src_ext += 2;
}
} // endwhile ((dstx & mtile) && (dstx < endx))
// do the odd pixels we stepped over
if (xext)
{
bltr.BLTEXT.PT.X = (USHORT)xext;
CALL_DIR_DRV_STR_MBLTX(&bltr);
}
// do all the whole tiles but the last
bltr.SRCX -= (USHORT)src_ext;
while (dstx < dstxe)
{
bltr.OP0_opRDRAM.PT.X = (USHORT)dstx;
bltr.OP1_opRDRAM.PT.X = (USHORT)srcx;
bltr.ACCUM_X = accx;
xext = 0;
src_ext = 0;
do
{
dstx += 2;
xext += 2;
accx += axis[0].min;
if (accx < 0)
{
accx += axis[0].maj;
srcx += 2;
src_ext += 2;
}
} while (dstx & mtile);
bltr.BLTEXT.PT.X = (USHORT)xext;
CALL_DIR_DRV_STR_MBLTX(&bltr);
bltr.SRCX -= (USHORT)src_ext;
} // endwhile (dstx < dstxe)
// do the last tile
if (dstx < endx)
{
bltr.OP0_opRDRAM.PT.X = (USHORT)dstx;
bltr.OP1_opRDRAM.PT.X = (USHORT)srcx;
bltr.ACCUM_X = accx;
bltr.BLTEXT.PT.X = endx - dstx;
CALL_DIR_DRV_STR_MBLTX(&bltr);
}
if ( (SrcType == LN_YUV422) || (SrcType == LN_RGB565 && nBytesPixel == 1) )
{
// This is to ensure that the last packet of stretch blt does no go out
// with 9th bit clear. It is cheaper than waiting, especially on single
// stripe BLTs
CALL_DIR_DELAY_9BIT_BLT(TRUE);
}
}
#else
{
// HWBUG !!! -- Break into Double aligned vertical stripes
// based on src and dest alignment
// dword and tile masks
const int mdwrd = 4 ;
const int tile = 128 ; /* sram is 128 bytes */
const int mtile = 128 - 1 ; /* sram is 128 bytes */
int endx = xDst + cxClip; // last x, exclusive
int dstxe = endx & ~mtile; // start of last tile
DDAX accx = axis[0].accum;
int dstx = xDst;
int srcx = xSrc;
int src_ext = 0;
int xext;
#ifndef WINNT_VER40
ASSERT( BITSPERPIXEL != 24 ); // HWBUG !!!
#endif
if ( nBytesPixel == 2 )
{
cxSrc *= 2; /* convert size to Bytes from pixels */
cxDst *= 2;
srcx = (xSrc *= 2);
dstx = (xDst *= 2);
bltr.OP0_opRDRAM.pt.X *= 2;
bltr.OP1_opRDRAM.pt.X *= 2;
endx *= 2;
dstxe = endx & ~mtile;
}
// step to the next tile
xext = 0;
while ((dstx & mtile) && (dstx < endx))
{
dstx += 2;
xext += 2;
accx += axis[0].min;
if (accx < 0)
{
accx += axis[0].maj;
srcx += 2;
src_ext += 2;
}
}
// do the odd pixels we stepped over
if (xext)
{
bltr.BLTEXT.PT.X = xext;
CALL_DIR_DRV_STR_MBLT(&bltr);
}
// do all the whole tiles but the last
bltr.SRCX -= src_ext;
while (dstx < dstxe)
{
bltr.OP0_opRDRAM.PT.X = dstx;
bltr.OP1_opRDRAM.PT.X = srcx;
bltr.ACCUM_X = accx;
xext = 0;
src_ext = 0;
do
{
dstx += 2;
xext += 2;
accx += axis[0].min;
if (accx < 0)
{
accx += axis[0].maj;
srcx += 2;
src_ext += 2;
}
} while (dstx & mtile);
bltr.BLTEXT.PT.X = xext;
CALL_DIR_DRV_STR_MBLT(&bltr);
}
// do the last tile
if (dstx < endx)
{
bltr.OP0_opRDRAM.PT.X = dstx;
bltr.OP1_opRDRAM.PT.X = srcx;
bltr.ACCUM_X = accx;
bltr.BLTEXT.PT.X = endx - dstx;
CALL_DIR_DRV_STR_MBLT(&bltr);
}
if ( (SrcType == LN_YUV422) || (SrcType == LN_RGB565 && nBytesPixel == 1) )
{
/* This is to ensure that the last packet of stretch blt does no go out with 9th bit clear */
/* It is cheaper than waiting, especially on single stripe BLTs */
CALL_DIR_DELAY_9BIT_BLT(TRUE);
}
}
#endif
else
{
// HWBUG !!! -- Break into sram-aligned vertical tiles
// based on source alignment
// tile mask
const int mtile = 128; /* sram is 128 bytes */
const int mtile_mask = mtile - 1;
const short maj_x = bltr.MAJ_X;
const short min_x = bltr.MIN_X;
int endx = xDst + cxClip; // last x, exclusive, in pixels
short xaccum;
int dstx = xDst;
int srcx = xSrc;
int dst_ext;
int src_ext;
int copy_src_ext;
#ifndef WINNT_VER40
ASSERT( BITSPERPIXEL != 24 ); // HWBUG !!!
#endif
if ( nBytesPixel == 2 )
{
cxSrc *= 2; /* convert size to Bytes from pixels */
cxDst *= 2;
srcx = (xSrc *= 2);
dstx = (xDst *= 2);
bltr.OP0_opRDRAM.pt.X *= 2;
bltr.OP1_opRDRAM.pt.X *= 2;
endx *= 2; /* convert end marker to bytes */
}
#ifdef TRACE_STRETCH
#ifdef TRACE_ALL
DBG_MESSAGE((" mtile = %d maj = %d min = %d accum = %d shrinkinc = %04x",
mtile, maj_x, min_x, bltr.ACCUM_X, bltr.SHRINKINC));
#endif
#endif
CALL_DIR_DRV_STR_MBLTY(&bltr); // Load the invariant registers
do
{
// get alignment to first src tile / sram break;
if ( srcx & mtile_mask ) // initial alignment
{
src_ext = mtile - (srcx & mtile_mask);
if ( src_ext > cxSrc )
src_ext = cxSrc;
}
else
{
if ( cxSrc < mtile )
src_ext = cxSrc; // last partial tile
else
src_ext = mtile; // complete tile
}
srcx += src_ext; // account for amount of src consumed
cxSrc -= src_ext;
// calculate how many destination pixels == src_ext
xaccum = bltr.ACCUM_X;
dst_ext = 0;
copy_src_ext = src_ext;
do
{
dst_ext += 2;
copy_src_ext -= 2 * bltr.SHRINKINC.pt.X;
xaccum += min_x;
if ( xaccum < 0 )
{
xaccum += maj_x;
copy_src_ext -= 2;
}
} while ( copy_src_ext > 0 && (dstx + dst_ext <= endx) );
dst_ext &= ~3; /* force destination extent to DWORDs */
dstx += dst_ext;
#ifdef TRACE_STRETCH
#ifdef TRACE_ALL
DBG_MESSAGE((" srcx = %d src_ext = %d cxSrc = %d dstx = %d dst_ext = %d end = %d",
srcx, src_ext, cxSrc, dstx, dst_ext, endx ));
#endif
#endif
bltr.BLTEXT.pt.X = (USHORT)dst_ext;
if ( dst_ext > 0 )
CALL_DIR_DRV_STR_MBLTX(&bltr);
bltr.ACCUM_X = xaccum;
bltr.OP0_opRDRAM.pt.X += (USHORT)dst_ext;
bltr.OP1_opRDRAM.pt.X += (USHORT)src_ext;
bltr.SRCX -= (USHORT)src_ext;
} while ( (dstx < endx) && ( cxSrc > 0));
xFill = bltr.OP0_opRDRAM.pt.X;
cxFill = (xDst + cxDst) - xFill;
#ifdef TRACE_STRETCH
DBG_MESSAGE((" srcx=%d src_ext=%d cxSrc=%d dstx=%d dst_ext=%d end=%d xFill=%d cxFill=%d",
srcx, src_ext, cxSrc, dstx, dst_ext, endx, xFill, cxFill ));
#endif
// Edge Fill for trailing edge was deferred. Calculate correct amount
// Taking into account pixels skipped above for alignment.
if ((cxFill > 0) && (cxClip = (xFill & 7)) && ((SrcType == LN_YUV422)||((nBytesPixel == 1) &&(SrcType == LN_RGB565))))
{// these must be extra pixels. They must be filled using
// the same 9th bit and in the same format as the stretch
cxClip = 8 - cxClip;
if ( SrcType == LN_YUV422 )
{
CALL_DIR_MEDGE_FILL_BLT(xFill,yFill,cxClip,cyFill,
MAKELONG(BOGUS_YUV-1,BOGUS_YUV-1),TRUE);
}
else
{
CALL_DIR_MEDGE_FILL_BLT(xFill,yFill,cxClip,cyFill,0,TRUE);
}
#ifdef TRACE_STRETCH
DBG_MESSAGE((" Edge Fill 9th bit set %d,%d %d x %d", xFill, yFill, cxFill, cyFill));
#endif
xFill = bltr.OP0_opRDRAM.pt.X + cxClip;
cxFill -= cxClip;
}
if ( (SrcType == LN_YUV422) || (SrcType == LN_RGB565 && nBytesPixel == 1) )
{
/* This is to ensure that the last packet of stretch blt does no go out with 9th bit clear */
/* It is cheaper than waiting, especially on single stripe BLTs */
CALL_DIR_DELAY_9BIT_BLT(TRUE);
}
if ( cxFill > 0 )
{
/* perform edge fill Blt */
#ifdef BOGUS_8BIT
CALL_DIR_MEDGE_FILL_BLT(xFill,yFill,cxFill,cyFill,
MAKELONG(BOGUS_YUV,BOGUS_YUV),FALSE);
#else
if ( nBytesPixel == 2 )
CALL_DIR_MEDGE_FILL_BLT(xFill,yFill,cxFill,cyFill,
MAKELONG(BOGUS_YUV,BOGUS_YUV),FALSE);
else
CALL_DIR_MEDGE_FILL_BLT(xFill,yFill,cxFill,cyFill,0,FALSE);
#endif
#ifdef TRACE_STRETCH
DBG_MESSAGE((" Edge Fill(5) %d,%d %d x %d", xFill, yFill, cxFill, cyFill));
#endif
}
}
} /* DrvStretch62 */
/***************************************************************************
*
* FUNCTION: StretchColor
*
* DESCRIPTION: This is a software solution for both the 5462 and 5464
* to perform a stretch or shrink while there is a source
* color key specified.
*
****************************************************************************/
void STRETCHCOLOR
#ifndef WINNT_VER40
LPGLOBALDATA lpDDHALData,
#endif
int xDst, int yDst, int cxDst, int cyDst,
int xSrc, int ySrc, int cxSrc, int cySrc,
DWORD ColorKey)
{
PVGAR pREG = (PVGAR) lpDDHALData->RegsAddress;
int xError, yError;
int xRun, yRun;
DD_LOG(("StretchColor - dst=%08lX dstext= %08lX src=%08lX srcext=%08lX colorkey=%08lX\r\n",
MAKELONG(xDst,yDst),MAKELONG(cxDst,cyDst),
MAKELONG(xSrc,ySrc),MAKELONG(cxSrc,cxSrc),
ColorKey));
// DD_LOG((" Beer break! - we're gonna blt every pixel one at a time\r\n"));
// Setup the hardware.
//LL32(grDRAWBLTDEF.DW, 0x101101CC);
//LL32(grOP_opBGCOLOR.DW, ColorKey);
// Initialize the error terms.
xError = ((cxSrc << 16) - 1) / cxDst + 1;
yError = ((cySrc << 16) - 1) / cyDst + 1;
// Y loop.
for (yRun = 0; cyDst--;)
{
int dst = xDst;
int src = xSrc;
int cx = cxDst;
// X loop.
for (xRun = 0; cx--;)
{
// Copy one pixel with color keying
//LL32(grOP0_opRDRAM.DW, MAKELONG(dst, yDst));
//LL32(grOP1_opRDRAM.DW, MAKELONG(src, ySrc));
//LL32(grOP2_opRDRAM.DW, MAKELONG(src, ySrc));
//LL32(grBLTEXT_EX.DW, MAKELONG(1, 1));
// this is bad but is needed for compatibility with display list
CALL_DRV_SRC_BLT(0x101101CC, // drawbltdef
MAKELONG(dst,yDst), // dst coord
MAKELONG(src,ySrc), // src coord
MAKELONG(src,ySrc), // colorkey coord
ColorKey, // colorkey
MAKELONG(1,1)); // extent
// Advance destination x.
dst++;
// Adjust x error term.
xRun += xError;
while (HIWORD(xRun))
{
// Advance source x.
src++;
xRun -= MAKELONG(0, 1);
}
}
// Advance destination y.
yDst++;
// Adjust y error term.
yRun += yError;
while (HIWORD(yRun))
{
// Advance source y.
ySrc++;
yRun -= MAKELONG(0, 1);
}
}
} /* StretchColor */
/***************************************************************************
*
* FUNCTION: TransparentStretch
*
* DESCRIPTION:
*
****************************************************************************/
void TRANSPARENTSTRETCH
#ifndef WINNT_VER40
LPGLOBALDATA lpDDHALData,
#endif
int xDst, int yDst, int cxDst, int cyDst,
int xSrc, int ySrc, int cxSrc, int cySrc,
DWORD ColorKey)
{
const int nBytesPixel = BYTESPERPIXEL;
const int nSRAMPixels = (SRAM_SIZE / nBytesPixel) / 2;
const int nSRAMMask = nSRAMPixels - 1;
autoblt_regs SrcToScratch;
int xScratch, yScratch;
int cxScratch, cyScratch;
AXIS axis[2];
int nDst[2];
int nSrc[2];
int i;
DDAX accx;
int srcx;
int xext;
int cxTemp;
int xTemp;
#ifndef WINNT_VER40
ASSERT(cxDst >= cxSrc);
#endif
xScratch = LOWORD(lpDDHALData->ScratchBufferOrg);
yScratch = HIWORD(lpDDHALData->ScratchBufferOrg);
cxScratch = cxDst;
cyScratch = cyDst;
// initialize auto blt struct for src to scratch buffer
SrcToScratch.DRAWBLTDEF.DW = MAKELONG(ROP_OP1_copy, (BD_RES+BD_OP1)*IS_VRAM);
SrcToScratch.OP0_opRDRAM.DW = MAKELONG(LOWORD(xScratch),LOWORD(yScratch));
SrcToScratch.OP1_opRDRAM.DW = MAKELONG(LOWORD(xSrc),LOWORD(ySrc));
SrcToScratch.LNCNTL.W = lncntl[nBytesPixel-1] << LN_YUV_SHIFT;
SrcToScratch.SRCX = cxSrc * nBytesPixel;
#if ENABLE_INTERPOLATED_BLTS
// Enable interpolation unless we have a palette (8bpp)
if (1 < nBytesPixel)
SrcToScratch.LNCNTL.W |= (LN_XINTP_EN | LN_YINTP_EN);
#endif
SrcToScratch.SHRINKINC.W = 0x0000;
if (cxDst < cxSrc)
{
SrcToScratch.LNCNTL.W |= LN_XSHRINK;
SrcToScratch.LNCNTL.W &= ~LN_XINTP_EN;
SrcToScratch.SHRINKINC.pt.X = (cxSrc / cxDst);
}
if ( cyDst < cySrc )
{
SrcToScratch.LNCNTL.W |= LN_YSHRINK;
SrcToScratch.LNCNTL.W &= ~LN_YINTP_EN;
SrcToScratch.SHRINKINC.pt.Y = (cySrc / cyDst);
}
SrcToScratch.BLTEXT.DW = MAKELONG(LOWORD(cxScratch),1);
// Compute DDA terms
nDst[0] = cxScratch;
nDst[1] = cyScratch;
nSrc[0] = cxSrc;
nSrc[1] = cySrc;
for (i = 0; i < 2; i++)
{
int kDst = 1;
#if ENABLE_INTERPOLATED_BLTS
if (SrcToScratch.LNCNTL.W & ((i==0) ? LN_XINTP_EN : LN_YINTP_EN))
{
nDst[i] *= 4;
nSrc[i] *= 4;
nSrc[i] -= 3;
kDst = 0x8000 / nDst[i];
}
#endif
if (SrcToScratch.LNCNTL.W & ((i==0) ? LN_XSHRINK : LN_YSHRINK))
{ /* Shrink Terms */
axis[i].maj = (short)nDst[i];
axis[i].min = - (nSrc[i] % nDst[i]);
axis[i].accum = axis[i].maj - 1
- ((nSrc[i] % nDst[i]) / (nSrc[i]/nDst[i] + 1));
}
else
{ /* Stretch Terms */
axis[i].maj = kDst * nDst[i];
axis[i].min = -kDst * nSrc[i];
axis[i].accum = axis[i].maj - 1
- ((axis[i].maj % -axis[i].min) / (nDst[i]/nSrc[i] + 1));
}
}
SrcToScratch.MAJ_X = axis[0].maj;
SrcToScratch.MIN_X = axis[0].min;
SrcToScratch.ACCUM_X = axis[0].accum;
SrcToScratch.MAJ_Y = axis[1].maj;
SrcToScratch.MIN_Y = axis[1].min;
SrcToScratch.ACCUM_Y = axis[1].accum;
// loop over scanlines in dst
// do two blts for each, one from src to scratch buffer
// then one from scratch buffer to dst
while (0 < cyDst)
{
// blt one scanline high from src to scratch buffer
// set values for initial stripe
xext = nSRAMPixels;
accx = SrcToScratch.ACCUM_X;
srcx = xSrc;
// write settings that don't vary over stripes to the chip
CALL_DRV_STR_BLTY(&SrcToScratch);
cxTemp = cxScratch;
xTemp = xScratch;
while (cxTemp > xext)
{
// update auto blt struct settings
SrcToScratch.OP0_opRDRAM.pt.X = (USHORT)xTemp;
SrcToScratch.OP1_opRDRAM.pt.X = (USHORT)srcx;
SrcToScratch.BLTEXT.pt.X = (USHORT)xext;
// blt current stripe
CALL_DRV_STR_BLTX(&SrcToScratch);
// increment xDst and decrement remaining dst extent
xTemp += xext;
cxTemp -= xext;
// walk DDA to compute error term (accx) and xSrc for next stripe
for (i = 0; i < xext; i++)
{
SrcToScratch.ACCUM_X += SrcToScratch.MIN_X;
if (0 > (short)SrcToScratch.ACCUM_X)
{
SrcToScratch.ACCUM_X += SrcToScratch.MAJ_X;
srcx++;
}
}
}
// if there's some area left to blt, then do it
if (0 < cxTemp)
{
// update auto blt struct settings
SrcToScratch.OP0_opRDRAM.pt.X = (USHORT)xTemp;
SrcToScratch.OP1_opRDRAM.pt.X = (USHORT)srcx;
SrcToScratch.BLTEXT.pt.X = (USHORT)cxTemp;
// blt final stripe
CALL_DRV_STR_BLTX(&SrcToScratch);
}
// reset ACCUM_X for beginning of next scanline
SrcToScratch.ACCUM_X = accx;
// walk Y DDA for src to scratch buffer blt
SrcToScratch.ACCUM_Y += SrcToScratch.MIN_Y;
SrcToScratch.OP1_opRDRAM.pt.Y += SrcToScratch.SHRINKINC.pt.Y;
if (0 > (short)SrcToScratch.ACCUM_Y)
{
SrcToScratch.ACCUM_Y += SrcToScratch.MAJ_Y;
SrcToScratch.OP1_opRDRAM.pt.Y++;
}
// blt from scratch buffer to dst
// 1:1 in X, 1:1 in Y, uses colorkey
CALL_DRV_SRC_BLT(MAKELONG((DD_TRANS | ROP_OP1_copy),
((BD_RES+BD_OP1+BD_OP2)*IS_VRAM)),
MAKELONG(xDst,yDst),
MAKELONG(xScratch,yScratch),
MAKELONG(xScratch,yScratch),
ColorKey,
MAKELONG(cxDst,1));
yDst++;
cyDst--;
}
}
/****************************************************************************
* FUNCTION NAME: DdBlt (NT) or Blt32 (Win95)
*
* DESCRIPTION:
****************************************************************************/
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#ifdef WINNT_VER40 // WINNT_VER40
DWORD DdBlt(PDD_BLTDATA pbd)
{
DRIVERDATA* lpDDHALData;
PDEV* ppdev;
PVGAR pREG;
#else // ----- #elseif WINNT_VER40 -----
DWORD __stdcall Blt32(LPDDHAL_BLTDATA pbd)
{
LPGLOBALDATA lpDDHALData = GetDDHALContext( pbd->lpDD);
#endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
HRESULT ddrval;
DWORD dwFlags;
DWORD dwDstCoord;
DWORD dwDstWidth;
DWORD dwDstHeight;
DWORD dwSrcCoord;
DWORD dwSrcWidth;
DWORD dwSrcHeight;
int BaseOffset;
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#ifdef WINNT_VER40 // WINNT_VER40
PDD_SURFACE_LOCAL dstx;
PDD_SURFACE_LOCAL srcx;
PDD_SURFACE_GLOBAL dst;
PDD_SURFACE_GLOBAL src;
DISPDBG((DBGLVL, "DDraw - DdBlt\n"));
ppdev = (PDEV*) pbd->lpDD->dhpdev;
lpDDHALData = (DRIVERDATA*) &ppdev->DriverData;
pREG = (PVGAR) lpDDHALData->RegsAddress;
#else // ----- #elseif WINNT_VER40 -----
LPDDRAWI_DDRAWSURFACE_LCL dstx;
LPDDRAWI_DDRAWSURFACE_LCL srcx;
LPDDRAWI_DDRAWSURFACE_GBL dst;
LPDDRAWI_DDRAWSURFACE_GBL src;
#endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
DD_LOG(("Blt32 Entry\r\n"));
#ifdef WINNT_VER40
SYNC_W_3D(ppdev); // if 3D context(s) active, make sure 3D engine idle before continuing...
#endif
// NOTES:
// Everything you need is in lpBlt->bltFX .
// Look at lpBlt->dwFlags to determine what kind of blt you are doing,
// DDBLT_xxxx are the flags.
//
// COLORKEY NOTES:
// ColorKey ALWAYS comes in BLTFX. You don't have to look it up in
// the surface.
#ifdef WINNT_VER40 // WINNT_VER40
#else // ----- #elseif WINNT_VER40 -----
// if direct draw is NOT using display list, it must sync here
// updateFlipStatus may access the hardware!
if (!lpDDHALData->DisplayListDDraw && ((lpDDHALData->DrvSemaphore & DRVSEM_3D_BUSY) || (lpDDHALData->DrvSemaphore & DRVSEM_DISPLAY_LIST)))
{
qmRequestDirectAccess();
}
#endif // WINNT_VER40
// is a flip in progress?
#ifdef WINNT_VER40
ddrval = vUpdateFlipStatus(
&ppdev->flipRecord,
pbd->lpDDDestSurface->lpGbl->fpVidMem);
#else
#if defined(DDRAW_COMPAT_10)
ddrval = pfnUpdateFlipStatus(
pbd->lpDDDestSurface->lpData->fpVidMem
lpDDHALData);
#else
ddrval = pfnUpdateFlipStatus(
pbd->lpDDDestSurface->lpGbl->fpVidMem,
lpDDHALData);
#endif
#endif
if (ddrval != DD_OK)
{
pbd->ddRVal = ddrval;
DD_LOG(("Blt32 Exit - flip in progress, returning %08lX\r\n", ddrval));
return (DDHAL_DRIVER_HANDLED);
}
#ifndef WINNT_VER40
// if the destination surface of this blt is a texture
if (DDSCAPS_TEXTURE & pbd->lpDDDestSurface->ddsCaps.dwCaps)
{
LP_SURFACE_DATA lpSurfaceData;
lpSurfaceData = (LP_SURFACE_DATA)(pbd->lpDDDestSurface->dwReserved1);
// if the texture is a non-agp host texture (i.e. pci memory)
if (lpSurfaceData->dwFlags & SURF_HOST_BASED_TEXTURE)
{
// punt the blt to direct draw hel
pbd->ddRVal = DDERR_UNSUPPORTED;
return DDHAL_DRIVER_NOTHANDLED;
}
}
// if the source surface of this blt is non-null and is a texture
if ((NULL != pbd->lpDDSrcSurface) &&
(DDSCAPS_TEXTURE & pbd->lpDDSrcSurface->ddsCaps.dwCaps))
{
LP_SURFACE_DATA lpSurfaceData;
lpSurfaceData = (LP_SURFACE_DATA)(pbd->lpDDSrcSurface->dwReserved1);
// if the texture is a non-agp host texture (i.e. pci memory)
if (lpSurfaceData->dwFlags & SURF_HOST_BASED_TEXTURE)
{
// punt the blt to direct draw hel
pbd->ddRVal = DDERR_UNSUPPORTED;
return DDHAL_DRIVER_NOTHANDLED;
}
}
#endif
// If async, then only work if blter isn't busy.
// This should probably be a little more specific to each call !!!
dwFlags = pbd->dwFlags;
//#if 0
// if( dwFlags & DDBLT_ASYNC )
// {
// if( !ENOUGH_FIFO_FOR_BLT )
// {
//#if 0 // diagnostics for ASYNC BLT lockup
// DWORD dwROP = pbd->bltFX.dwROP;
// WORD rop = (WORD) LOBYTE( HIWORD( dwROP ) );
// PVGAR pREG = (PVGAR) lpDDHALData->RegsAddress;
// DBG_MESSAGE(("Status = %02x QFREE = %2d", pREG->grSTATUS, pREG->grQFREE));
// dstx = pbd->lpDDDestSurface;
// dst = dstx->lpData;
// dwDstCoord = cvlxy( dst->fpVidMem - lpDDHALData->ScreenAddress, BYTESPERPIXEL );
// dwDstCoord += MAKELONG( pbd->rDest.left, pbd->rDest.top );
// dwDstWidth = pbd->rDest.right - pbd->rDest.left;
// dwDstHeight = pbd->rDest.bottom - pbd->rDest.top;
// srcx = pbd->lpDDSrcSurface;
// src = srcx->lpData;
// dwSrcCoord = cvlxy( src->fpVidMem - lpDDHALData->ScreenAddress, BYTESPERPIXEL );
// dwSrcCoord += MAKELONG( pbd->rSrc.left, pbd->rSrc.top );
// dwSrcWidth = pbd->rSrc.right - pbd->rSrc.left;
// dwSrcHeight = pbd->rSrc.bottom - pbd->rSrc.top;
//
// DBG_MESSAGE(("Failed Blt32: Blt from %08X %dx%d -> %08X %dx%d rop %X",
// dwSrcCoord, dwSrcWidth, dwSrcHeight,
// dwDstCoord, dwDstWidth, dwDstHeight,
// rop));
//#endif
// DBG_MESSAGE(("ASYNC FAILED"));
// pbd->ddRVal = DDERR_WASSTILLDRAWING;
// return DDHAL_DRIVER_HANDLED;
// }
// }
//#endif
// get offset, width, and height for destination
dstx = pbd->lpDDDestSurface;
#if DDRAW_COMPAT == 10
dst = dstx->lpData;
#else
dst = dstx->lpGbl;
#endif
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#ifdef WINNT_VER40 // WINNT_VER40
dwDstCoord = cvlxy(ppdev->lDeltaScreen,
dst->fpVidMem,
BYTESPERPIXEL);
#else // ----- #elseif WINNT_VER40 -----
dwDstCoord = cvlxy( lpDDHALData,dst->fpVidMem - lpDDHALData->ScreenAddress, BYTESPERPIXEL );
#endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
dwDstCoord += MAKELONG(pbd->rDest.left, pbd->rDest.top);
dwDstWidth = pbd->rDest.right - pbd->rDest.left;
dwDstHeight = pbd->rDest.bottom - pbd->rDest.top;
/* Check for a zero extent stretchblt */
if ((dwDstWidth == 0) || (dwDstHeight == 0))
{
pbd->ddRVal = DD_OK;
return (DDHAL_DRIVER_HANDLED);
}
// If someone is running a full-screen exclusive app it is the
// responsibility of the app to take care of the cursor. We don't
// call BeginAccess or EndAccess for them.
//
// However, if someone is running a windowed app and they have
// attached a clipper object to the destination surface then they
// are more like a normal windows app and we call BeginAccess and
// EndAccess for them around a blt. That is the only circumstance
// where we currently do cursor exclusion.
//
// We do intend to add calls to BeginAccess and EndAccess around
// a rectangle lock of the primary surface. In this case, we
// would only do cursor exclusion if a lock rect is specified.
// This will be implemented with DirectDraw 2.0.
//
// I believe that you should not do automatic cursor exclusion in
// the driver because you will penalize all blts and locks.
// Grab the hardware - disable HW cursor updates.
LOCK_HW_SEMAPHORE();
// Decipher the flags.
if (dwFlags & DDBLT_ROP)
{
static const WORD mix2blt[] =
{ // all ops color vram
BD_RES ,
BD_RES | BD_OP0 | BD_OP1,
BD_RES | BD_OP0 | BD_OP1,
BD_RES | BD_OP1,
BD_RES | BD_OP0 | BD_OP1,
BD_RES | BD_OP0 ,
BD_RES | BD_OP0 | BD_OP1,
BD_RES | BD_OP0 | BD_OP1,
BD_RES | BD_OP0 | BD_OP1,
BD_RES | BD_OP0 | BD_OP1,
BD_RES | BD_OP0 ,
BD_RES | BD_OP0 | BD_OP1,
BD_RES | BD_OP1,
BD_RES | BD_OP0 | BD_OP1,
BD_RES | BD_OP0 | BD_OP1,
BD_RES
}; // all ops color vram
DWORD dwROP = pbd->bltFX.dwROP;
WORD rop = (WORD) LOBYTE( HIWORD( dwROP ) );
WORD mix = rop & 0x0f;
WORD bdf = mix2blt[mix];
if (bdf & BD_OP1) // SRC rops
{
srcx = pbd->lpDDSrcSurface;
#if DDRAW_COMPAT == 10
src = srcx->lpData;
#else
src = srcx->lpGbl;
#endif
#ifdef WINNT_VER40 // YUV movement code
#else
if ((srcx->dwFlags & DDRAWISURF_HASPIXELFORMAT) &&
(src->ddpfSurface.dwFlags & DDPF_FOURCC) &&
(lpDDHALData->DrvSemaphore & DRVSEM_YUV_MOVED) )
{
BOOL fMoved = FALSE;
RECT rYUV;
LONG lDeltaX, lDeltaY, Scale;
LONG SrcWidth, SrcHeight, DstWidth, DstHeight;
SrcWidth = src->wWidth;
SrcHeight = src->wHeight;
if (lpDDHALData->DrvSemaphore & DRVSEM_YUV_RECT_VALID)
{
rYUV.left = min(lpDDHALData->YUVLeft,
pbd->rDest.left);
rYUV.top = min(lpDDHALData->YUVTop,
pbd->rDest.top);
rYUV.right = max(lpDDHALData->YUVLeft + lpDDHALData->YUVXExt,
pbd->rDest.right);
rYUV.bottom = max(lpDDHALData->YUVTop + lpDDHALData->YUVYExt,
pbd->rDest.bottom);
DstWidth = rYUV.right - rYUV.left;
DstHeight = rYUV.bottom - rYUV.top;
if (pbd->rDest.left > rYUV.left)
{
// YUV has moved to left.
lDeltaX = pbd->rDest.left - rYUV.left;
Scale = (SrcWidth - pbd->rSrc.right) * DstWidth / SrcWidth;
lDeltaX = min(lDeltaX, Scale);
pbd->rSrc.right += lDeltaX * SrcWidth / DstWidth;
pbd->rDest.left -= lDeltaX;
fMoved = TRUE;
}
if (pbd->rSrc.left > 0)
{
// YUV has moved to right.
lDeltaX = rYUV.right - pbd->rDest.right;
Scale = pbd->rSrc.left * DstWidth / SrcWidth;
lDeltaX = min(lDeltaX, Scale);
pbd->rSrc.left -= lDeltaX * SrcWidth / DstWidth;
pbd->rDest.right += lDeltaX;
fMoved = TRUE;
}
if (pbd->rDest.top > rYUV.top)
{
// YUV has moved up.
lDeltaY = pbd->rDest.top - rYUV.top;
Scale = (SrcHeight - pbd->rSrc.bottom) * DstHeight / SrcHeight;
lDeltaY = min(lDeltaY, Scale);
pbd->rSrc.bottom += lDeltaY * SrcHeight / DstHeight;
pbd->rDest.top -= lDeltaY;
fMoved = TRUE;
}
if (pbd->rSrc.top > 0)
{
// YUV has moved down.
lDeltaY = rYUV.bottom - pbd->rDest.bottom;
Scale = pbd->rSrc.top * DstHeight / SrcHeight;
lDeltaY = min(lDeltaY, Scale);
pbd->rSrc.top -= lDeltaY * SrcHeight / DstHeight;
pbd->rDest.bottom += lDeltaY;
fMoved = TRUE;
}
}
if (fMoved)
{
// Recalculate the destination parameters since they might have
// changed.
dwDstCoord = cvlxy(lpDDHALData,dst->fpVidMem - lpDDHALData->ScreenAddress,
BYTESPERPIXEL);
dwDstCoord += MAKELONG(pbd->rDest.left, pbd->rDest.top);
dwDstWidth = pbd->rDest.right - pbd->rDest.left;
dwDstHeight = pbd->rDest.bottom - pbd->rDest.top;
}
else
{
// Clear the YUV movement flag.
lpDDHALData->DrvSemaphore &= ~DRVSEM_YUV_MOVED;
}
}
#endif // YUV movement code
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#ifdef WINNT_VER40 // WINNT_VER40
dwSrcCoord = cvlxy(ppdev->lDeltaScreen,
src->fpVidMem,
BYTESPERPIXEL);
#else // ----- #elseif WINNT_VER40 -----
dwSrcCoord = cvlxy( lpDDHALData,src->fpVidMem - lpDDHALData->ScreenAddress, BYTESPERPIXEL );
#endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
dwSrcCoord += MAKELONG( pbd->rSrc.left, pbd->rSrc.top );
dwSrcWidth = pbd->rSrc.right - pbd->rSrc.left;
dwSrcHeight = pbd->rSrc.bottom - pbd->rSrc.top;
if (dwFlags & DDBLT_KEYSRCOVERRIDE) // Source Color Key
{
DWORD dwColor = CALL_DUP_COLOR(pbd->bltFX.ddckSrcColorkey.dwColorSpaceLowValue);
DD_LOG(("Src Color Key Blt\r\n"));
if ( (dwSrcWidth != dwDstWidth) || (dwSrcHeight != dwDstHeight) )
{
if ( !(srcx->dwFlags & DDRAWISURF_HASPIXELFORMAT) &&
(rop == 0x00CC) )
{
if (dwSrcWidth < dwDstWidth)
{
CALL_TRANSPARENTSTRETCH(LOWORD(dwDstCoord), HIWORD(dwDstCoord),
dwDstWidth, dwDstHeight,
LOWORD(dwSrcCoord), HIWORD(dwSrcCoord),
dwSrcWidth, dwSrcHeight,
dwColor);
goto blt_exit;
}
else
{
CALL_STRETCHCOLOR(LOWORD(dwDstCoord), HIWORD(dwDstCoord),
dwDstWidth, dwDstHeight,
LOWORD(dwSrcCoord), HIWORD(dwSrcCoord),
dwSrcWidth, dwSrcHeight,
dwColor);
goto blt_exit;
}
}
else
{
DD_LOG(("Unsupported SrcColorKey Blt -> punt\r\n"));
ddrval = DDERR_UNSUPPORTED;
goto blt_exit;
}
}
// // PATCOPY is faster if that's all we're doing.
// if (rop == 0xCC)
// {
// rop = 0xF0;
// bdf = BD_RES | BD_OP2;
// }
CALL_DRV_SRC_BLT(MAKELONG(rop|DD_TRANS, bdf | BD_OP2),
dwDstCoord,
dwSrcCoord,
dwSrcCoord, // Src transparency
dwColor, //
MAKELONG(dwDstWidth, dwDstHeight) );
} // (dwFlags & DDBLT_KEYSRCOVERRIDE) // Source Color Key
else if (dwFlags & DDBLT_KEYDESTOVERRIDE) // Destination Color Key
{
#if _WIN32_WINNT >= 0x500
// For some reason on NT 5.0 ddckDestColorkey does not work,
// but ddckSrcColorkey does...
DWORD dwColor = CALL_DUP_COLOR(pbd->bltFX.ddckSrcColorkey.dwColorSpaceLowValue);
#else
DWORD dwColor = CALL_DUP_COLOR(pbd->bltFX.ddckDestColorkey.dwColorSpaceLowValue);
#endif
DD_LOG(("Dst Color Key Blt\r\n"));
// Punt if stretch or shrink requested.
if ((dwSrcWidth != dwDstWidth) || (dwSrcHeight != dwDstHeight))
{
DD_LOG(("Unsupported DstColorKey Blt -> punt\r\n"));
ddrval = DDERR_UNSUPPORTED;
goto blt_exit;
}
CALL_DRV_SRC_BLT(MAKELONG(rop|DD_TRANS|DD_TRANSOP, bdf | BD_OP2),
dwDstCoord,
dwSrcCoord,
dwDstCoord, // Dst transparency
dwColor, //
MAKELONG(dwDstWidth, dwDstHeight) );
} // (dwFlags & DDBLT_KEYDESTOVERRIDE) // Destination Color Key
else
{
#ifdef TRACE_STRETCH
DBG_MESSAGE(("Blt32: Blt from %08X %dx%d -> %08X %dx%d rop %X",
dwSrcCoord, dwSrcWidth, dwSrcHeight,
dwDstCoord, dwDstWidth, dwDstHeight,
rop));
#endif
#ifdef TRACE_STRETCH
DBG_MESSAGE(("Blt32: BaseOffset %08X %08X",
src->fpVidMem - lpDDHALData->ScreenAddress, PITCH));
DBG_MESSAGE(("Blt32: src->w %04d %04d (%04x)",
src->wWidth, src->wHeight,
(src->fpVidMem - lpDDHALData->ScreenAddress) / PITCH ));
#endif
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#ifdef WINNT_VER40 // WINNT_VER40
BaseOffset = src->fpVidMem % ppdev->lDeltaScreen;
#else // ----- #elseif WINNT_VER40 -----
BaseOffset = (src->fpVidMem - lpDDHALData->ScreenAddress) % PITCH;
#endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
if ((dwSrcWidth != dwDstWidth) || (dwSrcHeight != dwDstHeight) ||
(srcx->dwFlags & DDRAWISURF_HASPIXELFORMAT))
{
int nBytesPixel = BYTESPERPIXEL;
int SrcType = lncntl[nBytesPixel - 1];
int SrcSize = nBytesPixel;
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#ifdef WINNT_VER40 // WINNT_VER40
int ySrcAddr = src->fpVidMem / ppdev->lDeltaScreen;
#else // ----- #elseif WINNT_VER40 -----
int ySrcAddr = (src->fpVidMem - lpDDHALData->ScreenAddress) / PITCH;
#endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
// Punt if 32bpp. The '62 and '64 don't do 32bpp stretches at all...
// KENTL - 10/4/96
if (nBytesPixel == 4)
{
DD_LOG(("Unsupported 32bpp resize blt -> punt\r\n"));
ddrval = DDERR_UNSUPPORTED;
goto blt_exit;
}
// Punt if not SRCCPY.
if (rop != 0x00CC)
{
DD_LOG(("Unsupport rop in resize blt -> punt\r\n"));
ddrval = DDERR_UNSUPPORTED;
goto blt_exit;
}
// This should only be RGB565 in 8Bit FB or YUV422 in 8 or 16.
if ( srcx->dwFlags & DDRAWISURF_HASPIXELFORMAT )
{
if ( src->ddpfSurface.dwFlags & DDPF_FOURCC )
SrcType = LN_YUV422;
else
SrcType = LN_RGB565;
SrcSize = 2;
}
if (LGDEVID == CL_GD5464)
{
if ( ! lpDDHALData->EdgeTrim )
lpDDHALData->EdgeTrim = 15; // Assign minimum trim percentage
if ((SrcType == LN_YUV422))
{
// Check for 5464 shrink workaround
if ((dwDstWidth * nBytesPixel) <=
((dwSrcWidth * SrcSize) * (100 - lpDDHALData->EdgeTrim)/100))
{
DWORD dwTDst_X;
int iratio;
int ratio_1, ratio_2;
unsigned int excess;
if ( nBytesPixel == 1 )
dwSrcWidth *= SrcSize;
iratio = dwSrcWidth / dwDstWidth;
excess = dwSrcWidth % dwDstWidth;
ratio_1 = iratio;
// get power of 2 greater than current number
ratio_2 = 1;
do
{
ratio_2 <<= 1;
} while ( ratio_1 >>= 1 );
// Check for special cases of ratio already a perfect
// power of 2 or could be trimmed to a power of two.
if ((!excess || ((100 * excess) <= (dwSrcWidth * (100 - lpDDHALData->EdgeTrim)/100)))
&& ( (ratio_2 / iratio) == 2 ) )
ratio_2 >>= 1;
if ( nBytesPixel == 1 )
{ // Mixed mode frame buffer so adjust coords / sizes
// to match
//#if 0
// if ( !( OFFSCR_YUV_VAR.ratio == ratio_2 ) )
// {
// OFFSCR_YUV_VAR.ratio = ratio_2;
//
// ratio_2 /= 2;
//
// // Perform offscreen shrink to adjacent src buffer
// CALL_DRVSTRETCH64(
// OFFSCR_YUV_VAR.SrcRect.right * SrcSize,
// OFFSCR_YUV_VAR.SrcRect.top,
// (OFFSCR_YUV_VAR.SrcRect.right - OFFSCR_YUV_VAR.SrcRect.left)/ratio_2,
// OFFSCR_YUV_VAR.SrcRect.bottom - OFFSCR_YUV_VAR.SrcRect.top,
// OFFSCR_YUV_VAR.SrcRect.left,
// OFFSCR_YUV_VAR.SrcRect.top,
// OFFSCR_YUV_VAR.SrcRect.right - OFFSCR_YUV_VAR.SrcRect.left,
// OFFSCR_YUV_VAR.SrcRect.bottom - OFFSCR_YUV_VAR.SrcRect.top,
// nBytesPixel,
// SrcType,
// BaseOffset,
// FALSE);
//
// ratio_2 *= 2;
// } // endif ( !( offscr_YUV.ratio == ratio_2 ) )
//
// // Perform stretch from adjacent src buffer to
// // onscreen dst
// dwTDst_X = LOWORD(dwSrcCoord) +
// (OFFSCR_YUV_VAR.SrcRect.right - OFFSCR_YUV_VAR.SrcRect.left) *
// SrcSize;
//#else
if (!( src->dwReserved1 == (DWORD)ratio_2))
{
src->dwReserved1 = ratio_2;
ratio_2 /= 2;
DD_LOG(("YUV shrink to extra buffer (8bpp)\r\n"));
// Perform offscreen shrink to adjacent src buffer
CALL_DRVSTRETCH64(
BaseOffset+(src->wWidth * SrcSize), // X Address of DST buffer
ySrcAddr, // Y Address of DST buffer
src->wWidth / ratio_2, // Width in PIXELS of DST
src->wHeight, // Height
BaseOffset, // X Address of SRC buffer
ySrcAddr, // Y Address of SRC buffer
src->wWidth, // Width in PIXELS of SRC
src->wHeight, // Height
nBytesPixel,
SrcType,
BaseOffset,
FALSE);
ratio_2 *= 2;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#ifdef WINNT_VER40 // WINNT_VER40
// Perform stretch from adjacent src buffer to onscreen dst
dwTDst_X = LOWORD(dwSrcCoord) / ratio_2 + (src->wWidth * SrcSize);
#else // ----- #elseif WINNT_VER40 -----
// Perform stretch from adjacent src buffer to onscreen dst
// Russ/Kent 10/4/96 - This fails for unknown reasons as code. The alternate coding
// seems to work better. Fixes PDR#6799
// dwTDst_X = LOWORD(dwSrcCoord) / ratio_2 + (src->wWidth * SrcSize);
dwTDst_X = BaseOffset + (LOWORD(dwSrcCoord) - BaseOffset)/ratio_2 + (src->wWidth*SrcSize);
#endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
//#endif
// dwTDst_X /= SrcSize; // Modify src X address
dwSrcWidth /= SrcSize;
DD_LOG(("YUV stretch from extra buffer (8bpp)\r\n"));
CALL_DRVSTRETCH64(
LOWORD(dwDstCoord),
HIWORD(dwDstCoord),
dwDstWidth,
dwDstHeight,
dwTDst_X,
HIWORD(dwSrcCoord),
dwSrcWidth / ratio_2,
dwSrcHeight,
nBytesPixel,
SrcType,
BaseOffset + (src->wWidth * SrcSize),
TRUE);
} // if ( nBytesPixel == 1 )
else
{
//#if 0
// if (!( OFFSCR_YUV_VAR.ratio == ratio_2))
// {
// OFFSCR_YUV_VAR.ratio = ratio_2;
//
// CALL_DRVSTRETCH64(
// lpDDHALData,
// OFFSCR_YUV_VAR.SrcRect.right,
// OFFSCR_YUV_VAR.SrcRect.top,
// (OFFSCR_YUV_VAR.SrcRect.right - OFFSCR_YUV_VAR.SrcRect.left)/ratio_2,
// OFFSCR_YUV_VAR.SrcRect.bottom - OFFSCR_YUV_VAR.SrcRect.top,
// OFFSCR_YUV_VAR.SrcRect.left,
// OFFSCR_YUV_VAR.SrcRect.top,
// OFFSCR_YUV_VAR.SrcRect.right - OFFSCR_YUV_VAR.SrcRect.left,
// OFFSCR_YUV_VAR.SrcRect.bottom - OFFSCR_YUV_VAR.SrcRect.top,
// nBytesPixel, SrcType, BaseOffset,
// FALSE);
//
// }; // endif (!(offscr_YUV.ratio == ratio_2))
//
// // Perform stretch from adjacent src buffer to onscreen dst
// dwTDst_X = (LOWORD(dwSrcCoord) / ratio_2) +
// (OFFSCR_YUV_VAR.SrcRect.right - OFFSCR_YUV_VAR.SrcRect.left);
//
//#else
if ( !( src->dwReserved1 == (DWORD)ratio_2 ) )
{
src->dwReserved1 = ratio_2;
DD_LOG(("YUV shrink to extra buffer (16bpp)\r\n"));
// Perform offscreen shrink to adjacent src buffer
CALL_DRVSTRETCH64(
BaseOffset + (src->wWidth) , // X Address of DST buffer
ySrcAddr, // Y Address of DST buffer
src->wWidth / ratio_2, // Width in PIXELS of DST
src->wHeight, // Height
BaseOffset, // X Address of SRC buffer
ySrcAddr, // Y Address of SRC buffer
src->wWidth, // Width in PIXELS of SRC
src->wHeight, // Height
nBytesPixel,
SrcType,
BaseOffset,
FALSE);
}
// Perform stretch from adjacent src buffer to onscreen dst
dwTDst_X = (LOWORD(dwSrcCoord) - BaseOffset) / ratio_2 + BaseOffset + (src->wWidth);
//#endif
DD_LOG(("YUV stretch from extra buffer (16bpp)\r\n"));
CALL_DRVSTRETCH64(
LOWORD(dwDstCoord),
HIWORD(dwDstCoord),
dwDstWidth,
dwDstHeight,
dwTDst_X,
HIWORD(dwSrcCoord),
dwSrcWidth / ratio_2,
dwSrcHeight,
nBytesPixel,
SrcType,
BaseOffset,
TRUE);
} // endif ( nBytesPixel == 1 )
}
else
{
DD_LOG(("YUV stretch\r\n"));
CALL_DRVSTRETCH64(
LOWORD(dwDstCoord),
HIWORD(dwDstCoord),
dwDstWidth,
dwDstHeight,
LOWORD(dwSrcCoord),
HIWORD(dwSrcCoord),
dwSrcWidth,
dwSrcHeight,
nBytesPixel,
SrcType,
BaseOffset,
TRUE);
}
} // if ((SrcType == LN_YUV422))
else
{
DD_LOG(("RGB resize blt\r\n"));
// handle shrinks & stretches
if ((2 == nBytesPixel) && (dwSrcWidth > dwDstWidth))
{
// handles 16bpp RGB shrinks
CALL_RGB_16SHRINKBOF64(LOWORD(dwDstCoord), HIWORD(dwDstCoord),
dwDstWidth, dwDstHeight,
LOWORD(dwSrcCoord), HIWORD(dwSrcCoord),
dwSrcWidth, dwSrcHeight);
}
else
{
// handles 16bpp RGB stretches, 8bpp stretches & 8bpp shrinks
CALL_RGB_RESIZEBOF64(LOWORD(dwDstCoord), HIWORD(dwDstCoord),
dwDstWidth, dwDstHeight,
LOWORD(dwSrcCoord), HIWORD(dwSrcCoord),
dwSrcWidth, dwSrcHeight);
}
} // endif ((SrcType == LN_YUV422))
} // if (LGDEVID == CL_GD5464)
else
{
DD_LOG(("calling DrvStretch62\r\n"));
CALL_DRVSTRETCH62(
LOWORD(dwDstCoord),
HIWORD(dwDstCoord),
dwDstWidth,
dwDstHeight,
LOWORD(dwSrcCoord),
HIWORD(dwSrcCoord),
dwSrcWidth,
dwSrcHeight,
nBytesPixel,
SrcType,
BaseOffset,
TRUE);
} // endif (LGDEVID == CL_GD5464)
}
else
{
DD_LOG(("1:1 two operand blt\r\n"));
CALL_DRV_SRC_BLT(MAKELONG(rop, bdf),
dwDstCoord,
dwSrcCoord,
0UL, // don't care
0UL, //
MAKELONG(dwDstWidth, dwDstHeight));
}
} // endif (dwFlags & DDBLT_KEYSRCOVERRIDE) // Source Color Key
}
else // DST ONLY rops
{
DD_LOG(("Dst Only Blt\r\n"));
CALL_DRV_DST_BLT(MAKELONG(rop, bdf),
dwDstCoord,
0UL, // don't care
MAKELONG(dwDstWidth, dwDstHeight) );
} // endif (bdf & BD_OP1) // SRC rops
} // (dwFlags & DDBLT_ROP)
else if (dwFlags & DDBLT_COLORFILL)
{
DWORD dwColor = CALL_DUP_COLOR(pbd->bltFX.dwFillColor);
DD_LOG(("Solid Color Fill\r\n"));
CALL_DRV_DST_BLT(MAKELONG(0x00CC, BD_RES | (BD_OP1 * IS_SOLID)),
dwDstCoord,
dwColor, // fill color
MAKELONG(dwDstWidth, dwDstHeight));
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#ifndef WINNT_VER40 // Not WINNT_VER40
else if (bD3DInit && dwFlags & DDBLT_DEPTHFILL)
{
//JGO changed for Laguna3D integration
DWORD dwFillDepth = CALL_DUPZFILL(pbd->bltFX.dwFillDepth,
dstx->lpGbl->ddpfSurface.dwZBufferBitDepth);
DD_LOG(("Depth Fill Blt\r\n"));
// convert to byte blt
// 16 bit zbuffer in 32 bit frame buffer trashes everything to right
// of zbuffer
// Fixes PDR #9152
((PT *)(&dwDstCoord))->X *= (WORD)(dst->ddpfSurface.dwZBufferBitDepth / 8);
dwDstWidth *= (dst->ddpfSurface.dwZBufferBitDepth / 8);
CALL_DRV_DST_MBLT(MAKELONG(0x00CC, BD_RES | (BD_OP1 * IS_SOLID)),
dwDstCoord,
dwFillDepth,
MAKELONG(dwDstWidth, dwDstHeight));
}
#endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
else
{
DD_LOG(("Unsupported blt - dwFlags = %08lX\r\n", dwFlags));
ddrval = DDERR_UNSUPPORTED;
goto blt_exit;
} // endif (dwFlags & DDBLT_ROP)
blt_exit:
// Release the hardware - enable HW cursor updates.
UNLOCK_HW_SEMAPHORE();
if (ddrval != DD_OK)
return DDHAL_DRIVER_NOTHANDLED;
pbd->ddRVal = DD_OK;
DD_LOG(("Blt32 Exit\r\n"));
return DDHAL_DRIVER_HANDLED;
} /* DdBlt */
/***************************************************************************
*
* FUNCTION: BltInit
*
* DESCRIPTION:
*
****************************************************************************/
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#ifdef WINNT_VER40 // WINNT_VER40
void BltInit (PDEV* ppdev, BOOL bEnableDisplayListBlts )
#else // ----- #elseif WINNT_VER40-----
void BltInit ( BOOL bEnableDisplayListBlts ,LPGLOBALDATA lpDDHALData)
#endif // WINNT_VER40 >>>>>>>>>>>>>>>>>>>>>>
{
if ((CL_GD5462 == LGDEVID) || (FALSE == bEnableDisplayListBlts))
{
#ifdef WINNT_VER40
ppdev->pfnDelay9BitBlt = DIR_Delay9BitBlt;
ppdev->pfnEdgeFillBlt = DIR_EdgeFillBlt;
ppdev->pfnMEdgeFillBlt = DIR_MEdgeFillBlt;
ppdev->pfnDrvDstBlt = DIR_DrvDstBlt;
ppdev->pfnDrvDstMBlt = DIR_DrvDstMBlt;
ppdev->pfnDrvSrcBlt = DIR_DrvSrcBlt;
ppdev->pfnDrvSrcMBlt = DIR_DrvSrcMBlt;
ppdev->pfnDrvStrBlt = DIR_DrvStrBlt;
ppdev->pfnDrvStrMBlt = DIR_DrvStrMBlt;
ppdev->pfnDrvStrMBltY = DIR_DrvStrMBltY;
ppdev->pfnDrvStrMBltX = DIR_DrvStrMBltX;
ppdev->pfnDrvStrBltY = DIR_DrvStrBltY;
ppdev->pfnDrvStrBltX = DIR_DrvStrBltX;
#else
pfnDelay9BitBlt = DIR_Delay9BitBlt;
pfnEdgeFillBlt = DIR_EdgeFillBlt;
pfnMEdgeFillBlt = DIR_MEdgeFillBlt;
pfnDrvDstBlt = DIR_DrvDstBlt;
pfnDrvDstMBlt = DIR_DrvDstMBlt;
pfnDrvSrcBlt = DIR_DrvSrcBlt;
pfnDrvSrcMBlt = DIR_DrvSrcMBlt;
if (REVID_PRE65 & lpDDHALData->bRevInfoBits)
pfnDrvStrBlt = DIR_DrvStrBlt;
else
pfnDrvStrBlt = DIR_DrvStrBlt65;
pfnDrvStrMBlt = DIR_DrvStrMBlt;
pfnDrvStrMBltY = DIR_DrvStrMBltY;
pfnDrvStrMBltX = DIR_DrvStrMBltX;
pfnDrvStrBltY = DIR_DrvStrBltY;
pfnDrvStrBltX = DIR_DrvStrBltX;
#if ENABLE_CLIPPEDBLTS
if (! (REVID_PRE65 & lpDDHALData->bRevInfoBits))
{
if (CL_GD5465 == LGDEVID)
{
pfnClippedDrvDstBlt = DIR_SWClippedDrvDstBlt;
pfnClippedDrvDstMBlt = DIR_SWClippedDrvDstMBlt;
pfnClippedDrvSrcBlt = DIR_SWClippedDrvSrcBlt;
}
else
{
pfnClippedDrvDstBlt = DIR_HWClippedDrvDstBlt;
pfnClippedDrvDstMBlt = DIR_HWClippedDrvDstMBlt;
pfnClippedDrvSrcBlt = DIR_HWClippedDrvSrcBlt;
}
}
#endif
#endif
}
else
{
#ifdef WINNT_VER40
ppdev->pfnDelay9BitBlt = DL_Delay9BitBlt;
ppdev->pfnEdgeFillBlt = DL_EdgeFillBlt;
ppdev->pfnMEdgeFillBlt = DL_MEdgeFillBlt;
ppdev->pfnDrvDstBlt = DL_DrvDstBlt;
ppdev->pfnDrvDstMBlt = DL_DrvDstMBlt;
ppdev->pfnDrvSrcBlt = DL_DrvSrcBlt;
ppdev->pfnDrvSrcMBlt = DL_DrvSrcMBlt;
ppdev->pfnDrvStrBlt = DL_DrvStrBlt;
ppdev->pfnDrvStrMBlt = DL_DrvStrMBlt;
ppdev->pfnDrvStrMBltY = DL_DrvStrMBltY;
ppdev->pfnDrvStrMBltX = DL_DrvStrMBltX;
ppdev->pfnDrvStrBltY = DL_DrvStrBltY;
ppdev->pfnDrvStrBltX = DL_DrvStrBltX;
#else
pfnDelay9BitBlt = DL_Delay9BitBlt;
pfnEdgeFillBlt = DL_EdgeFillBlt;
pfnMEdgeFillBlt = DL_MEdgeFillBlt;
pfnDrvDstBlt = DL_DrvDstBlt;
pfnDrvDstMBlt = DL_DrvDstMBlt;
pfnDrvSrcBlt = DL_DrvSrcBlt;
pfnDrvSrcMBlt = DL_DrvSrcMBlt;
if (REVID_PRE65 & lpDDHALData->bRevInfoBits)
pfnDrvStrBlt = DL_DrvStrBlt;
else
pfnDrvStrBlt = DL_DrvStrBlt65;
pfnDrvStrMBlt = DL_DrvStrMBlt;
pfnDrvStrMBltY = DL_DrvStrMBltY;
pfnDrvStrMBltX = DL_DrvStrMBltX;
pfnDrvStrBltY = DL_DrvStrBltY;
pfnDrvStrBltX = DL_DrvStrBltX;
#if ENABLE_CLIPPEDBLTS
if (! (REVID_PRE65 & lpDDHALData->bRevInfoBits))
{
if (CL_GD5465 == LGDEVID)
{
pfnClippedDrvDstBlt = DL_SWClippedDrvDstBlt;
pfnClippedDrvDstMBlt = DL_SWClippedDrvDstMBlt;
pfnClippedDrvSrcBlt = DL_SWClippedDrvSrcBlt;
}
else
{
pfnClippedDrvDstBlt = DL_HWClippedDrvDstBlt;
pfnClippedDrvDstMBlt = DL_HWClippedDrvDstMBlt;
pfnClippedDrvSrcBlt = DL_HWClippedDrvSrcBlt;
}
}
#endif
#endif
}
}
#endif // WINNT_VER35