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
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
|
|
|