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.
2005 lines
65 KiB
2005 lines
65 KiB
/**************************************************************************
|
|
***************************************************************************
|
|
*
|
|
* Copyright (c) 1997, Cirrus Logic, Inc.
|
|
* All Rights Reserved
|
|
*
|
|
* FILE: blt65.c
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
* REVISION HISTORY:
|
|
*
|
|
* $Log: //uinac/log/log/laguna/ddraw/src/Blt65.c $
|
|
*
|
|
* Rev 1.47 Jun 21 1998 12:16:46 clang
|
|
* Fixed PDR#11507 CK with ConCurrent RAM has the same transparent
|
|
* blt problem with AC
|
|
*
|
|
* Rev 1.46 May 01 1998 15:47:06 frido
|
|
* Fixed the checks for the programmable blitter stride.
|
|
*
|
|
* Rev 1.45 May 01 1998 13:37:06 frido
|
|
* Copied programmable blitter stride to Windows 95 code as well.
|
|
*
|
|
* Rev 1.44 May 01 1998 11:12:38 frido
|
|
* Added test for programmable blitter stride.
|
|
*
|
|
* Rev 1.43 Feb 24 1998 11:36:56 frido
|
|
* The overlay data has been changed in Windows NT 5.0.
|
|
*
|
|
* Rev 1.42 Feb 16 1998 16:23:06 frido
|
|
* Moved the PFN_UPDATEFLIPSTATUS into Windows 95 specific region.
|
|
*
|
|
* Rev 1.41 14 Jan 1998 06:14:02 eleland
|
|
*
|
|
* added support for display list flipping: calls to UpdateFlipStatus are
|
|
* thru function pointer pfnUpdateFlipStatus
|
|
*
|
|
* Rev 1.40 06 Jan 1998 15:01:58 xcong
|
|
* Pass lpDDHALData into some functions and macros for multi-monitor support.
|
|
*
|
|
* Rev 1.39 06 Jan 1998 11:52:16 xcong
|
|
* change pDriverData into local lpDDHALData for multi-monitor support.
|
|
*
|
|
* Rev 1.38 28 Oct 1997 15:33:24 RUSSL
|
|
* src colorkey blts are faster and less work for the hw if just OP2 is used
|
|
* with a rop of F0 rather than using both OP1 & OP2 with a rop of CC
|
|
* To get back the old way, set the OP2_ONLY_SRC_COLORKEY define to 0
|
|
*
|
|
* Rev 1.37 16 Oct 1997 17:01:34 RUSSL
|
|
* In Blt65, if REMOVE_GLOBAL_VARS is nonzero, get pdevice pointer from
|
|
* DDRAWI_DIRECTDRAW_GBL struct. It's a 16:16 ptr so call an asm function
|
|
* to convert it to a 32 bit linear address and then store this in
|
|
* DDRAWI_DIRECTDRAW_GBL dwReserved1 element.
|
|
*
|
|
* Rev 1.36 03 Oct 1997 15:45:12 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.35 01 Oct 1997 12:57:20 eleland
|
|
* added check in blt65() to detect blts to host texture surfaces and
|
|
* punt those blts back to the ddraw hel
|
|
*
|
|
* Rev 1.34 20 Aug 1997 15:36:30 RUSSL
|
|
* Added ColorKeyBlt24 function.
|
|
* With 256 byte fetch disabled, SrcColorKey blts seem to be working
|
|
* correctly at 24bpp and DstColorKey blts appear to be working correctly
|
|
* for the tddraw BLT, single DESTKEY, VMem to Primary case but running
|
|
* foxbear in 24bpp modes with only DDCKEYCAPS_DESTBLT set doesn't look
|
|
* correct. The best I've been able to do is run the tddraw DESTKEY case
|
|
* and force ColorKeyBlt24 to go though each path and verify that they
|
|
* each work correctly. This leads me to expect that foxbear using
|
|
* DstColorKeying wasn't debugged very thoroughly (now that's probably a big
|
|
* surprise to everyone). We need more dest color key blt tests.
|
|
* For Win95, this was basically a wasted effort since 256 byte fetch appears
|
|
* to break 24bpp colorkey blts in some other way, which would require yet
|
|
* another workaround.
|
|
*
|
|
* Rev 1.33 18 Aug 1997 15:00:42 bennyn
|
|
* For NT, if DDBLTFX dwSize not equal to sizeof(DDBLTFX), set dwColor to 0.
|
|
*
|
|
* Rev 1.32 13 Aug 1997 12:20:48 bennyn
|
|
* For NT, punt if no scratch buffer and DDBLTFX dwSize is not sizeof(DDBLTFX)
|
|
*
|
|
* Rev 1.31 29 Jul 1997 17:18:18 bennyn
|
|
* Fixed the Foxbear F8 bug
|
|
*
|
|
* Rev 1.30 29 Jul 1997 10:51:40 bennyn
|
|
* NT only, punt if it is a host to screen BLT
|
|
*
|
|
* Rev 1.29 24 Jul 1997 12:30:36 RUSSL
|
|
* Added check for NULL src surface ptr in Blt65 before nonlocal vidmem test
|
|
*
|
|
* Rev 1.28 24 Jul 1997 11:17:14 RUSSL
|
|
* cover up various wickle crimes against humanity
|
|
* which means disabling interpolated stretch blts among other things
|
|
*
|
|
* Rev 1.27 18 Jul 1997 10:21:50 RUSSL
|
|
* Added check for zero extent blts in TransparentStretch65
|
|
*
|
|
* Rev 1.26 14 Jul 1997 13:15:14 RUSSL
|
|
* Fix for PDR 9947 - include support for all surface formats for blts
|
|
* between overlay surfaces
|
|
*
|
|
* Rev 1.25 08 Jul 1997 11:50:48 RUSSL
|
|
* Rewrite of TransparentStretch65, similar to TransparentStretch in ddblt.c
|
|
* but can blt each scanline's full x extent without striping.
|
|
* Modified calls to do stretch blt with source colorkeying in Blt65.
|
|
*
|
|
* Rev 1.24 07 Jul 1997 13:43:52 dzenz
|
|
* Added check of DRVSEM_DISPLAY_LIST semaphore to ascertain if
|
|
* qmRequestDirectAccess needs to be called.
|
|
*
|
|
* Rev 1.23 20 Jun 1997 09:45:32 RUSSL
|
|
* Added FBToFBCopy to handle blts to/from a linear surface
|
|
* (currently these can be overlay or videoport surfaces only)
|
|
* Fixed one of our seemingly inevitable NT/Win95 collisions
|
|
*
|
|
* Rev 1.22 12 Jun 1997 17:30:46 bennyn
|
|
* For 24 & 32 BPP use StretchColor() instead of TransparentStretch()
|
|
*
|
|
* Rev 1.21 23 May 1997 15:41:28 noelv
|
|
* Added nt method for chip revision test.
|
|
*
|
|
* Rev 1.20 22 May 1997 16:46:38 RUSSL
|
|
* Fix for PDRs 9710 & 9706, remove xext <= 8 check on striping of src
|
|
* colorkey blts on 65AC (this is a workaround for a hw bug)
|
|
* Add check for 65AC or earlier and do striping of src colorkey blts
|
|
* on 65AD striping isn't needed so just do single blt
|
|
*
|
|
* Rev 1.19 19 May 1997 13:08:10 noelv
|
|
* Put NT4.0 wrapper around DrvSrcMBlt call.
|
|
*
|
|
* Rev 1.18 16 May 1997 15:32:02 RUSSL
|
|
* Added blt case to handle blts from a UYVY surface to another UYVY surface
|
|
* This fixes the VFW bugs, WinBench 97 video bugs and Encarta 97 video bugs
|
|
* PDRs 9557, 9604, 9692, 9268 & 9270
|
|
* Thanks to Peter Hou
|
|
*
|
|
* Rev 1.17 16 Apr 1997 18:40:48 RUSSL
|
|
* Fix for PDR #9340, for color conversion and resize blts calculate surface
|
|
* offset based on frame buffer pixel format then calculate offset into surface
|
|
* based on surface pixel format. Pass DrvStretch65 byte based coordinates
|
|
* rather than pixel based coordinates.
|
|
*
|
|
* Rev 1.16 16 Apr 1997 10:50:54 bennyn
|
|
* Eliminated the warning due to Win95 DBG_MESSAGE call.
|
|
*
|
|
* Rev 1.15 08 Apr 1997 11:50:46 einkauf
|
|
* WINNT_VER40 affected only:add SYNC_W_3D to coordinate MCD and 2D hw access
|
|
*
|
|
* Rev 1.14 03 Apr 1997 15:25:34 RUSSL
|
|
* Modified DDBLT_DEPTHFILL case in Blt65 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.13 02 Apr 1997 15:44:54 RUSSL
|
|
* Stripe src color key blts at 24bpp, fixes PDR #9113
|
|
* Added TransparentStretch65 but hw doesn't work so it's #if'd out
|
|
*
|
|
* Rev 1.12 27 Mar 1997 16:12:36 RUSSL
|
|
* Tossed the whole bloody mess in the bit bucket. Reverted to rev 1.1
|
|
* Changed name of DrvStretch to DrvStretch65
|
|
* Modified DrvStretch65 to do 65-style resize blts using stretch_cntl
|
|
* rather than lncntl
|
|
* Added use of original src & dst rectangle (if available) to compute
|
|
* error terms. Walk DDA's in DrvStretch65 for clipped rect's.
|
|
* Changed Blt65 locals dwDstCoord, dwDstWidth, dwDstHeight and dwSrcCoord,
|
|
* dwSrcWidth, dwSrcHeight to DstDDRect and SrcDDRect DDRECTL structures
|
|
* Moved sync with queue manager in front of call to updateFlipStatus since
|
|
* updateFlipStatus might access the hardware
|
|
* Added workaround for hw bug for src colorkey blts less than one qword
|
|
* wide that require fetching from two src qwords but writing to only
|
|
* one dst qword. Fixes white lines on foxbear that used to appear in
|
|
* some modes
|
|
*
|
|
* Rev 1.11 21 Mar 1997 18:08:38 RUSSL
|
|
* Fixups in StretchRect so Foxbear now runs correctly in a window at
|
|
* all 4 colordepths
|
|
*
|
|
* Rev 1.10 18 Mar 1997 07:51:44 bennyn
|
|
* Resolved NT comiling error by #ifdef queue manager sync call
|
|
*
|
|
* Rev 1.9 12 Mar 1997 14:59:50 RUSSL
|
|
* replaced a block of includes with include of precomp.h for
|
|
* precompiled headers
|
|
*
|
|
* Rev 1.8 07 Mar 1997 12:47:10 RUSSL
|
|
* Modified DDRAW_COMPAT usage
|
|
*
|
|
* Rev 1.7 03 Mar 1997 10:31:40 eleland
|
|
* inserted queue manager sync call to blt65(), removed #ifdef
|
|
* USE_QUEUE_MANAGER
|
|
*
|
|
* Rev 1.6 21 Feb 1997 15:40:38 RUSSL
|
|
* Anybody know why we were doing every 1:1 blt through the
|
|
* resize engine rather than just a normal blt ???????
|
|
*
|
|
* Rev 1.5 06 Feb 1997 13:09:36 BENNYN
|
|
* Fixed DWORD alignment for DD resizing code
|
|
*
|
|
* Rev 1.4 31 Jan 1997 13:44:06 BENNYN
|
|
* Added clipping support and no interpolation set for 24BPP & YUV src shrink
|
|
*
|
|
* Rev 1.3 27 Jan 1997 17:29:14 BENNYN
|
|
* Added Win95 support
|
|
*
|
|
* Rev 1.2 23 Jan 1997 17:10:10 bennyn
|
|
* Modified to support 5465 DD
|
|
*
|
|
* Rev 1.1 21 Jan 1997 15:09:28 RUSSL
|
|
* Added include of ddinline.h
|
|
*
|
|
* Rev 1.0 15 Jan 1997 10:35:20 RUSSL
|
|
* Initial revision.
|
|
*
|
|
***************************************************************************
|
|
***************************************************************************/
|
|
|
|
/*----------------------------- INCLUDES ----------------------------------*/
|
|
|
|
#include "precomp.h"
|
|
|
|
// If WinNT 3.5 skip all the source code
|
|
#if defined WINNT_VER35 // WINNT_VER35
|
|
#else // !WinNT 3.51
|
|
|
|
#ifdef WINNT_VER40 // WINNT_VER40
|
|
|
|
#define DBGLVL 1
|
|
|
|
#else // Win95
|
|
|
|
#include "flip.h"
|
|
#include "surface.h"
|
|
#include "blt.h"
|
|
#include "palette.h"
|
|
|
|
#include "bltP.h"
|
|
#include "ddinline.h"
|
|
#include "qmgr.h"
|
|
|
|
#include "ddshared.h"
|
|
#include "overlay.h"
|
|
|
|
#endif // WINNT_VER40
|
|
|
|
/*----------------------------- DEFINES -----------------------------------*/
|
|
|
|
#define OP2_ONLY_SRC_COLORKEY 1
|
|
|
|
#ifdef WINNT_VER40
|
|
#define UPDATE_FLIP_STATUS(arg) vUpdateFlipStatus(&ppdev->flipRecord,(arg))
|
|
#else // Win95
|
|
#define UPDATE_FLIP_STATUS(arg) updateFlipStatus((arg),lpDDHALData)
|
|
#endif // WINNT_VER40
|
|
|
|
#define LOCK_HW_SEMAPHORE() (lpDDHALData->DrvSemaphore |= DRVSEM_IN_USE)
|
|
#define UNLOCK_HW_SEMAPHORE() (lpDDHALData->DrvSemaphore &= ~ DRVSEM_IN_USE)
|
|
|
|
// defines for STRETCH_CNTL register
|
|
#define RGB_8_FMT 0
|
|
#define RGB_555_FMT 1
|
|
#define RGB_565_FMT 2
|
|
#define RGB_24_FMT 3
|
|
#define RGB_32_FMT 4
|
|
#define YUV_422_FMT 9
|
|
|
|
#define SRC_FMT_SHIFT 12
|
|
#define DST_FMT_SHIFT 8
|
|
#define SRC_FMT_MASK 0xF000
|
|
#define DST_FMT_MASK 0x0F00
|
|
|
|
#define YSHRINK_ENABLE 0x8
|
|
#define XSHRINK_ENABLE 0x4
|
|
#define YINTERP_ENABLE 0x2
|
|
#define XINTERP_ENABLE 0x1
|
|
|
|
// bltdef defines
|
|
#define BD_TYPE_RESIZE (1 << 9)
|
|
#define BD_TYPE_NORMAL 0
|
|
|
|
/*----------------------------- TYPEDEFS ----------------------------------*/
|
|
|
|
typedef short DDAX;
|
|
typedef struct tagAxis
|
|
{
|
|
DDAX accum;
|
|
DDAX maj;
|
|
DDAX min;
|
|
} AXIS;
|
|
|
|
#if !ENABLE_CLIPPEDBLTS
|
|
typedef struct _DDRECTL
|
|
{
|
|
REG32 loc;
|
|
REG32 ext;
|
|
} DDRECTL;
|
|
#endif
|
|
|
|
/*------------------------- FUNCTION PROTOTYPES ---------------------------*/
|
|
|
|
#ifdef DEBUG
|
|
extern VOID SaveSurfaceToBmp ( DDRAWI_DDRAWSURFACE_LCL *pSurface );
|
|
#endif
|
|
|
|
/*-------------------------- STATIC VARIABLES -----------------------------*/
|
|
|
|
#ifndef WINNT_VER40
|
|
|
|
ASSERTFILE("blt65.c");
|
|
extern PFN_UPDATEFLIPSTATUS pfnUpdateFlipStatus;
|
|
|
|
#endif
|
|
|
|
/*-------------------------- GLOBAL FUNCTIONS -----------------------------*/
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: DrvStretch65()
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
****************************************************************************/
|
|
|
|
void DrvStretch65
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
DRIVERDATA *lpDDHALData,
|
|
#else
|
|
LPGLOBALDATA lpDDHALData,
|
|
#endif
|
|
DDRECTL SrcDDRect,
|
|
DDRECTL DstDDRect,
|
|
DWORD Stretch_Cntl,
|
|
DDRECTL OrigSrcDDRect,
|
|
DDRECTL OrigDstDDRect
|
|
)
|
|
{
|
|
const int nBytesPixel = BYTESPERPIXEL;
|
|
|
|
autoblt_regs bltr;
|
|
AXIS axis[2];
|
|
int nDst[2];
|
|
int nSrc[2];
|
|
int i;
|
|
int ext;
|
|
|
|
|
|
#ifndef WINNT_VER40
|
|
DBG_MESSAGE(("DrvStretch65: %4d,%4d %4dx%4d -> %4d,%4d %4dx%4d",
|
|
SrcDDRect.loc.pt.X, SrcDDRect.loc.pt.Y,
|
|
SrcDDRect.ext.pt.X, SrcDDRect.ext.pt.Y,
|
|
DstDDRect.loc.pt.X, DstDDRect.loc.pt.Y,
|
|
DstDDRect.ext.pt.X, DstDDRect.ext.pt.Y));
|
|
#endif // WINNT_VER40
|
|
|
|
if ((0 == DstDDRect.ext.pt.X) || (0 == DstDDRect.ext.pt.Y) ||
|
|
(0 == SrcDDRect.ext.pt.X) || (0 == SrcDDRect.ext.pt.Y))
|
|
{
|
|
// nothing to do, so get outta here!
|
|
return;
|
|
}
|
|
|
|
#ifdef WINNT_VER40
|
|
SYNC_W_3D(ppdev);
|
|
#endif
|
|
|
|
bltr.DRAWBLTDEF.DW = MAKELONG(ROP_OP1_copy, BD_RES * IS_VRAM |
|
|
BD_OP1 * IS_VRAM |
|
|
BD_TYPE_RESIZE);
|
|
|
|
// dst coords
|
|
bltr.OP0_opMRDRAM.DW = DstDDRect.loc.DW;
|
|
|
|
// src coords
|
|
bltr.OP1_opMRDRAM.DW = SrcDDRect.loc.DW;
|
|
|
|
// blt extent
|
|
bltr.MBLTEXTR_EX.DW = DstDDRect.ext.DW;
|
|
#if 1
|
|
// tddraw agp Case 47 puts the goofy happy face with arms image in the middle
|
|
// of the screen and then expects us to stretch it over the top of itself
|
|
// if we don't handle the overlap somehow, the result is trash at the bottom
|
|
// we blt the original src to the lower right of the dest and then stretch
|
|
// that copy of the src to the dest
|
|
// hack, hack, cough, cough
|
|
bltr.BLTEXT.DW = SrcDDRect.ext.DW; // stuff this here for overlap check
|
|
#endif
|
|
|
|
bltr.STRETCH_CNTL.W = (WORD)Stretch_Cntl;
|
|
|
|
bltr.SHRINKINC.W = 0x0000;
|
|
|
|
bltr.SRCX = SrcDDRect.ext.pt.X;
|
|
|
|
// convert back to pixels for error term computations
|
|
DstDDRect.ext.pt.X /= (USHORT)nBytesPixel;
|
|
OrigDstDDRect.ext.pt.X /= (USHORT)nBytesPixel;
|
|
if ((YUV_422_FMT << SRC_FMT_SHIFT) == (SRC_FMT_MASK & Stretch_Cntl))
|
|
{
|
|
bltr.OP1_opMRDRAM.pt.X &= 0xFFFC;
|
|
SrcDDRect.ext.pt.X /= 2;
|
|
OrigSrcDDRect.ext.pt.X /= 2;
|
|
}
|
|
else
|
|
{
|
|
SrcDDRect.ext.pt.X /= (USHORT)nBytesPixel;
|
|
OrigSrcDDRect.ext.pt.X /= (USHORT)nBytesPixel;
|
|
}
|
|
if (DstDDRect.ext.pt.X < SrcDDRect.ext.pt.X)
|
|
{
|
|
bltr.STRETCH_CNTL.W |= XSHRINK_ENABLE;
|
|
bltr.STRETCH_CNTL.W &= ~XINTERP_ENABLE;
|
|
bltr.SHRINKINC.pt.X = SrcDDRect.ext.pt.X / DstDDRect.ext.pt.X;
|
|
}
|
|
if (DstDDRect.ext.pt.Y < SrcDDRect.ext.pt.Y)
|
|
{
|
|
bltr.STRETCH_CNTL.W |= YSHRINK_ENABLE;
|
|
bltr.STRETCH_CNTL.W &= ~YINTERP_ENABLE;
|
|
bltr.SHRINKINC.pt.Y = SrcDDRect.ext.pt.Y / DstDDRect.ext.pt.Y;
|
|
}
|
|
|
|
// Compute DDA terms.
|
|
nDst[0] = OrigDstDDRect.ext.pt.X;
|
|
nDst[1] = OrigDstDDRect.ext.pt.Y;
|
|
nSrc[0] = OrigSrcDDRect.ext.pt.X;
|
|
nSrc[1] = OrigSrcDDRect.ext.pt.Y;
|
|
|
|
for (i = 0; i < 2; i++)
|
|
{
|
|
int kDst = 1;
|
|
|
|
if (bltr.STRETCH_CNTL.W & ((i==0) ? XINTERP_ENABLE : YINTERP_ENABLE))
|
|
{
|
|
nDst[i] *= 4;
|
|
nSrc[i] *= 4;
|
|
nSrc[i] -= 3;
|
|
|
|
kDst = 0x8000 / nDst[i];
|
|
}
|
|
|
|
if (bltr.STRETCH_CNTL.W & ((i==0) ? XSHRINK_ENABLE : YSHRINK_ENABLE))
|
|
{ /* 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;
|
|
|
|
#define DO_SW_CLIPPING
|
|
#ifdef DO_SW_CLIPPING
|
|
// walk DDA's to get correct initial ACCUM terms
|
|
ext = DstDDRect.loc.pt.X - OrigDstDDRect.loc.pt.X;
|
|
while (0 < ext--)
|
|
{
|
|
bltr.ACCUM_X += bltr.MIN_X;
|
|
if (0 > (short)bltr.ACCUM_X)
|
|
{
|
|
bltr.ACCUM_X += bltr.MAJ_X;
|
|
}
|
|
}
|
|
ext = DstDDRect.loc.pt.Y - OrigDstDDRect.loc.pt.Y;
|
|
while (0 < ext--)
|
|
{
|
|
bltr.ACCUM_Y += bltr.MIN_Y;
|
|
if (0 > (short)bltr.ACCUM_Y)
|
|
{
|
|
bltr.ACCUM_Y += bltr.MAJ_Y;
|
|
}
|
|
}
|
|
#else
|
|
#pragma message("Add hw clipping")
|
|
#endif
|
|
|
|
#ifdef WINNT_VER40
|
|
ppdev->pfnDrvStrBlt(ppdev, lpDDHALData,
|
|
#else
|
|
pfnDrvStrBlt(
|
|
lpDDHALData,
|
|
#endif
|
|
&bltr);
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: TransparentStretch65()
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
****************************************************************************/
|
|
|
|
void TransparentStretch65
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
DRIVERDATA *lpDDHALData,
|
|
#else
|
|
LPGLOBALDATA lpDDHALData,
|
|
#endif
|
|
DDRECTL SrcDDRect,
|
|
DDRECTL DstDDRect,
|
|
DWORD Stretch_Cntl,
|
|
DWORD ColorKey
|
|
)
|
|
{
|
|
const int nBytesPixel = BYTESPERPIXEL;
|
|
|
|
autoblt_regs SrcToScratch;
|
|
|
|
AXIS axis[2];
|
|
int nDst[2];
|
|
int nSrc[2];
|
|
int i;
|
|
|
|
|
|
// currently this only supports same src & dst formats
|
|
#ifndef WINNT_VER40
|
|
ASSERT(((SRC_FMT_MASK & Stretch_Cntl) >> SRC_FMT_SHIFT) ==
|
|
((DST_FMT_MASK & Stretch_Cntl) >> DST_FMT_SHIFT));
|
|
|
|
DBG_MESSAGE(("TransparentStretch65: %4X,%4X %4Xx%4X -> %4X,%4X %4Xx%4X",
|
|
SrcDDRect.loc.pt.X, SrcDDRect.loc.pt.Y,
|
|
SrcDDRect.ext.pt.X, SrcDDRect.ext.pt.Y,
|
|
DstDDRect.loc.pt.X, DstDDRect.loc.pt.Y,
|
|
DstDDRect.ext.pt.X, DstDDRect.ext.pt.Y));
|
|
|
|
#endif
|
|
|
|
if ((0 == DstDDRect.ext.pt.X) || (0 == DstDDRect.ext.pt.Y) ||
|
|
(0 == SrcDDRect.ext.pt.X) || (0 == SrcDDRect.ext.pt.Y))
|
|
{
|
|
// nothing to do, so get outta here!
|
|
return;
|
|
}
|
|
|
|
// initialize auto blt struct for src to scratch buffer
|
|
SrcToScratch.DRAWBLTDEF.DW = MAKELONG(ROP_OP1_copy, BD_RES * IS_VRAM |
|
|
BD_OP1 * IS_VRAM |
|
|
BD_TYPE_RESIZE);
|
|
|
|
// dst coords in bytes (scratch buffer)
|
|
SrcToScratch.OP0_opMRDRAM.DW = lpDDHALData->ScratchBufferOrg;
|
|
SrcToScratch.OP0_opMRDRAM.pt.X *= (USHORT)nBytesPixel;
|
|
|
|
// src coords in bytes
|
|
SrcToScratch.OP1_opMRDRAM.DW = SrcDDRect.loc.DW;
|
|
SrcToScratch.OP1_opMRDRAM.pt.X *= (USHORT)nBytesPixel;
|
|
|
|
// blt extent in bytes (1 scanline at a time)
|
|
SrcToScratch.MBLTEXTR_EX.DW = MAKELONG(DstDDRect.ext.pt.X * nBytesPixel,1);
|
|
|
|
SrcToScratch.STRETCH_CNTL.W = (WORD)Stretch_Cntl;
|
|
|
|
SrcToScratch.SHRINKINC.W = 0x0000;
|
|
|
|
SrcToScratch.SRCX = SrcDDRect.ext.pt.X * nBytesPixel;
|
|
|
|
if (DstDDRect.ext.pt.X < SrcDDRect.ext.pt.X)
|
|
{
|
|
SrcToScratch.STRETCH_CNTL.W |= XSHRINK_ENABLE;
|
|
SrcToScratch.STRETCH_CNTL.W &= ~XINTERP_ENABLE;
|
|
SrcToScratch.SHRINKINC.pt.X = SrcDDRect.ext.pt.X / DstDDRect.ext.pt.X;
|
|
}
|
|
|
|
if (DstDDRect.ext.pt.Y < SrcDDRect.ext.pt.Y)
|
|
{
|
|
SrcToScratch.STRETCH_CNTL.W |= YSHRINK_ENABLE;
|
|
SrcToScratch.STRETCH_CNTL.W &= ~YINTERP_ENABLE;
|
|
SrcToScratch.SHRINKINC.pt.Y = SrcDDRect.ext.pt.Y / DstDDRect.ext.pt.Y;
|
|
}
|
|
|
|
// Compute DDA terms
|
|
|
|
nDst[0] = DstDDRect.ext.pt.X;
|
|
nDst[1] = DstDDRect.ext.pt.Y;
|
|
nSrc[0] = SrcDDRect.ext.pt.X;
|
|
nSrc[1] = SrcDDRect.ext.pt.Y;
|
|
|
|
for (i = 0; i < 2; i++)
|
|
{
|
|
int kDst = 1;
|
|
|
|
if (SrcToScratch.STRETCH_CNTL.W & ((i==0) ? XINTERP_ENABLE : YINTERP_ENABLE))
|
|
{
|
|
nDst[i] *= 4;
|
|
nSrc[i] *= 4;
|
|
nSrc[i] -= 3;
|
|
|
|
kDst = 0x8000 / nDst[i];
|
|
}
|
|
|
|
if (SrcToScratch.STRETCH_CNTL.W & ((i==0) ? XSHRINK_ENABLE : YSHRINK_ENABLE))
|
|
{ /* 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 < DstDDRect.ext.pt.Y)
|
|
{
|
|
// blt one scanline high from src to scratch buffer
|
|
#ifdef WINNT_VER40
|
|
ppdev->pfnDrvStrBlt(ppdev, lpDDHALData,
|
|
#else
|
|
pfnDrvStrBlt(
|
|
lpDDHALData,
|
|
#endif
|
|
&SrcToScratch);
|
|
|
|
// walk Y DDA for src to scratch buffer blt
|
|
SrcToScratch.ACCUM_Y += SrcToScratch.MIN_Y;
|
|
SrcToScratch.OP1_opMRDRAM.pt.Y += SrcToScratch.SHRINKINC.pt.Y;
|
|
if (0 > (short)SrcToScratch.ACCUM_Y)
|
|
{
|
|
SrcToScratch.ACCUM_Y += SrcToScratch.MAJ_Y;
|
|
SrcToScratch.OP1_opMRDRAM.pt.Y++;
|
|
}
|
|
|
|
|
|
// blt from scratch buffer to dst
|
|
// 1:1 in X, 1:1 in Y, uses colorkey
|
|
#ifdef WINNT_VER40
|
|
ppdev->pfnDrvSrcBlt(ppdev, lpDDHALData,
|
|
#else
|
|
pfnDrvSrcBlt(
|
|
lpDDHALData,
|
|
#endif
|
|
#if OP2_ONLY_SRC_COLORKEY
|
|
MAKELONG((DD_TRANS | ROP_OP2_copy),
|
|
((BD_RES+BD_OP2)*IS_VRAM)),
|
|
#else
|
|
MAKELONG((DD_TRANS | ROP_OP1_copy),
|
|
((BD_RES+BD_OP1+BD_OP2)*IS_VRAM)),
|
|
#endif
|
|
DstDDRect.loc.DW,
|
|
lpDDHALData->ScratchBufferOrg,
|
|
lpDDHALData->ScratchBufferOrg,
|
|
ColorKey,
|
|
MAKELONG(DstDDRect.ext.pt.X,1));
|
|
DstDDRect.loc.pt.Y++;
|
|
DstDDRect.ext.pt.Y--;
|
|
}
|
|
}
|
|
|
|
#ifndef WINNT_VER40
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: FBToFBCopy()
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
****************************************************************************/
|
|
|
|
VOID
|
|
FBToFBCopy ( BYTE *dst, LONG dstPitch, BYTE *src, LONG srcPitch, REG32 ext, LONG bpp )
|
|
{
|
|
int yext = ext.pt.Y;
|
|
int xext = ext.pt.X * bpp;
|
|
|
|
while (0 < yext--)
|
|
{
|
|
memcpy(dst,src,xext);
|
|
dst += dstPitch;
|
|
src += srcPitch;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: ColorKeyBlt24()
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
****************************************************************************/
|
|
|
|
#define MIN_WIDTH 21 // empirically determined that most widths less than this don't work
|
|
#define STRIPE_WIDTH 40 // max is 128 / 3 = 42 pixels, but use 40 to account for phase
|
|
|
|
STATIC VOID ColorKeyBlt24
|
|
(
|
|
#ifdef WINNT_VER40
|
|
PDEV *ppdev,
|
|
DRIVERDATA *lpDDHALData,
|
|
#else
|
|
LPGLOBALDATA lpDDHALData,
|
|
#endif
|
|
DWORD drawbltdef,
|
|
DDRECTL DstDDRect,
|
|
DDRECTL SrcDDRect,
|
|
DDRECTL KeyDDRect,
|
|
DWORD dwColorKey
|
|
)
|
|
{
|
|
short xStep = 1;
|
|
short yStep = 1;
|
|
WORD xExt;
|
|
|
|
|
|
// check for overlap
|
|
if ((abs(DstDDRect.loc.pt.X - SrcDDRect.loc.pt.X) < DstDDRect.ext.pt.X) &&
|
|
(abs(DstDDRect.loc.pt.Y - SrcDDRect.loc.pt.Y) < DstDDRect.ext.pt.Y))
|
|
{
|
|
// see if we need to blt from bottom to top
|
|
if (DstDDRect.loc.pt.Y > SrcDDRect.loc.pt.Y)
|
|
{
|
|
// point to bottom scanline and update bltdef
|
|
drawbltdef |= MAKELONG(0, BD_YDIR);
|
|
DstDDRect.loc.pt.Y += (DstDDRect.ext.pt.Y - 1);
|
|
SrcDDRect.loc.pt.Y += (DstDDRect.ext.pt.Y - 1);
|
|
KeyDDRect.loc.pt.Y += (DstDDRect.ext.pt.Y - 1);
|
|
yStep = -1;
|
|
}
|
|
// see if we need to blt from right to left
|
|
if (DstDDRect.loc.pt.X > SrcDDRect.loc.pt.X)
|
|
{
|
|
// point to right edge pixel
|
|
DstDDRect.loc.pt.X += (DstDDRect.ext.pt.X - 1);
|
|
SrcDDRect.loc.pt.X += (DstDDRect.ext.pt.X - 1);
|
|
KeyDDRect.loc.pt.X += (DstDDRect.ext.pt.X - 1);
|
|
xStep = -1;
|
|
}
|
|
}
|
|
|
|
// if width is too narrow, do blt a pixel at a time
|
|
// Also blt a pixel at a time for certain overlapping src/dst combinations
|
|
// that won't work correctly otherwise. While setting BD_YDIR to blt from
|
|
// bottom to top and also bltting in SRAM width stripes from right to left
|
|
// do work at 24bpp, they unfortunately don't work for certain overlap cases.
|
|
// In particular BD_YDIR doesn't work when you need it (period!) and bltting
|
|
// in SRAM width stripes from right to left doesn't work if the src and dst
|
|
// have the same y. Take out the two || cases and try the tddraw
|
|
// BLT_BltFast, SRCKEY, From/To same surface test and see for yourself.
|
|
if ( (MIN_WIDTH >= DstDDRect.ext.pt.X)
|
|
|| (0 > yStep)
|
|
|| ((0 > xStep) && (DstDDRect.loc.pt.Y == SrcDDRect.loc.pt.Y))
|
|
)
|
|
{
|
|
BltOnePixelAtATime:
|
|
// loop over scanlines
|
|
while (0 < DstDDRect.ext.pt.Y)
|
|
{
|
|
DWORD dst = DstDDRect.loc.DW;
|
|
DWORD src = SrcDDRect.loc.DW;
|
|
DWORD key = KeyDDRect.loc.DW;
|
|
|
|
xExt = DstDDRect.ext.pt.X;
|
|
|
|
// loop over pixels in scanline
|
|
while (0 < xExt)
|
|
{
|
|
#ifdef WINNT_VER40
|
|
ppdev->pfnDrvSrcBlt(ppdev, lpDDHALData,
|
|
#else
|
|
pfnDrvSrcBlt(
|
|
lpDDHALData,
|
|
#endif
|
|
drawbltdef, dst, src, key, dwColorKey, MAKELONG(1,1));
|
|
// adjust extent and ptrs (x is in low word)
|
|
xExt--;
|
|
dst += xStep;
|
|
src += xStep;
|
|
key += xStep;
|
|
}
|
|
// adjust extent and ptrs (y is in high word)
|
|
DstDDRect.ext.pt.Y--;
|
|
SrcDDRect.loc.pt.Y += yStep;
|
|
DstDDRect.loc.pt.Y += yStep;
|
|
KeyDDRect.loc.pt.Y += yStep;
|
|
}
|
|
}
|
|
// if width is less than SRAM width, just do a single blt
|
|
else if (STRIPE_WIDTH >= DstDDRect.ext.pt.X)
|
|
{
|
|
// except if there's overlap, do it the slow way
|
|
//if ((0 > xStep) || (0 > yStep))
|
|
if (0 > xStep) // check for (0 > yStep) already handled above
|
|
goto BltOnePixelAtATime;
|
|
|
|
// just blt it
|
|
#ifdef WINNT_VER40
|
|
ppdev->pfnDrvSrcBlt(ppdev, lpDDHALData,
|
|
#else
|
|
pfnDrvSrcBlt(
|
|
lpDDHALData,
|
|
#endif
|
|
drawbltdef,
|
|
DstDDRect.loc.DW,
|
|
SrcDDRect.loc.DW,
|
|
KeyDDRect.loc.DW,
|
|
dwColorKey,
|
|
DstDDRect.ext.DW);
|
|
}
|
|
// stripe the blt into SRAM width blts
|
|
else
|
|
{
|
|
xExt = STRIPE_WIDTH;
|
|
|
|
// blt from right to left
|
|
if (0 > xStep)
|
|
{
|
|
DstDDRect.loc.pt.X++;
|
|
SrcDDRect.loc.pt.X++;
|
|
KeyDDRect.loc.pt.X++;
|
|
|
|
while (1)
|
|
{
|
|
// adjust ptrs to start of stripe
|
|
DstDDRect.loc.pt.X -= xExt;
|
|
SrcDDRect.loc.pt.X -= xExt;
|
|
KeyDDRect.loc.pt.X -= xExt;
|
|
|
|
// blt the stripe
|
|
#ifdef WINNT_VER40
|
|
ppdev->pfnDrvSrcBlt(ppdev, lpDDHALData,
|
|
#else
|
|
pfnDrvSrcBlt(
|
|
lpDDHALData,
|
|
#endif
|
|
drawbltdef,
|
|
DstDDRect.loc.DW,
|
|
SrcDDRect.loc.DW,
|
|
KeyDDRect.loc.DW,
|
|
dwColorKey,
|
|
MAKELONG(xExt,DstDDRect.ext.pt.Y));
|
|
|
|
// adjust remaining extent
|
|
DstDDRect.ext.pt.X -= xExt;
|
|
// are we done?
|
|
if (0 == DstDDRect.ext.pt.X)
|
|
break;
|
|
|
|
// last stripe might not be STRIPE_WIDTH wide
|
|
if (xExt > DstDDRect.ext.pt.X)
|
|
{
|
|
xExt = DstDDRect.ext.pt.X;
|
|
|
|
// if the last stripe is too narrow,
|
|
// finish the blt the even slower way
|
|
if (MIN_WIDTH >= xExt)
|
|
{
|
|
// but first point to x pixel to start with
|
|
SrcDDRect.loc.pt.X--;
|
|
DstDDRect.loc.pt.X--;
|
|
KeyDDRect.loc.pt.X--;
|
|
goto BltOnePixelAtATime;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// blt from left to right
|
|
else
|
|
{
|
|
while (1)
|
|
{
|
|
// blt the stripe
|
|
#ifdef WINNT_VER40
|
|
ppdev->pfnDrvSrcBlt(ppdev, lpDDHALData,
|
|
#else
|
|
pfnDrvSrcBlt(
|
|
lpDDHALData,
|
|
#endif
|
|
drawbltdef,
|
|
DstDDRect.loc.DW,
|
|
SrcDDRect.loc.DW,
|
|
KeyDDRect.loc.DW,
|
|
dwColorKey,
|
|
MAKELONG(xExt,DstDDRect.ext.pt.Y));
|
|
|
|
// adjust remaining extent
|
|
DstDDRect.ext.pt.X -= xExt;
|
|
// are we done?
|
|
if (0 >= DstDDRect.ext.pt.X)
|
|
break;
|
|
|
|
// adjust ptrs to start of next stripe
|
|
SrcDDRect.loc.pt.X += xExt;
|
|
DstDDRect.loc.pt.X += xExt;
|
|
KeyDDRect.loc.pt.X += xExt;
|
|
|
|
// last stripe might not be STRIPE_WIDTH wide
|
|
if (xExt > DstDDRect.ext.pt.X)
|
|
{
|
|
xExt = DstDDRect.ext.pt.X;
|
|
|
|
// if the last stripe is too narrow,
|
|
// finish the blt the even slower way
|
|
if (MIN_WIDTH >= xExt)
|
|
{
|
|
// ptrs already set
|
|
goto BltOnePixelAtATime;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
* FUNCTION: Blt65()
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef WINNT_VER40
|
|
DWORD Blt65(PDD_BLTDATA pbd)
|
|
{
|
|
DRIVERDATA* lpDDHALData;
|
|
PDEV* ppdev;
|
|
PVGAR pREG;
|
|
#else // Win95
|
|
DWORD __stdcall
|
|
Blt65 ( LPDDHAL_BLTDATA pbd)
|
|
{
|
|
LPGLOBALDATA lpDDHALData = GetDDHALContext( pbd->lpDD);
|
|
#endif
|
|
|
|
HRESULT ddrval;
|
|
DWORD dwFlags;
|
|
|
|
DDRECTL DstDDRect;
|
|
DDRECTL SrcDDRect;
|
|
|
|
#ifdef WINNT_VER40
|
|
|
|
PDD_SURFACE_GLOBAL dst;
|
|
PDD_SURFACE_GLOBAL src;
|
|
|
|
DISPDBG((DBGLVL, "DDraw - Blt65\n"));
|
|
|
|
ppdev = (PDEV*) pbd->lpDD->dhpdev;
|
|
lpDDHALData = (DRIVERDATA*) &ppdev->DriverData; //why ?
|
|
pREG = (PVGAR) lpDDHALData->RegsAddress;
|
|
|
|
#else // Win95
|
|
|
|
LPDDRAWI_DDRAWSURFACE_GBL dst;
|
|
LPDDRAWI_DDRAWSURFACE_GBL src;
|
|
|
|
#if defined(REMOVE_GLOBAL_VARS) && (REMOVE_GLOBAL_VARS != 0)
|
|
PDEV *ppdev;
|
|
|
|
ppdev = GetPDevice(pbd->lpDD);
|
|
#endif
|
|
#endif // WINNT_VER40
|
|
|
|
DD_LOG(("Blt65 Entry\r\n"));
|
|
|
|
#ifdef WINNT_VER40
|
|
SYNC_W_3D(ppdev);
|
|
|
|
// Punt, we don't support Host memory to Screen BLT
|
|
if ((NULL != pbd->lpDDSrcSurface) &&
|
|
(pbd->lpDDSrcSurface->lpGbl->xHint != 0) &&
|
|
(pbd->lpDDSrcSurface->lpGbl->yHint != 0) &&
|
|
(pbd->lpDDSrcSurface->dwReserved1 == 0))
|
|
{
|
|
pbd->ddRVal = DDERR_UNSUPPORTED;
|
|
return DDHAL_DRIVER_NOTHANDLED;
|
|
}
|
|
#endif
|
|
|
|
#if 1 // PC98
|
|
#ifdef WINNT_VER40
|
|
if ( (pbd->lpDDSrcSurface != NULL)
|
|
&& (pbd->lpDDSrcSurface->lpGbl->lPitch < ppdev->lDeltaScreen)
|
|
)
|
|
{
|
|
pbd->ddRVal = DDERR_UNSUPPORTED;
|
|
return DDHAL_DRIVER_NOTHANDLED;
|
|
}
|
|
#else
|
|
if ( (pbd->lpDDSrcSurface != NULL)
|
|
&& (pbd->lpDDSrcSurface->lpGbl->lPitch < pDriverData->HALInfo.vmiData.lDisplayPitch)
|
|
)
|
|
{
|
|
pbd->ddRVal = DDERR_UNSUPPORTED;
|
|
return DDHAL_DRIVER_NOTHANDLED;
|
|
}
|
|
#endif
|
|
#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(("Blt65 Exit - flip in progress, returning %08lX\r\n", ddrval));
|
|
return (DDHAL_DRIVER_HANDLED);
|
|
}
|
|
|
|
// 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 1
|
|
// billy and dah boyz strike again
|
|
// tddraw agp Case 59 asks us to blt between to nonlocal video memory
|
|
// surfaces even though we report that we don't support offscreen
|
|
// plain nonlocal video memory surfaces
|
|
// why is ddraw allocating offscreen plain surfaces in agp memory?
|
|
#if DDRAW_COMPAT >= 50
|
|
// see if the dest is in nonlocal video memory
|
|
if (DDSCAPS_NONLOCALVIDMEM & pbd->lpDDDestSurface->ddsCaps.dwCaps)
|
|
{
|
|
pbd->ddRVal = DDERR_UNSUPPORTED;
|
|
return DDHAL_DRIVER_NOTHANDLED;
|
|
}
|
|
// if there is a src, see if it's in nonlocal video memory
|
|
if ((NULL != pbd->lpDDSrcSurface) &&
|
|
(DDSCAPS_NONLOCALVIDMEM & pbd->lpDDSrcSurface->ddsCaps.dwCaps))
|
|
{
|
|
pbd->ddRVal = DDERR_UNSUPPORTED;
|
|
return DDHAL_DRIVER_NOTHANDLED;
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
#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
|
|
|
|
// get offset, width, and height for destination
|
|
#if defined(DDRAW_COMPAT_10)
|
|
dst = pbd->lpDDDestSurface->lpData;
|
|
#else
|
|
dst = pbd->lpDDDestSurface->lpGbl;
|
|
#endif
|
|
|
|
#ifdef WINNT_VER40
|
|
DstDDRect.loc.DW = cvlxy(ppdev->lDeltaScreen,dst->fpVidMem,BYTESPERPIXEL);
|
|
#else // Win95
|
|
DstDDRect.loc.DW = cvlxy(lpDDHALData,dst->fpVidMem-lpDDHALData->ScreenAddress,BYTESPERPIXEL);
|
|
#endif
|
|
DstDDRect.loc.DW += MAKELONG(pbd->rDest.left,pbd->rDest.top);
|
|
DstDDRect.ext.pt.X = (WORD)(pbd->rDest.right - pbd->rDest.left);
|
|
DstDDRect.ext.pt.Y = (WORD)(pbd->rDest.bottom - pbd->rDest.top);
|
|
|
|
// 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
|
|
{
|
|
#if defined(DDRAW_COMPAT_10)
|
|
src = pbd->lpDDSrcSurface->lpData;
|
|
#else
|
|
src = pbd->lpDDSrcSurface->lpGbl;
|
|
#endif
|
|
|
|
#ifdef WINNT_VER40
|
|
SrcDDRect.loc.DW = cvlxy(ppdev->lDeltaScreen,src->fpVidMem,BYTESPERPIXEL);
|
|
#else // Win95
|
|
SrcDDRect.loc.DW = cvlxy(lpDDHALData,src->fpVidMem-lpDDHALData->ScreenAddress,BYTESPERPIXEL);
|
|
#endif
|
|
SrcDDRect.loc.DW += MAKELONG(pbd->rSrc.left,pbd->rSrc.top);
|
|
SrcDDRect.ext.pt.X = (WORD)(pbd->rSrc.right - pbd->rSrc.left);
|
|
SrcDDRect.ext.pt.Y = (WORD)(pbd->rSrc.bottom - pbd->rSrc.top);
|
|
|
|
if (dwFlags & DDBLT_KEYSRCOVERRIDE) // Source Color Key
|
|
{
|
|
DWORD dwColor =
|
|
#ifdef WINNT_VER40
|
|
DupColor(ppdev,
|
|
#else
|
|
DupColor(
|
|
lpDDHALData,
|
|
#endif
|
|
pbd->bltFX.ddckSrcColorkey.dwColorSpaceLowValue);
|
|
|
|
DD_LOG(("Src Color Key Blt\r\n"));
|
|
|
|
#ifdef DEBUG
|
|
if (FALSE)
|
|
SaveSurfaceToBmp(pbd->lpDDSrcSurface);
|
|
#endif
|
|
|
|
if ((SrcDDRect.ext.pt.X != DstDDRect.ext.pt.X) ||
|
|
(SrcDDRect.ext.pt.Y != DstDDRect.ext.pt.Y))
|
|
{
|
|
#ifdef WINNT_VER40
|
|
// If there is no scratch buffer allocated then punt the
|
|
// transparent stretch BLT
|
|
if (lpDDHALData->ScratchBufferOrg == 0)
|
|
{
|
|
ddrval = DDERR_UNSUPPORTED;
|
|
goto blt_exit;
|
|
};
|
|
#endif
|
|
|
|
if ( !(pbd->lpDDSrcSurface->dwFlags & DDRAWISURF_HASPIXELFORMAT) &&
|
|
(rop == 0x00CC) )
|
|
{
|
|
if (16 >= BITSPERPIXEL)
|
|
{
|
|
DWORD StretchCntl;
|
|
|
|
|
|
if (8 == BITSPERPIXEL)
|
|
{
|
|
StretchCntl = (RGB_8_FMT << SRC_FMT_SHIFT) |
|
|
(RGB_8_FMT << DST_FMT_SHIFT) |
|
|
0;
|
|
}
|
|
else
|
|
{
|
|
// this only works because the src & dst fmt's in stretch control
|
|
// for 565, 24bpp & 32bpp are the same as the bytes/pixel
|
|
StretchCntl = (BYTESPERPIXEL << SRC_FMT_SHIFT) |
|
|
(BYTESPERPIXEL << DST_FMT_SHIFT) |
|
|
0;
|
|
}
|
|
#ifdef WINNT_VER40
|
|
TransparentStretch65(ppdev, lpDDHALData,
|
|
#else
|
|
TransparentStretch65(
|
|
lpDDHALData,
|
|
#endif
|
|
SrcDDRect, DstDDRect, StretchCntl, dwColor);
|
|
}
|
|
else
|
|
{
|
|
#ifdef WINNT_VER40
|
|
StretchColor(ppdev, lpDDHALData,
|
|
#else
|
|
StretchColor(
|
|
lpDDHALData,
|
|
#endif
|
|
DstDDRect.loc.pt.X, DstDDRect.loc.pt.Y,
|
|
DstDDRect.ext.pt.X, DstDDRect.ext.pt.Y,
|
|
SrcDDRect.loc.pt.X, SrcDDRect.loc.pt.Y,
|
|
SrcDDRect.ext.pt.X, SrcDDRect.ext.pt.Y,
|
|
dwColor);
|
|
}
|
|
goto blt_exit;
|
|
}
|
|
else
|
|
{
|
|
DD_LOG(("Unsupported SrcColorKey Blt -> punt\r\n"));
|
|
ddrval = DDERR_UNSUPPORTED;
|
|
goto blt_exit;
|
|
}
|
|
}
|
|
|
|
if (24 != BITSPERPIXEL)
|
|
{
|
|
// if it's 5465AC or earlier, do hw transparency bug workaround
|
|
#ifdef WINNT_VER40
|
|
if (1 >= ppdev->dwLgDevRev)
|
|
#else
|
|
#if 1 //PDR#11507 CK with ConCurrent RAM has the same transparent blt problem with AC.
|
|
if (1 >= lpDDHALData->bLgRevID)
|
|
#else
|
|
if ( ( 1 >= lpDDHALData->bLgRevID ) ||
|
|
( (0x25 == lpDDHALData->bLgRevID) &&
|
|
lpDDHALData->bConCurrentRAM) )
|
|
#endif
|
|
#endif
|
|
{
|
|
// convert to byte extents and positions
|
|
SrcDDRect.loc.pt.X *= (WORD)BYTESPERPIXEL;
|
|
SrcDDRect.ext.pt.X *= (WORD)BYTESPERPIXEL;
|
|
DstDDRect.loc.pt.X *= (WORD)BYTESPERPIXEL;
|
|
DstDDRect.ext.pt.X *= (WORD)BYTESPERPIXEL;
|
|
|
|
if (//(8 >= SrcDDRect.ext.pt.X) &&
|
|
((7 & SrcDDRect.loc.pt.X) > (7 & DstDDRect.loc.pt.X)))
|
|
{
|
|
WORD x_ext;
|
|
|
|
x_ext = 8 - (SrcDDRect.loc.pt.X & 7);
|
|
if (x_ext < SrcDDRect.ext.pt.X)
|
|
{
|
|
#ifdef WINNT_VER40
|
|
ppdev->pfnDrvSrcMBlt(ppdev, lpDDHALData,
|
|
#else
|
|
pfnDrvSrcMBlt(
|
|
lpDDHALData,
|
|
#endif
|
|
#if OP2_ONLY_SRC_COLORKEY
|
|
MAKELONG((DD_TRANS | ROP_OP2_copy),
|
|
((BD_RES+BD_OP2)*IS_VRAM)),
|
|
#else
|
|
MAKELONG(rop|DD_TRANS, bdf | BD_OP2),
|
|
#endif
|
|
DstDDRect.loc.DW,
|
|
SrcDDRect.loc.DW,
|
|
SrcDDRect.loc.DW, // Src transparency
|
|
dwColor,
|
|
MAKELONG(x_ext,DstDDRect.ext.pt.Y));
|
|
SrcDDRect.loc.pt.X += x_ext;
|
|
DstDDRect.loc.pt.X += x_ext;
|
|
SrcDDRect.ext.pt.X -= x_ext;
|
|
DstDDRect.ext.pt.X -= x_ext;
|
|
}
|
|
}
|
|
#ifdef WINNT_VER40
|
|
ppdev->pfnDrvSrcMBlt(ppdev, lpDDHALData,
|
|
#else
|
|
pfnDrvSrcMBlt(
|
|
lpDDHALData,
|
|
#endif
|
|
#if OP2_ONLY_SRC_COLORKEY
|
|
MAKELONG((DD_TRANS | ROP_OP2_copy),
|
|
((BD_RES+BD_OP2)*IS_VRAM)),
|
|
#else
|
|
MAKELONG(rop|DD_TRANS, bdf | BD_OP2),
|
|
#endif
|
|
DstDDRect.loc.DW,
|
|
SrcDDRect.loc.DW,
|
|
SrcDDRect.loc.DW, // Src transparency
|
|
dwColor,
|
|
DstDDRect.ext.DW);
|
|
}
|
|
// 5465AD and later can do it as a single blt
|
|
else
|
|
{
|
|
#ifdef WINNT_VER40
|
|
ppdev->pfnDrvSrcBlt(ppdev, lpDDHALData,
|
|
#else
|
|
pfnDrvSrcBlt(
|
|
lpDDHALData,
|
|
#endif
|
|
#if OP2_ONLY_SRC_COLORKEY
|
|
MAKELONG((DD_TRANS | ROP_OP2_copy),
|
|
((BD_RES+BD_OP2)*IS_VRAM)),
|
|
#else
|
|
MAKELONG(rop|DD_TRANS, bdf | BD_OP2),
|
|
#endif
|
|
DstDDRect.loc.DW,
|
|
SrcDDRect.loc.DW,
|
|
SrcDDRect.loc.DW, // Src transparency
|
|
dwColor,
|
|
DstDDRect.ext.DW);
|
|
}
|
|
}
|
|
else // 24bpp workaround (needed on 5465AD also)
|
|
{
|
|
#ifdef WINNT_VER40
|
|
ColorKeyBlt24(ppdev,lpDDHALData,
|
|
#else
|
|
ColorKeyBlt24(
|
|
lpDDHALData,
|
|
#endif
|
|
#if OP2_ONLY_SRC_COLORKEY
|
|
MAKELONG((DD_TRANS | ROP_OP2_copy),
|
|
((BD_RES+BD_OP2)*IS_VRAM)),
|
|
#else
|
|
MAKELONG(rop|DD_TRANS, bdf|BD_OP2),
|
|
#endif
|
|
DstDDRect,
|
|
SrcDDRect,
|
|
SrcDDRect, // src transparency
|
|
dwColor);
|
|
}
|
|
#ifdef DEBUG
|
|
if (FALSE)
|
|
SaveSurfaceToBmp(pbd->lpDDDestSurface);
|
|
#endif
|
|
|
|
} // (dwFlags & DDBLT_KEYSRCOVERRIDE) // Source Color Key
|
|
else if (dwFlags & DDBLT_KEYDESTOVERRIDE) // Destination Color Key
|
|
{
|
|
DWORD dwColor;
|
|
|
|
dwColor =
|
|
#ifdef WINNT_VER40
|
|
DupColor(ppdev,
|
|
#else
|
|
DupColor(
|
|
lpDDHALData,
|
|
#endif
|
|
pbd->bltFX.ddckDestColorkey.dwColorSpaceLowValue);
|
|
|
|
DD_LOG(("Dst Color Key Blt\r\n"));
|
|
|
|
// Punt if stretch or shrink requested.
|
|
if ((SrcDDRect.ext.pt.X != DstDDRect.ext.pt.X) ||
|
|
(SrcDDRect.ext.pt.Y != DstDDRect.ext.pt.Y))
|
|
{
|
|
DD_LOG(("Unsupported DstColorKey Blt -> punt\r\n"));
|
|
ddrval = DDERR_UNSUPPORTED;
|
|
goto blt_exit;
|
|
}
|
|
|
|
#ifdef WINNT_VER40
|
|
// If the dwSize not equal to the size of DDBLTFX structure
|
|
// Punt it.
|
|
//
|
|
// For the WHQL TDDRAW test case 29, for some reason, the DDBLTFX
|
|
// structure in DD_BLTDATA is invalid. The dwSize and the
|
|
// ddckDestColorkey fields contain garbage value.
|
|
// In order to pass the test, we force the dwColor to zero if
|
|
// the dwSize of DDBLTFX is invalid.
|
|
if (pbd->bltFX.dwSize != sizeof(DDBLTFX))
|
|
{
|
|
// ddrval = DDERR_UNSUPPORTED;
|
|
// goto blt_exit;
|
|
dwColor = 0;
|
|
};
|
|
#endif
|
|
|
|
if (24 != BITSPERPIXEL)
|
|
{
|
|
#ifdef WINNT_VER40
|
|
ppdev->pfnDrvSrcBlt(ppdev, lpDDHALData,
|
|
#else
|
|
pfnDrvSrcBlt(
|
|
lpDDHALData,
|
|
#endif
|
|
MAKELONG(rop|DD_TRANS|DD_TRANSOP, bdf | BD_OP2),
|
|
DstDDRect.loc.DW,
|
|
SrcDDRect.loc.DW,
|
|
DstDDRect.loc.DW, // Dst transparency
|
|
dwColor, //
|
|
DstDDRect.ext.DW);
|
|
}
|
|
else
|
|
{
|
|
#ifdef WINNT_VER40
|
|
ColorKeyBlt24(ppdev,lpDDHALData,
|
|
#else
|
|
ColorKeyBlt24(
|
|
lpDDHALData,
|
|
#endif
|
|
MAKELONG(rop|DD_TRANS|DD_TRANSOP, bdf|BD_OP2),
|
|
DstDDRect,
|
|
SrcDDRect,
|
|
DstDDRect, // dst transparency
|
|
dwColor);
|
|
}
|
|
} // (dwFlags & DDBLT_KEYDESTOVERRIDE) // Destination Color Key
|
|
else
|
|
{
|
|
#if _WIN32_WINNT >= 0x0500
|
|
#define BLAM (DDRAWISURF_HASPIXELFORMAT)
|
|
#else
|
|
#define BLAM (DDRAWISURF_HASPIXELFORMAT | DDRAWISURF_HASOVERLAYDATA)
|
|
#endif
|
|
if ((BLAM == (BLAM & pbd->lpDDDestSurface->dwFlags)) &&
|
|
(BLAM == (BLAM & pbd->lpDDSrcSurface->dwFlags))
|
|
#if _WIN32_WINNT >= 0x0500
|
|
&& (pbd->lpDDDestSurface->ddsCaps.dwCaps & DDSCAPS_OVERLAY)
|
|
&& (pbd->lpDDSrcSurface->ddsCaps.dwCaps & DDSCAPS_OVERLAY)
|
|
#endif
|
|
)
|
|
{
|
|
if (//(FOURCC_UYVY == dst->ddpfSurface.dwFourCC) &&
|
|
//(FOURCC_UYVY == src->ddpfSurface.dwFourCC) &&
|
|
(SrcDDRect.ext.pt.X == DstDDRect.ext.pt.X) &&
|
|
(SrcDDRect.ext.pt.Y == DstDDRect.ext.pt.Y))
|
|
{
|
|
#ifndef WINNT_VER40
|
|
LP_SURFACE_DATA lpSrcSurfaceData;
|
|
LP_SURFACE_DATA lpDstSurfaceData;
|
|
#endif
|
|
DWORD dstbpp,srcbpp;
|
|
|
|
dstbpp = pbd->lpDDDestSurface->lpGbl->ddpfSurface.dwRGBBitCount / 8;
|
|
srcbpp = pbd->lpDDSrcSurface->lpGbl->ddpfSurface.dwRGBBitCount / 8;
|
|
if (dstbpp != srcbpp)
|
|
{
|
|
ddrval = DDERR_UNSUPPORTED;
|
|
goto blt_exit;
|
|
}
|
|
|
|
#ifndef WINNT_VER40
|
|
// see if either the src or dst is a linear surface
|
|
// if so do a CPU memcpy
|
|
lpSrcSurfaceData = (LP_SURFACE_DATA)(pbd->lpDDSrcSurface->dwReserved1);
|
|
lpDstSurfaceData = (LP_SURFACE_DATA)(pbd->lpDDDestSurface->dwReserved1);
|
|
if ((FLG_LINEAR & lpSrcSurfaceData->dwOverlayFlags) ||
|
|
(FLG_LINEAR & lpDstSurfaceData->dwOverlayFlags))
|
|
{
|
|
if (ROP_OP1_copy == rop)
|
|
{
|
|
// mind numbing fb to fb copy
|
|
FBToFBCopy((BYTE *)(lpDDHALData->ScreenAddress + DstDDRect.loc.pt.Y * PITCH + DstDDRect.loc.pt.X * 2),
|
|
dst->lPitch,
|
|
(BYTE *)(lpDDHALData->ScreenAddress + SrcDDRect.loc.pt.Y * PITCH + SrcDDRect.loc.pt.X * 2),
|
|
src->lPitch,
|
|
DstDDRect.ext,
|
|
dstbpp);
|
|
}
|
|
else
|
|
{
|
|
// punt it
|
|
ddrval = DDERR_UNSUPPORTED;
|
|
goto blt_exit;
|
|
}
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
SrcDDRect.loc.pt.X *= (WORD)BYTESPERPIXEL;
|
|
DstDDRect.loc.pt.X *= (WORD)BYTESPERPIXEL;
|
|
SrcDDRect.ext.pt.X *= (WORD)dstbpp;
|
|
DstDDRect.ext.pt.X *= (WORD)dstbpp;
|
|
#ifdef WINNT_VER40
|
|
ppdev->pfnDrvSrcMBlt(ppdev, lpDDHALData,
|
|
#else
|
|
pfnDrvSrcMBlt(
|
|
lpDDHALData,
|
|
#endif
|
|
MAKELONG(rop, bdf),
|
|
DstDDRect.loc.DW,
|
|
SrcDDRect.loc.DW,
|
|
0UL, // don't care
|
|
0UL,
|
|
DstDDRect.ext.DW);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ddrval = DDERR_UNSUPPORTED;
|
|
goto blt_exit;
|
|
}
|
|
}
|
|
else if ((SrcDDRect.ext.pt.X != DstDDRect.ext.pt.X) ||
|
|
(SrcDDRect.ext.pt.Y != DstDDRect.ext.pt.Y) ||
|
|
(DDRAWISURF_HASPIXELFORMAT & pbd->lpDDSrcSurface->dwFlags))
|
|
{
|
|
DWORD StretchCntl;
|
|
DDRECTL OrigSrcDDRect;
|
|
DDRECTL OrigDstDDRect;
|
|
int nDstBytesPixel = BYTESPERPIXEL;
|
|
int nSrcBytesPixel = BYTESPERPIXEL;
|
|
|
|
|
|
if (8 == BITSPERPIXEL)
|
|
{
|
|
StretchCntl = (RGB_8_FMT << SRC_FMT_SHIFT) |
|
|
(RGB_8_FMT << DST_FMT_SHIFT) |
|
|
0;
|
|
}
|
|
else if ((DDRAWISURF_HASPIXELFORMAT & pbd->lpDDSrcSurface->dwFlags) &&
|
|
(DDPF_FOURCC & src->ddpfSurface.dwFlags) &&
|
|
(FOURCC_UYVY == src->ddpfSurface.dwFourCC))
|
|
{
|
|
StretchCntl = (YUV_422_FMT << SRC_FMT_SHIFT)
|
|
| (BYTESPERPIXEL << DST_FMT_SHIFT)
|
|
| XINTERP_ENABLE | YINTERP_ENABLE
|
|
;
|
|
nSrcBytesPixel = 2;
|
|
}
|
|
else
|
|
{
|
|
// this only works because the src & dst fmt's in stretch control
|
|
// for 565, 24bpp & 32bpp are the same as the bytes/pixel
|
|
StretchCntl = (BYTESPERPIXEL << SRC_FMT_SHIFT)
|
|
| (BYTESPERPIXEL << DST_FMT_SHIFT)
|
|
#if 0
|
|
// tddraw agp Cases 21, 23 & 42 do stretch blts with ddraw and
|
|
// the same stretch through gdi, then they expect the results
|
|
// to be identical
|
|
// Since our display driver is not using interpolation on stretch
|
|
// blts then we either need to rewrite StretchBlt in the display
|
|
// driver (lots of days of work) or disable interpolation in
|
|
// ddraw (a one line change)
|
|
| XINTERP_ENABLE | YINTERP_ENABLE
|
|
#endif
|
|
;
|
|
}
|
|
|
|
// now compute byte coordinates of src and dst
|
|
// upper left of surface is based on frame buffer pixel format
|
|
// offset into surface is based on surface pixel format
|
|
#ifdef WINNT_VER40
|
|
OrigDstDDRect.loc.DW = cvlxy(ppdev->lDeltaScreen,dst->fpVidMem,BYTESPERPIXEL);
|
|
#else
|
|
OrigDstDDRect.loc.DW = cvlxy(lpDDHALData,dst->fpVidMem-lpDDHALData->ScreenAddress,
|
|
BYTESPERPIXEL);
|
|
#endif
|
|
OrigDstDDRect.loc.pt.X *= (USHORT)nDstBytesPixel;
|
|
DstDDRect.loc.DW = OrigDstDDRect.loc.DW;
|
|
|
|
#ifdef WINNT_VER40
|
|
OrigSrcDDRect.loc.DW = cvlxy(ppdev->lDeltaScreen,src->fpVidMem,BYTESPERPIXEL);
|
|
#else
|
|
OrigSrcDDRect.loc.DW = cvlxy(lpDDHALData,src->fpVidMem-lpDDHALData->ScreenAddress,
|
|
BYTESPERPIXEL);
|
|
#endif
|
|
OrigSrcDDRect.loc.pt.X *= (USHORT)nDstBytesPixel; // YES, it's nDstBytesPixel
|
|
SrcDDRect.loc.DW = OrigSrcDDRect.loc.DW;
|
|
|
|
#ifndef WINNT_VER40 // nt doesn't get this info
|
|
if (pbd->IsClipped)
|
|
{
|
|
OrigDstDDRect.loc.DW += MAKELONG(pbd->rOrigDest.left * nDstBytesPixel,
|
|
pbd->rOrigDest.top);
|
|
OrigDstDDRect.ext.pt.X = (WORD)((pbd->rOrigDest.right - pbd->rOrigDest.left) *
|
|
nDstBytesPixel);
|
|
OrigDstDDRect.ext.pt.Y = (WORD)(pbd->rOrigDest.bottom - pbd->rOrigDest.top);
|
|
|
|
OrigSrcDDRect.loc.DW += MAKELONG(pbd->rOrigSrc.left * nSrcBytesPixel,
|
|
pbd->rOrigSrc.top);
|
|
OrigSrcDDRect.ext.pt.X = (WORD)((pbd->rOrigSrc.right - pbd->rOrigSrc.left) *
|
|
nSrcBytesPixel);
|
|
OrigSrcDDRect.ext.pt.Y = (WORD)(pbd->rOrigSrc.bottom - pbd->rOrigSrc.top);
|
|
|
|
DstDDRect.loc.DW += MAKELONG(pbd->rDest.left * nDstBytesPixel,
|
|
pbd->rDest.top);
|
|
DstDDRect.ext.pt.X = (WORD)((pbd->rDest.right - pbd->rDest.left) *
|
|
nDstBytesPixel);
|
|
DstDDRect.ext.pt.Y = (WORD)(pbd->rDest.bottom - pbd->rDest.top);
|
|
|
|
SrcDDRect.loc.DW += MAKELONG(pbd->rSrc.left * nSrcBytesPixel,
|
|
pbd->rSrc.top);
|
|
SrcDDRect.ext.pt.X = (WORD)((pbd->rSrc.right - pbd->rSrc.left) *
|
|
nSrcBytesPixel);
|
|
SrcDDRect.ext.pt.Y = (WORD)(pbd->rSrc.bottom - pbd->rSrc.top);
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
OrigDstDDRect.loc.DW += MAKELONG(pbd->rDest.left * nDstBytesPixel,
|
|
pbd->rDest.top);
|
|
DstDDRect.loc.DW = OrigDstDDRect.loc.DW;
|
|
OrigDstDDRect.ext.pt.X = (WORD)((pbd->rDest.right - pbd->rDest.left) *
|
|
nDstBytesPixel);
|
|
DstDDRect.ext.pt.X = OrigDstDDRect.ext.pt.X;
|
|
OrigDstDDRect.ext.pt.Y = (WORD)(pbd->rDest.bottom - pbd->rDest.top);
|
|
DstDDRect.ext.pt.Y = OrigDstDDRect.ext.pt.Y;
|
|
|
|
OrigSrcDDRect.loc.DW += MAKELONG(pbd->rSrc.left * nSrcBytesPixel,
|
|
pbd->rSrc.top);
|
|
SrcDDRect.loc.DW = OrigSrcDDRect.loc.DW;
|
|
OrigSrcDDRect.ext.pt.X = (WORD)((pbd->rSrc.right - pbd->rSrc.left) *
|
|
nSrcBytesPixel);
|
|
SrcDDRect.ext.pt.X = OrigSrcDDRect.ext.pt.X;
|
|
OrigSrcDDRect.ext.pt.Y = (WORD)(pbd->rSrc.bottom - pbd->rSrc.top);
|
|
SrcDDRect.ext.pt.Y = OrigSrcDDRect.ext.pt.Y;
|
|
}
|
|
|
|
#ifdef WINNT_VER40
|
|
DrvStretch65(ppdev, lpDDHALData,
|
|
#else
|
|
DrvStretch65(
|
|
lpDDHALData,
|
|
#endif
|
|
SrcDDRect,
|
|
DstDDRect,
|
|
StretchCntl,
|
|
OrigSrcDDRect,
|
|
OrigDstDDRect);
|
|
}
|
|
else
|
|
{
|
|
#if ENABLE_CLIPPEDBLTS
|
|
DWORD dstBaseXY;
|
|
DWORD srcBaseXY;
|
|
|
|
#ifdef WINNT_VER40
|
|
dstBaseXY = cvlxy(ppdev->lDeltaScreen,dst->fpVidMem,BYTESPERPIXEL);
|
|
srcBaseXY = cvlxy(ppdev->lDeltaScreen,src->fpVidMem,BYTESPERPIXEL);
|
|
#else // Win95
|
|
dstBaseXY = cvlxy(dst->fpVidMem-lpDDHALData->ScreenAddress,BYTESPERPIXEL);
|
|
srcBaseXY = cvlxy(src->fpVidMem-lpDDHALData->ScreenAddress,BYTESPERPIXEL);
|
|
#endif
|
|
|
|
if (pbd->IsClipped)
|
|
{
|
|
// compute original dst coordinates
|
|
DstDDRect.loc.DW = dstBaseXY + MAKELONG(pbd->rOrigDest.left, pbd->rOrigDest.top);
|
|
DstDDRect.ext.pt.X = (WORD)(pbd->rOrigDest.right - pbd->rOrigDest.left);
|
|
DstDDRect.ext.pt.Y = (WORD)(pbd->rOrigDest.bottom - pbd->rOrigDest.top);
|
|
|
|
// compute original src coordinates
|
|
SrcDDRect.loc.DW = srcBaseXY + MAKELONG(pbd->rOrigSrc.left, pbd->rOrigSrc.top);
|
|
SrcDDRect.ext.pt.X = (WORD)(pbd->rOrigSrc.right - pbd->rOrigSrc.left);
|
|
SrcDDRect.ext.pt.Y = (WORD)(pbd->rOrigSrc.bottom - pbd->rOrigSrc.top);
|
|
|
|
// do the blts
|
|
#ifdef WINNT_VER40
|
|
ppdev->pfnClippedDrvSrcBlt(ppdev, lpDDHALData,
|
|
#else
|
|
pfnClippedDrvSrcBlt(
|
|
lpDDHALData,
|
|
#endif
|
|
MAKELONG(rop|DD_CLIP, bdf),
|
|
DstDDRect.loc.DW,
|
|
SrcDDRect.loc.DW,
|
|
0UL, // don't care
|
|
0UL,
|
|
DstDDRect.ext.DW,
|
|
dstBaseXY,
|
|
srcBaseXY,
|
|
pbd->dwRectCnt,
|
|
pbd->prDestRects);
|
|
}
|
|
else // just do a single blt
|
|
{
|
|
// compute dst coordinates
|
|
DstDDRect.loc.DW = dstBaseXY + MAKELONG(pbd->rDest.left, pbd->rDest.top);
|
|
DstDDRect.ext.pt.X = (WORD)(pbd->rDest.right - pbd->rDest.left);
|
|
DstDDRect.ext.pt.Y = (WORD)(pbd->rDest.bottom - pbd->rDest.top);
|
|
|
|
// compute src coordinates
|
|
SrcDDRect.loc.DW = srcBaseXY + MAKELONG(pbd->rSrc.left, pbd->rSrc.top);
|
|
SrcDDRect.ext.pt.X = (WORD)(pbd->rSrc.right - pbd->rSrc.left);
|
|
SrcDDRect.ext.pt.Y = (WORD)(pbd->rSrc.bottom - pbd->rSrc.top);
|
|
#endif // ENABLE_CLIPPEDBLTS
|
|
|
|
// do the blt
|
|
#ifdef WINNT_VER40
|
|
ppdev->pfnDrvSrcBlt(ppdev, lpDDHALData,
|
|
#else
|
|
pfnDrvSrcBlt(
|
|
lpDDHALData,
|
|
#endif
|
|
MAKELONG(rop, bdf),
|
|
DstDDRect.loc.DW,
|
|
SrcDDRect.loc.DW,
|
|
0UL, // don't care
|
|
0UL,
|
|
DstDDRect.ext.DW);
|
|
#if ENABLE_CLIPPEDBLTS
|
|
}
|
|
#endif // ENABLE_CLIPPEDBLTS
|
|
}
|
|
}
|
|
}
|
|
else // DST ONLY rops
|
|
{
|
|
#if ENABLE_CLIPPEDBLTS
|
|
DWORD dstBaseXY;
|
|
#endif // ENABLE_CLIPPEDBLTS
|
|
|
|
DD_LOG(("Dst Only Blt\r\n"));
|
|
|
|
#if ENABLE_CLIPPEDBLTS
|
|
#ifdef WINNT_VER40
|
|
dstBaseXY = cvlxy(ppdev->lDeltaScreen,dst->fpVidMem,BYTESPERPIXEL);
|
|
#else // Win95
|
|
dstBaseXY = cvlxy(dst->fpVidMem-lpDDHALData->ScreenAddress,BYTESPERPIXEL);
|
|
#endif
|
|
|
|
if (pbd->IsClipped)
|
|
{
|
|
// compute original dst coordinates
|
|
DstDDRect.loc.DW = dstBaseXY + MAKELONG(pbd->rOrigDest.left, pbd->rOrigDest.top);
|
|
DstDDRect.ext.pt.X = (WORD)(pbd->rOrigDest.right - pbd->rOrigDest.left);
|
|
DstDDRect.ext.pt.Y = (WORD)(pbd->rOrigDest.bottom - pbd->rOrigDest.top);
|
|
|
|
// do the blts
|
|
#ifdef WINNT_VER40
|
|
ppdev->pfnDrvClippedDstBlt(ppdev, lpDDHALData,
|
|
#else
|
|
pfnDrvClippedDstBlt(
|
|
lpDDHALData,
|
|
#endif
|
|
MAKELONG(rop|DD_CLIP, bdf),
|
|
DstDDRect.loc.DW,
|
|
0UL, // don't care
|
|
DstDDRect.ext.DW,
|
|
dstBaseXY,
|
|
pbd->dwRectCnt,
|
|
pbd->prDestRects);
|
|
}
|
|
else // just do a single blt
|
|
{
|
|
// compute dst coordinates
|
|
DstDDRect.loc.DW = dstBaseXY + MAKELONG(pbd->rDest.left, pbd->rDest.top);
|
|
DstDDRect.ext.pt.X = (WORD)(pbd->rDest.right - pbd->rDest.left);
|
|
DstDDRect.ext.pt.Y = (WORD)(pbd->rDest.bottom - pbd->rDest.top);
|
|
#endif // ENABLE_CLIPPEDBLTS
|
|
|
|
#ifdef WINNT_VER40
|
|
ppdev->pfnDrvDstBlt(ppdev, lpDDHALData,
|
|
#else
|
|
pfnDrvDstBlt(
|
|
lpDDHALData,
|
|
#endif
|
|
MAKELONG(rop, bdf),
|
|
DstDDRect.loc.DW,
|
|
0UL, // don't care
|
|
DstDDRect.ext.DW);
|
|
#if ENABLE_CLIPPEDBLTS
|
|
}
|
|
#endif // ENABLE_CLIPPEDBLTS
|
|
} // endif (bdf & BD_OP1) // SRC rops
|
|
} // (dwFlags & DDBLT_ROP)
|
|
else if (dwFlags & DDBLT_COLORFILL)
|
|
{
|
|
DWORD dwColor;
|
|
#if ENABLE_CLIPPEDBLTS
|
|
DWORD dstBaseXY;
|
|
#endif
|
|
|
|
|
|
DD_LOG(("Solid Color Fill\r\n"));
|
|
|
|
#ifdef WINNT_VER40
|
|
dwColor = DupColor(ppdev,pbd->bltFX.dwFillColor);
|
|
#else
|
|
dwColor = DupColor(lpDDHALData,pbd->bltFX.dwFillColor);
|
|
#endif
|
|
|
|
#if ENABLE_CLIPPEDBLTS
|
|
#ifdef WINNT_VER40
|
|
dstBaseXY = cvlxy(ppdev->lDeltaScreen,dst->fpVidMem,BYTESPERPIXEL);
|
|
#else // Win95
|
|
dstBaseXY = cvlxy(dst->fpVidMem-lpDDHALData->ScreenAddress,BYTESPERPIXEL);
|
|
#endif
|
|
|
|
if (pbd->IsClipped)
|
|
{
|
|
// compute original dst coordinates
|
|
DstDDRect.loc.DW = dstBaseXY + MAKELONG(pbd->rOrigDest.left, pbd->rOrigDest.top);
|
|
DstDDRect.ext.pt.X = (WORD)(pbd->rOrigDest.right - pbd->rOrigDest.left);
|
|
DstDDRect.ext.pt.Y = (WORD)(pbd->rOrigDest.bottom - pbd->rOrigDest.top);
|
|
|
|
// do the blts
|
|
#ifdef WINNT_VER40
|
|
ppdev->pfnClippedDrvDstBlt(ppdev, lpDDHALData,
|
|
#else
|
|
pfnDrvClippedDstBlt(
|
|
lpDDHALData,
|
|
#endif
|
|
MAKELONG(ROP_OP1_copy | DD_CLIP, BD_RES | (BD_OP1 * IS_SOLID)),
|
|
DstDDRect.loc.DW,
|
|
dwColor,
|
|
DstDDRect.ext.DW,
|
|
dstBaseXY,
|
|
pbd->dwRectCnt,
|
|
pbd->prDestRects);
|
|
}
|
|
else // just do a single blt
|
|
{
|
|
// compute dst coordinates
|
|
DstDDRect.loc.DW = dstBaseXY + MAKELONG(pbd->rDest.left, pbd->rDest.top);
|
|
DstDDRect.ext.pt.X = (WORD)(pbd->rDest.right - pbd->rDest.left);
|
|
DstDDRect.ext.pt.Y = (WORD)(pbd->rDest.bottom - pbd->rDest.top);
|
|
#endif // ENABLE_CLIPPEDBLTS
|
|
|
|
#ifdef WINNT_VER40
|
|
ppdev->pfnDrvDstBlt(ppdev, lpDDHALData,
|
|
#else
|
|
pfnDrvDstBlt(
|
|
lpDDHALData,
|
|
#endif
|
|
MAKELONG(ROP_OP1_copy, BD_RES | (BD_OP1 * IS_SOLID)),
|
|
DstDDRect.loc.DW,
|
|
dwColor, // fill color
|
|
DstDDRect.ext.DW);
|
|
#if ENABLE_CLIPPEDBLTS
|
|
}
|
|
#endif
|
|
}
|
|
#ifndef WINNT_VER40 // Not WINNT_VER40
|
|
else if (bD3DInit && dwFlags & DDBLT_DEPTHFILL)
|
|
{
|
|
DWORD dwFillDepth;
|
|
#if ENABLE_CLIPPEDBLTS // I don't think we'll ever get a clipped zbuffer but you never know ...
|
|
DWORD dstBaseXY;
|
|
#endif // ENABLE_CLIPPEDBLTS
|
|
|
|
|
|
DD_LOG(("Depth Fill Blt\r\n"));
|
|
|
|
#ifdef WINNT_VER40
|
|
dwFillDepth = DupZFill(ppdev,pbd->bltFX.dwFillDepth,dst->ddpfSurface.dwZBufferBitDepth);
|
|
#else
|
|
dwFillDepth = DupZFill(lpDDHALData,pbd->bltFX.dwFillDepth,dst->ddpfSurface.dwZBufferBitDepth);
|
|
#endif
|
|
|
|
#if ENABLE_CLIPPEDBLTS
|
|
#ifdef WINNT_VER40
|
|
dstBaseXY = cvlxy(ppdev->lDeltaScreen,dst->fpVidMem,BYTESPERPIXEL);
|
|
#else // Win95
|
|
dstBaseXY = cvlxy(dst->fpVidMem-lpDDHALData->ScreenAddress,BYTESPERPIXEL);
|
|
#endif
|
|
|
|
if (pbd->IsClipped)
|
|
{
|
|
// compute original dst coordinates
|
|
DstDDRect.loc.DW = dstBaseXY + MAKELONG(pbd->rOrigDest.left, pbd->rOrigDest.top);
|
|
DstDDRect.ext.pt.X = (WORD)(pbd->rOrigDest.right - pbd->rOrigDest.left);
|
|
DstDDRect.ext.pt.Y = (WORD)(pbd->rOrigDest.bottom - pbd->rOrigDest.top);
|
|
|
|
// convert to byte blt
|
|
// 16 bit zbuffer in 32 bit frame buffer trashes everything to right
|
|
// of zbuffer
|
|
// Fixes PDR #9152
|
|
DstDDRect.loc.pt.X *= (WORD)(dst->ddpfSurface.dwZBufferBitDepth / 8);
|
|
DstDDRect.ext.pt.X *= (WORD)(dst->ddpfSurface.dwZBufferBitDepth / 8);
|
|
|
|
// do the blts
|
|
#ifdef WINNT_VER40
|
|
ppdev->pfnClippedDrvDstMBlt(ppdev, lpDDHALData,
|
|
#else
|
|
pfnClippedDrvDstMBlt(
|
|
lpDDHALData,
|
|
#endif
|
|
MAKELONG(ROP_OP1_copy | DD_CLIP, BD_RES | (BD_OP1 * IS_SOLID)),
|
|
DstDDRect.loc.DW,
|
|
dwFillDepth,
|
|
DstDDRect.ext.DW,
|
|
dstBaseXY,
|
|
pbd->dwRectCnt,
|
|
pbd->prDestRects);
|
|
}
|
|
else // just do a single blt
|
|
{
|
|
// compute dst coordinates
|
|
DstDDRect.loc.DW = dstBaseXY + MAKELONG(pbd->rDest.left, pbd->rDest.top);
|
|
DstDDRect.ext.pt.X = (WORD)(pbd->rDest.right - pbd->rDest.left);
|
|
DstDDRect.ext.pt.Y = (WORD)(pbd->rDest.bottom - pbd->rDest.top);
|
|
#endif // ENABLE_CLIPPEDBLTS
|
|
|
|
// convert to byte blt
|
|
// 16 bit zbuffer in 32 bit frame buffer trashes everything to right
|
|
// of zbuffer
|
|
// Fixes PDR #9152
|
|
DstDDRect.loc.pt.X *= (WORD)(dst->ddpfSurface.dwZBufferBitDepth / 8);
|
|
DstDDRect.ext.pt.X *= (WORD)(dst->ddpfSurface.dwZBufferBitDepth / 8);
|
|
|
|
#ifdef WINNT_VER40
|
|
ppdev->pfnDrvDstMBlt(ppdev, lpDDHALData,
|
|
#else
|
|
pfnDrvDstMBlt(
|
|
lpDDHALData,
|
|
#endif
|
|
MAKELONG(ROP_OP1_copy, BD_RES | (BD_OP1 * IS_SOLID)),
|
|
DstDDRect.loc.DW,
|
|
dwFillDepth,
|
|
DstDDRect.ext.DW);
|
|
#if ENABLE_CLIPPEDBLTS
|
|
}
|
|
#endif // ENABLE_CLIPPEDBLTS
|
|
}
|
|
#endif
|
|
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(("Blt65 Exit\r\n"));
|
|
|
|
return DDHAL_DRIVER_HANDLED;
|
|
} /* Blt65 */
|
|
|
|
#endif // WINNT_VER35
|
|
|