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

2266 lines
93 KiB

/******************************Module*Header**********************************\
*
* **************************
* * DirectDraw SAMPLE CODE *
* **************************
*
* Module Name: ddbltfx.c
*
* Content: DirectDraw Blt implementation for stretching blts
*
* Copyright (c) 1994-1999 3Dlabs Inc. Ltd. All rights reserved.
* Copyright (c) 1995-2003 Microsoft Corporation. All rights reserved.
\*****************************************************************************/
#include "glint.h"
#include "glintdef.h"
#include "dma.h"
#include "tag.h"
#include "chroma.h"
// A magic number to make it all work.
// This must be 11 or less, according to the P3 spec.
#define MAGIC_NUMBER_2D 11
//-----------------------------------------------------------------------------
//
// _DD_P3BltSourceChroma
//
// Do a blt with no stretching, but with source chroma keying
//
//-----------------------------------------------------------------------------
void
_DD_P3BltSourceChroma(
P3_THUNKEDDATA* pThisDisplay,
LPDDRAWI_DDRAWSURFACE_LCL pSource,
LPDDRAWI_DDRAWSURFACE_LCL pDest,
P3_SURF_FORMAT* pFormatSource,
P3_SURF_FORMAT* pFormatDest,
LPDDHAL_BLTDATA lpBlt,
RECTL *rSrc,
RECTL *rDest)
{
LONG rSrctop, rSrcleft, rDesttop, rDestleft;
BOOL b8to8blit;
BOOL bBlocking;
DWORD dwRenderDirection;
DWORD dwSourceOffset;
DWORD dwLowerSrcBound, dwUpperSrcBound;
P3_DMA_DEFS();
// Beacuse of a bug in RL we sometimes
// have to fiddle with these values
rSrctop = rSrc->top;
rSrcleft = rSrc->left;
rDesttop = rDest->top;
rDestleft = rDest->left;
// Fix coords origin
if(!_DD_BLT_FixRectlOrigin("_DD_P3BltSourceChroma", rSrc, rDest))
{
// Nothing to be blitted
return;
}
if ( ( pFormatDest->DeviceFormat == SURF_CI8 ) &&
( pFormatSource->DeviceFormat == SURF_CI8 ) )
{
// An 8bit->8bit blit. This is treated specially, since no LUT translation is involved.
b8to8blit = TRUE;
}
else
{
b8to8blit = FALSE;
}
DISPDBG((DBGLVL, "P3 Chroma (before): Upper = 0x%08x, Lower = 0x%08x",
lpBlt->bltFX.ddckSrcColorkey.dwColorSpaceHighValue,
lpBlt->bltFX.ddckSrcColorkey.dwColorSpaceLowValue));
// Prepare data to be used as color keying limits
if ( b8to8blit )
{
// No conversion, just use the index value in the R channel.
dwLowerSrcBound = lpBlt->bltFX.ddckSrcColorkey.dwColorSpaceLowValue & 0x000000ff;
dwUpperSrcBound = lpBlt->bltFX.ddckSrcColorkey.dwColorSpaceHighValue | 0xffffff00;
}
else
{
dwLowerSrcBound = lpBlt->bltFX.ddckSrcColorkey.dwColorSpaceLowValue;
dwUpperSrcBound = lpBlt->bltFX.ddckSrcColorkey.dwColorSpaceHighValue;
if ( pFormatSource->DeviceFormat == SURF_8888 )
{
//
// Mask off alpha channel when a single source color key is used
//@@BEGIN_DDKSPLIT
// IZ : This can be a problem when a color key range is used.
//@@END_DDKSPLIT
//
dwUpperSrcBound |= 0xFF000000;
dwLowerSrcBound &= 0x00FFFFFF;
}
}
DISPDBG((DBGLVL, "P3 Chroma (after): Upper = 0x%08x, Lower = 0x%08x",
dwUpperSrcBound, dwLowerSrcBound));
// Determine the direction of the blt
dwRenderDirection = _DD_BLT_GetBltDirection(pSource->lpGbl->fpVidMem,
pDest->lpGbl->fpVidMem,
rSrc,
rDest,
&bBlocking);
P3_DMA_GET_BUFFER_ENTRIES(32);
// Even though the AlphaBlend is disabled, the chromakeying uses
// the ColorFormat, ColorOrder and ColorConversion fields.
SEND_P3_DATA(PixelSize, (2 - DDSurf_GetChipPixelSize(pDest)));
SEND_P3_DATA(AlphaBlendColorMode,
P3RX_ALPHABLENDCOLORMODE_ENABLE ( __PERMEDIA_DISABLE )
| P3RX_ALPHABLENDCOLORMODE_COLORFORMAT ( pFormatDest->DitherFormat )
| P3RX_ALPHABLENDCOLORMODE_COLORORDER ( COLOR_MODE )
| P3RX_ALPHABLENDCOLORMODE_COLORCONVERSION ( P3RX_ALPHABLENDMODE_CONVERT_SHIFT )
);
SEND_P3_DATA(AlphaBlendAlphaMode,
P3RX_ALPHABLENDALPHAMODE_ENABLE ( __PERMEDIA_DISABLE )
| P3RX_ALPHABLENDALPHAMODE_NOALPHABUFFER( __PERMEDIA_DISABLE )
| P3RX_ALPHABLENDALPHAMODE_ALPHATYPE ( P3RX_ALPHABLENDMODE_ALPHATYPE_OGL )
| P3RX_ALPHABLENDALPHAMODE_ALPHACONVERSION ( P3RX_ALPHABLENDMODE_CONVERT_SHIFT )
);
// Setup the hw chromakeying registers
SEND_P3_DATA(ChromaTestMode,
P3RX_CHROMATESTMODE_ENABLE(__PERMEDIA_ENABLE)
| P3RX_CHROMATESTMODE_SOURCE(P3RX_CHROMATESTMODE_SOURCE_FBDATA)
| P3RX_CHROMATESTMODE_PASSACTION(P3RX_CHROMATESTMODE_ACTION_REJECT)
| P3RX_CHROMATESTMODE_FAILACTION(P3RX_CHROMATESTMODE_ACTION_PASS)
);
SEND_P3_DATA(ChromaLower, dwLowerSrcBound);
SEND_P3_DATA(ChromaUpper, dwUpperSrcBound);
SEND_P3_DATA(LogicalOpMode, GLINT_ENABLED_LOGICALOP( __GLINT_LOGICOP_NOOP ));
SEND_P3_DATA(FBWriteBufferAddr0,
DDSurf_SurfaceOffsetFromMemoryBase(pThisDisplay, pDest));
SEND_P3_DATA(FBWriteBufferWidth0, DDSurf_GetPixelPitch(pDest));
SEND_P3_DATA(FBWriteBufferOffset0, 0);
SEND_P3_DATA(FBSourceReadBufferAddr,
DDSurf_SurfaceOffsetFromMemoryBase(pThisDisplay, pSource));
SEND_P3_DATA(FBSourceReadBufferWidth, DDSurf_GetPixelPitch(pSource));
dwSourceOffset = (( rSrc->top - rDest->top ) << 16 ) |
(( rSrc->left - rDest->left ) & 0xffff );
SEND_P3_DATA(FBSourceReadBufferOffset, dwSourceOffset);
SEND_P3_DATA(FBDestReadMode,
P3RX_FBDESTREAD_READENABLE(__PERMEDIA_DISABLE)
| P3RX_FBDESTREAD_LAYOUT0(P3RX_LAYOUT_LINEAR));
SEND_P3_DATA(FBWriteMode,
P3RX_FBWRITEMODE_WRITEENABLE(__PERMEDIA_ENABLE)
| P3RX_FBWRITEMODE_LAYOUT0(P3RX_LAYOUT_LINEAR));
SEND_P3_DATA(FBSourceReadMode,
P3RX_FBSOURCEREAD_READENABLE(__PERMEDIA_ENABLE)
| P3RX_FBSOURCEREAD_LAYOUT(P3RX_LAYOUT_LINEAR)
| P3RX_FBSOURCEREAD_BLOCKING(bBlocking));
P3_DMA_COMMIT_BUFFER();
P3_DMA_GET_BUFFER_ENTRIES(30);
// Can't use 2D setup because we aren't rendering with spans.
if (dwRenderDirection == 0)
{
// right to left, bottom to top
SEND_P3_DATA(StartXDom, (rDest->right << 16));
SEND_P3_DATA(StartXSub, (rDest->left << 16));
SEND_P3_DATA(StartY, ((rDest->bottom - 1) << 16));
SEND_P3_DATA(dY, (DWORD)((-1) << 16));
}
else
{
// left to right, top to bottom
SEND_P3_DATA(StartXDom, (rDest->left << 16));
SEND_P3_DATA(StartXSub, (rDest->right << 16));
SEND_P3_DATA(StartY, (rDest->top << 16));
SEND_P3_DATA(dY, (1 << 16));
}
SEND_P3_DATA(Count, rDest->bottom - rDest->top );
// Do the blt
SEND_P3_DATA(Render,
P3RX_RENDER_PRIMITIVETYPE(P3RX_RENDER_PRIMITIVETYPE_TRAPEZOID)
| P3RX_RENDER_FBSOURCEREADENABLE(__PERMEDIA_ENABLE));
// Disable all the units that were switched on.
SEND_P3_DATA(ChromaTestMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(AlphaBlendColorMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(AlphaBlendAlphaMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(LogicalOpMode, __PERMEDIA_DISABLE );
// Put back the values if we changed them.
rSrc->top = rSrctop;
rSrc->left = rSrcleft;
rDest->top = rDesttop;
rDest->left = rDestleft;
P3_DMA_COMMIT_BUFFER();
} // _DD_P3BltSourceChroma
//-----------------------------------------------------------------------------
//
// _DD_P3BltStretchSrcChDstCh
//
//
// Does a blit through the texture unit to allow stretching. Also
// handle mirroring if the stretched image requires it and doth dest and
// source chromakeying. Can also YUV->RGB convert
//
// This is the generic rout - others will be optimisations of this
// (if necessary).
//
//
//-----------------------------------------------------------------------------
VOID
_DD_P3BltStretchSrcChDstCh(
P3_THUNKEDDATA* pThisDisplay,
FLATPTR fpSrcVidMem,
P3_SURF_FORMAT* pFormatSource,
DWORD dwSrcPixelSize,
DWORD dwSrcWidth,
DWORD dwSrcHeight,
DWORD dwSrcPixelPitch,
DWORD dwSrcPatchMode,
ULONG ulSrcOffsetFromMemBase,
DWORD dwSrcFlags,
DDPIXELFORMAT* pSrcDDPF,
BOOL bIsSourceAGP,
FLATPTR fpDestVidMem,
P3_SURF_FORMAT* pFormatDest,
DWORD dwDestPixelSize,
DWORD dwDestWidth,
DWORD dwDestHeight,
DWORD dwDestPixelPitch,
DWORD dwDestPatchMode,
ULONG ulDestOffsetFromMemBase,
DWORD dwBltFlags,
DWORD dwBltDDFX,
DDCOLORKEY BltSrcColorKey,
DDCOLORKEY BltDestColorKey,
RECTL *rSrc,
RECTL *rDest)
{
ULONG renderData;
RECTL rMySrc, rMyDest;
int iXScale, iYScale;
int iSrcWidth, iSrcHeight;
int iDstWidth, iDstHeight;
DWORD texSStart, texTStart;
DWORD dwRenderDirection;
BOOL bXMirror, bYMirror;
BOOL bFiltering;
BOOL bSrcKey, bDstKey;
BOOL bDisableLUT;
int iTemp;
BOOL b8to8blit;
BOOL bYUVMode;
BOOL bBlocking;
DWORD TR0;
int iTextureType;
int iPixelSize;
int iTextureFilterModeColorOrder;
SurfFilterDeviceFormat sfdfTextureFilterModeFormat;
P3_DMA_DEFS();
// Make local copies that we can mangle.
rMySrc = *rSrc;
rMyDest = *rDest;
// Fix coords origin
if(!_DD_BLT_FixRectlOrigin("_DD_P3BltStretchSrcChDstCh",
&rMySrc, &rMyDest))
{
// Nothing to be blitted
return;
}
iSrcWidth = rMySrc.right - rMySrc.left;
iSrcHeight = rMySrc.bottom - rMySrc.top;
iDstWidth = rMyDest.right - rMyDest.left;
iDstHeight = rMyDest.bottom - rMyDest.top;
bDisableLUT = FALSE;
if (pFormatSource->DeviceFormat == SURF_YUV422)
{
bYUVMode = TRUE;
// Always use ABGR for YUV;
iTextureFilterModeColorOrder = 0;
}
else
{
bYUVMode = FALSE;
iTextureFilterModeColorOrder = COLOR_MODE;
}
sfdfTextureFilterModeFormat = pFormatSource->FilterFormat;
if ( ( pFormatDest->DeviceFormat == SURF_CI8 ) &&
( pFormatSource->DeviceFormat == SURF_CI8 ) )
{
// An 8bit->8bit blit. This is treated specially,
// since no LUT translation is involved.
// Fake this up in a wacky way to stop the LUT
// getting it's hands on it.
sfdfTextureFilterModeFormat = SURF_FILTER_L8;
bDisableLUT = TRUE;
b8to8blit = TRUE;
}
else
{
b8to8blit = FALSE;
}
// Let's see if anyone uses this flag - might be good to get it working
// now that we know what it means (use bilinear filtering instead of point).
ASSERTDD ( ( dwBltFlags & DDBLTFX_ARITHSTRETCHY ) == 0,
"** _DD_P3BltStretchSrcChDstCh: DDBLTFX_ARITHSTRETCHY used");
// Is this a stretch blit?
if (((iSrcWidth != iDstWidth) ||
(iSrcHeight != iDstHeight)) &&
((pFormatSource->DeviceFormat == SURF_YUV422)) )
{
bFiltering = TRUE;
}
else
{
bFiltering = FALSE;
}
if ( ( dwBltFlags & DDBLT_KEYSRCOVERRIDE ) != 0 )
{
bSrcKey = TRUE;
}
else
{
bSrcKey = FALSE;
}
if ( ( dwBltFlags & DDBLT_KEYDESTOVERRIDE ) != 0 )
{
bDstKey = TRUE;
}
else
{
bDstKey = FALSE;
}
// Determine the direction of the blt
dwRenderDirection = _DD_BLT_GetBltDirection(fpSrcVidMem,
fpDestVidMem,
&rMySrc,
&rMyDest,
&bBlocking);
// If we are doing special effects, and we are mirroring,
// we need to fix up the rectangles and change the sense of
// the render operation - we need to be carefull with overlapping
// rectangles
if (dwRenderDirection)
{
if(dwBltFlags & DDBLT_DDFX)
{
if(dwBltDDFX & DDBLTFX_MIRRORUPDOWN)
{
if (pThisDisplay->dwDXVersion < DX6_RUNTIME)
{
// Need to fix up the rectangles
iTemp = rMySrc.bottom;
rMySrc.bottom = dwSrcHeight - rMySrc.top;
rMySrc.top = dwSrcHeight - iTemp;
}
bYMirror = TRUE;
}
else
{
bYMirror = FALSE;
}
if(dwBltDDFX & DDBLTFX_MIRRORLEFTRIGHT)
{
if (pThisDisplay->dwDXVersion < DX6_RUNTIME)
{
// Need to fix up the rectangles
iTemp = rMySrc.right;
rMySrc.right = dwSrcWidth - rMySrc.left;
rMySrc.left = dwSrcWidth - iTemp;
}
bXMirror = TRUE;
}
else
{
bXMirror = FALSE;
}
}
else
{
bXMirror = FALSE;
bYMirror = FALSE;
}
}
else
{
if(dwBltFlags & DDBLT_DDFX)
{
if(dwBltDDFX & DDBLTFX_MIRRORUPDOWN)
{
if (pThisDisplay->dwDXVersion < DX6_RUNTIME)
{
// Fix up the rectangles
iTemp = rMySrc.bottom;
rMySrc.bottom = dwSrcHeight - rMySrc.top;
rMySrc.top = dwSrcHeight - iTemp;
}
bYMirror = FALSE;
}
else
{
bYMirror = TRUE;
}
if(dwBltDDFX & DDBLTFX_MIRRORLEFTRIGHT)
{
if (pThisDisplay->dwDXVersion < DX6_RUNTIME)
{
// Need to fix up the rectangles
iTemp = rMySrc.right;
rMySrc.right = dwSrcWidth - rMySrc.left;
rMySrc.left = dwSrcWidth - iTemp;
}
bXMirror = FALSE;
}
else
{
bXMirror = TRUE;
}
}
else
{
// Not mirroring, but need to render from the other side.
bXMirror = TRUE;
bYMirror = TRUE;
}
}
// MAGIC_NUMBER_2D can be anything, but it needs to be at least as
// big as the widest texture, but not too big or you'll lose fractional
// precision. Valid range for a P3 is 0->11
ASSERTDD ( iSrcWidth <= ( 1 << MAGIC_NUMBER_2D ),
"_DD_P3BltStretchSrcChDstCh: MAGIC_NUMBER_2D is too small" );
ASSERTDD ( iSrcHeight <= ( 1 << MAGIC_NUMBER_2D ),
"_DD_P3BltStretchSrcChDstCh: MAGIC_NUMBER_2D is too small" );
ASSERTDD ( ( iSrcWidth > 0 ) && ( iSrcHeight > 0 ) &&
( iDstWidth > 0 ) && ( iDstHeight > 0 ),
"_DD_P3BltStretchSrcChDstCh: width or height negative" );
if ( bFiltering )
{
// This must be an unsigned divide, because we need the top bit.
iXScale = ( ( ( (unsigned)iSrcWidth ) << (32-MAGIC_NUMBER_2D) ) /
(unsigned)( iDstWidth ) );
iYScale = ( ( ( (unsigned)iSrcHeight ) << (32-MAGIC_NUMBER_2D) ) /
(unsigned)( iDstHeight ) );
}
else
{
// This must be an unsigned divide, because we need the top bit.
iXScale = ( ( (unsigned)iSrcWidth << (32-MAGIC_NUMBER_2D)) /
(unsigned)( iDstWidth ) );
iYScale = ( ( (unsigned)iSrcHeight << (32-MAGIC_NUMBER_2D)) /
(unsigned)( iDstHeight) );
}
if (bXMirror)
{
texSStart = ( rMySrc.right - 1 ) << (32-MAGIC_NUMBER_2D);
iXScale = -iXScale;
}
else
{
texSStart = rMySrc.left << (32-MAGIC_NUMBER_2D);
}
if (bYMirror)
{
texTStart = ( rMySrc.bottom - 1 ) << (32-MAGIC_NUMBER_2D);
iYScale = -iYScale;
}
else
{
texTStart = rMySrc.top << (32-MAGIC_NUMBER_2D);
}
// Move pixel centres to 0.5, 0.5.
if ( bFiltering )
{
texSStart -= 1 << (31-MAGIC_NUMBER_2D);
texTStart -= 1 << (31-MAGIC_NUMBER_2D);
}
DISPDBG((DBGLVL, "Blt from (%d, %d) to (%d,%d) (%d, %d)",
rMySrc.left, rMySrc.top,
rMyDest.left, rMyDest.top,
rMyDest.right, rMyDest.bottom));
P3_DMA_GET_BUFFER_ENTRIES(24);
SEND_P3_DATA(PixelSize, (2 - dwDestPixelSize ));
// Vape the cache.
P3RX_INVALIDATECACHE(__PERMEDIA_ENABLE, __PERMEDIA_ENABLE);
// The write buffer is the destination for the pixels
SEND_P3_DATA(FBWriteBufferAddr0, ulDestOffsetFromMemBase);
SEND_P3_DATA(FBWriteBufferWidth0, dwDestPixelPitch);
SEND_P3_DATA(FBWriteBufferOffset0, 0);
SEND_P3_DATA(PixelSize, (2 - dwDestPixelSize));
SEND_P3_DATA(RectanglePosition, P3RX_RECTANGLEPOSITION_X( rMyDest.left )
| P3RX_RECTANGLEPOSITION_Y( rMyDest.top ));
renderData = P3RX_RENDER2D_WIDTH(( rMyDest.right - rMyDest.left ) & 0xfff )
| P3RX_RENDER2D_FBREADSOURCEENABLE( __PERMEDIA_ENABLE )
| P3RX_RENDER2D_HEIGHT ( 0 )
| P3RX_RENDER2D_INCREASINGX( __PERMEDIA_ENABLE )
| P3RX_RENDER2D_INCREASINGY( __PERMEDIA_ENABLE )
| P3RX_RENDER2D_TEXTUREENABLE( __PERMEDIA_ENABLE );
SEND_P3_DATA(Render2D, renderData);
// This is the alpha blending unit.
// AlphaBlendxxxMode are set up by the context code.
ASSERTDD ( pFormatDest->DitherFormat >= 0,
"_DD_P3BltStretchSrcChDstCh: Destination format illegal" );
// The colour format, order and conversion fields are used by the
// chroma keying, even though this register is disabled.
SEND_P3_DATA(AlphaBlendColorMode,
P3RX_ALPHABLENDCOLORMODE_ENABLE ( __PERMEDIA_DISABLE )
| P3RX_ALPHABLENDCOLORMODE_COLORFORMAT ( pFormatDest->DitherFormat )
| P3RX_ALPHABLENDCOLORMODE_COLORORDER ( COLOR_MODE )
| P3RX_ALPHABLENDCOLORMODE_COLORCONVERSION ( P3RX_ALPHABLENDMODE_CONVERT_SHIFT )
);
SEND_P3_DATA(AlphaBlendAlphaMode,
P3RX_ALPHABLENDALPHAMODE_ENABLE ( __PERMEDIA_DISABLE )
| P3RX_ALPHABLENDALPHAMODE_NOALPHABUFFER( __PERMEDIA_DISABLE )
| P3RX_ALPHABLENDALPHAMODE_ALPHATYPE ( P3RX_ALPHABLENDMODE_ALPHATYPE_OGL )
| P3RX_ALPHABLENDALPHAMODE_ALPHACONVERSION ( P3RX_ALPHABLENDMODE_CONVERT_SHIFT )
);
P3_DMA_COMMIT_BUFFER();
P3_DMA_GET_BUFFER_ENTRIES(26);
// If there is only one chromakey needed, use the proper chromakey
// This is mainly because the alphamap version doesn't work yet.
if ( bDstKey )
{
// Dest keying.
// The conventional chroma test is set up to key off the dest - the framebuffer.
SEND_P3_DATA(ChromaTestMode,
P3RX_CHROMATESTMODE_ENABLE(__PERMEDIA_ENABLE) |
P3RX_CHROMATESTMODE_SOURCE(P3RX_CHROMATESTMODE_SOURCE_FBDATA) |
P3RX_CHROMATESTMODE_PASSACTION(P3RX_CHROMATESTMODE_ACTION_PASS) |
P3RX_CHROMATESTMODE_FAILACTION(P3RX_CHROMATESTMODE_ACTION_REJECT)
);
SEND_P3_DATA(ChromaLower, BltDestColorKey.dwColorSpaceLowValue);
SEND_P3_DATA(ChromaUpper, BltDestColorKey.dwColorSpaceHighValue);
// The source buffer is the source for the destination color key
SEND_P3_DATA(FBSourceReadBufferAddr, ulDestOffsetFromMemBase);
SEND_P3_DATA(FBSourceReadBufferWidth, dwDestPixelPitch);
SEND_P3_DATA(FBSourceReadBufferOffset, 0);
// Enable source reads to get the colorkey color
SEND_P3_DATA(FBSourceReadMode,
P3RX_FBSOURCEREAD_READENABLE(__PERMEDIA_ENABLE) |
P3RX_FBSOURCEREAD_LAYOUT(dwDestPatchMode)
);
}
else
{
// Don't need source reads - the source data comes from the texturemap
SEND_P3_DATA(FBSourceReadMode,
P3RX_FBSOURCEREAD_READENABLE(__PERMEDIA_DISABLE));
if ( bSrcKey )
{
DWORD dwLowerSrcBound;
DWORD dwUpperSrcBound;
// Source keying, no dest keying.
// The conventional chroma test is set up to key off the source.
// Note we are keying off the input from the texture here, so we use the INPUTCOLOR as the chroma test
// source
SEND_P3_DATA(ChromaTestMode,
P3RX_CHROMATESTMODE_ENABLE(__PERMEDIA_ENABLE) |
P3RX_CHROMATESTMODE_SOURCE(P3RX_CHROMATESTMODE_SOURCE_INPUTCOLOR) |
P3RX_CHROMATESTMODE_PASSACTION(P3RX_CHROMATESTMODE_ACTION_REJECT) |
P3RX_CHROMATESTMODE_FAILACTION(P3RX_CHROMATESTMODE_ACTION_PASS)
);
if ( b8to8blit )
{
// No conversion, just use the index value in the R channel.
dwLowerSrcBound = BltSrcColorKey.dwColorSpaceLowValue & 0x000000ff;
dwUpperSrcBound = BltSrcColorKey.dwColorSpaceHighValue | 0xffffff00;
}
else
{
// Don't scale, do a shift instead.
Get8888ScaledChroma(pThisDisplay,
dwSrcFlags,
pSrcDDPF,
BltSrcColorKey.dwColorSpaceLowValue,
BltSrcColorKey.dwColorSpaceHighValue,
&dwLowerSrcBound,
&dwUpperSrcBound,
NULL, // NULL palette
FALSE,
TRUE);
}
DISPDBG((DBGLVL,"P3 Src Chroma: Upper = 0x%08x, Lower = 0x%08x",
BltSrcColorKey.dwColorSpaceLowValue,
BltSrcColorKey.dwColorSpaceHighValue));
DISPDBG((DBGLVL,"P3 Src Chroma(after): "
"Upper = 0x%08x, Lower = 0x%08x",
dwUpperSrcBound,
dwLowerSrcBound));
SEND_P3_DATA(ChromaLower, dwLowerSrcBound);
SEND_P3_DATA(ChromaUpper, dwUpperSrcBound);
}
else if ( !bSrcKey && !bDstKey )
{
// No chroma keying at all.
SEND_P3_DATA(ChromaTestMode,
P3RX_CHROMATESTMODE_ENABLE(__PERMEDIA_DISABLE ) );
}
}
if ( bDstKey && bSrcKey )
{
DWORD dwLowerSrcBound;
DWORD dwUpperSrcBound;
if ( b8to8blit )
{
DISPDBG((ERRLVL,"Er... don't know what to do in this situation."));
}
// Enable source reads to get the colorkey color during dest colorkeys
SEND_P3_DATA(FBSourceReadMode,
P3RX_FBSOURCEREAD_READENABLE(__PERMEDIA_ENABLE) |
P3RX_FBSOURCEREAD_LAYOUT(dwDestPatchMode)
);
// Don't scale, do a shift instead.
Get8888ZeroExtendedChroma(pThisDisplay,
dwSrcFlags,
pSrcDDPF,
BltSrcColorKey.dwColorSpaceLowValue,
BltSrcColorKey.dwColorSpaceHighValue,
&dwLowerSrcBound,
&dwUpperSrcBound);
// If both colourkeys are needed, the source keying is done by counting
// chroma test fails in the texture filter unit.
SEND_P3_DATA(TextureChromaLower0, dwLowerSrcBound);
SEND_P3_DATA(TextureChromaUpper0, dwUpperSrcBound);
SEND_P3_DATA(TextureChromaLower1, dwLowerSrcBound);
SEND_P3_DATA(TextureChromaUpper1, dwUpperSrcBound);
SEND_P3_DATA(TextureFilterMode,
P3RX_TEXFILTERMODE_ENABLE ( __PERMEDIA_ENABLE )
| P3RX_TEXFILTERMODE_FORMATBOTH ( sfdfTextureFilterModeFormat )
| P3RX_TEXFILTERMODE_COLORORDERBOTH ( COLOR_MODE )
| P3RX_TEXFILTERMODE_ALPHAMAPENABLEBOTH ( __PERMEDIA_ENABLE )
| P3RX_TEXFILTERMODE_ALPHAMAPSENSEBOTH ( P3RX_ALPHAMAPSENSE_INRANGE )
| P3RX_TEXFILTERMODE_COMBINECACHES ( __PERMEDIA_ENABLE )
| P3RX_TEXFILTERMODE_SHIFTBOTH ( __PERMEDIA_ENABLE )
| P3RX_TEXFILTERMODE_ALPHAMAPFILTERING ( __PERMEDIA_ENABLE )
| P3RX_TEXFILTERMODE_ALPHAMAPFILTERLIMIT0 ( bFiltering ? 3 : 0 )
| P3RX_TEXFILTERMODE_ALPHAMAPFILTERLIMIT1 ( 4 )
| P3RX_TEXFILTERMODE_ALPHAMAPFILTERLIMIT01 ( 8 )
);
}
else
{
SEND_P3_DATA(TextureFilterMode,
P3RX_TEXFILTERMODE_ENABLE ( __PERMEDIA_ENABLE )
| P3RX_TEXFILTERMODE_FORMATBOTH ( sfdfTextureFilterModeFormat )
| P3RX_TEXFILTERMODE_COLORORDERBOTH ( iTextureFilterModeColorOrder )
| P3RX_TEXFILTERMODE_ALPHAMAPENABLEBOTH ( __PERMEDIA_DISABLE )
| P3RX_TEXFILTERMODE_COMBINECACHES ( __PERMEDIA_ENABLE )
| P3RX_TEXFILTERMODE_ALPHAMAPFILTERING ( __PERMEDIA_DISABLE )
| P3RX_TEXFILTERMODE_FORCEALPHATOONEBOTH ( __PERMEDIA_DISABLE )
| P3RX_TEXFILTERMODE_SHIFTBOTH ( __PERMEDIA_ENABLE )
);
// And now the alpha test (alpha test unit)
SEND_P3_DATA ( AlphaTestMode, P3RX_ALPHATESTMODE_ENABLE ( __PERMEDIA_DISABLE ) );
}
P3_DMA_COMMIT_BUFFER();
P3_DMA_GET_BUFFER_ENTRIES(18);
SEND_P3_DATA ( AntialiasMode, P3RX_ANTIALIASMODE_ENABLE ( __PERMEDIA_DISABLE ) );
// Texture coordinate unit.
SEND_P3_DATA(TextureCoordMode,
P3RX_TEXCOORDMODE_ENABLE ( __PERMEDIA_ENABLE )
| P3RX_TEXCOORDMODE_WRAPS ( P3RX_TEXCOORDMODE_WRAP_REPEAT )
| P3RX_TEXCOORDMODE_WRAPT ( P3RX_TEXCOORDMODE_WRAP_REPEAT )
| P3RX_TEXCOORDMODE_OPERATION ( P3RX_TEXCOORDMODE_OPERATION_2D )
| P3RX_TEXCOORDMODE_INHIBITDDAINIT ( __PERMEDIA_DISABLE )
| P3RX_TEXCOORDMODE_ENABLELOD ( __PERMEDIA_DISABLE )
| P3RX_TEXCOORDMODE_ENABLEDY ( __PERMEDIA_DISABLE )
| P3RX_TEXCOORDMODE_WIDTH ( log2 ( dwDestWidth ) )
| P3RX_TEXCOORDMODE_HEIGHT ( log2 ( dwDestHeight ) )
| P3RX_TEXCOORDMODE_TEXTUREMAPTYPE ( P3RX_TEXCOORDMODE_TEXTUREMAPTYPE_2D )
| P3RX_TEXCOORDMODE_WRAPS1 ( P3RX_TEXCOORDMODE_WRAP_CLAMP )
| P3RX_TEXCOORDMODE_WRAPT1 ( P3RX_TEXCOORDMODE_WRAP_CLAMP )
);
SEND_P3_DATA(SStart, texSStart);
SEND_P3_DATA(TStart, texTStart);
SEND_P3_DATA(dSdx, iXScale);
SEND_P3_DATA(dSdyDom, 0);
SEND_P3_DATA(dTdx, 0);
SEND_P3_DATA(dTdyDom, iYScale);
SEND_P3_DATA(TextureBaseAddr0, ulSrcOffsetFromMemBase);
P3_DMA_COMMIT_BUFFER();
P3_DMA_GET_BUFFER_ENTRIES(32);
if ( bYUVMode )
{
// Set up the YUV unit.
SEND_P3_DATA ( YUVMode, P3RX_YUVMODE_ENABLE ( __PERMEDIA_ENABLE ) );
iTextureType = P3RX_TEXREADMODE_TEXTURETYPE_VYUY422;
iPixelSize = P3RX_TEXREADMODE_TEXELSIZE_16;
// The idea here is to do ((colorcomp - 16) * 1.14), but in YUV space
// because the YUV unit comes after the texture composite unit.
SEND_P3_DATA(TextureCompositeMode,
P3RX_TEXCOMPMODE_ENABLE ( __PERMEDIA_ENABLE ));
SEND_P3_DATA(TextureCompositeColorMode0,
P3RX_TEXCOMPCAMODE01_ENABLE(__PERMEDIA_ENABLE)
| P3RX_TEXCOMPCAMODE01_ARG1(P3RX_TEXCOMP_T0C)
| P3RX_TEXCOMPCAMODE01_INVARG1(__PERMEDIA_DISABLE)
| P3RX_TEXCOMPCAMODE01_ARG2(P3RX_TEXCOMP_FC)
| P3RX_TEXCOMPCAMODE01_INVARG2(__PERMEDIA_DISABLE)
| P3RX_TEXCOMPCAMODE01_A(P3RX_TEXCOMP_ARG1)
| P3RX_TEXCOMPCAMODE01_B(P3RX_TEXCOMP_ARG2)
| P3RX_TEXCOMPCAMODE01_OPERATION(P3RX_TEXCOMP_OPERATION_SUBTRACT_AB)
| P3RX_TEXCOMPCAMODE01_SCALE(P3RX_TEXCOMP_OPERATION_SCALE_ONE));
SEND_P3_DATA(TextureCompositeAlphaMode0,
P3RX_TEXCOMPCAMODE01_ENABLE(__PERMEDIA_ENABLE)
| P3RX_TEXCOMPCAMODE01_ARG1(P3RX_TEXCOMP_T0A)
| P3RX_TEXCOMPCAMODE01_INVARG1(__PERMEDIA_DISABLE)
| P3RX_TEXCOMPCAMODE01_ARG2(P3RX_TEXCOMP_FA)
| P3RX_TEXCOMPCAMODE01_INVARG2(__PERMEDIA_DISABLE)
| P3RX_TEXCOMPCAMODE01_A(P3RX_TEXCOMP_ARG1)
| P3RX_TEXCOMPCAMODE01_B(P3RX_TEXCOMP_ARG2)
| P3RX_TEXCOMPCAMODE01_OPERATION(P3RX_TEXCOMP_OPERATION_SUBTRACT_AB)
| P3RX_TEXCOMPCAMODE01_SCALE(P3RX_TEXCOMP_OPERATION_SCALE_ONE));
// This subtracts 16 from Y
SEND_P3_DATA(TextureCompositeFactor0, ((0 << 24) |
(0x0 << 16)|
(0x0 << 8) |
(0x10) ));
// This multiplies the channels by 0.57.
SEND_P3_DATA(TextureCompositeFactor1, ((0x80 << 24) |
(0x80 << 16) |
(0x80 << 8) |
(0x91) ));
SEND_P3_DATA(TextureCompositeColorMode1,
P3RX_TEXCOMPCAMODE01_ENABLE(__PERMEDIA_ENABLE)
| P3RX_TEXCOMPCAMODE01_ARG1(P3RX_TEXCOMP_OC)
| P3RX_TEXCOMPCAMODE01_INVARG1(__PERMEDIA_DISABLE)
| P3RX_TEXCOMPCAMODE01_ARG2(P3RX_TEXCOMP_FC)
| P3RX_TEXCOMPCAMODE01_INVARG2(__PERMEDIA_DISABLE)
| P3RX_TEXCOMPCAMODE01_A(P3RX_TEXCOMP_ARG1)
| P3RX_TEXCOMPCAMODE01_B(P3RX_TEXCOMP_ARG2)
| P3RX_TEXCOMPCAMODE01_OPERATION(P3RX_TEXCOMP_OPERATION_MODULATE_AB)
| P3RX_TEXCOMPCAMODE01_SCALE(P3RX_TEXCOMP_OPERATION_SCALE_TWO));
SEND_P3_DATA(TextureCompositeAlphaMode1,
P3RX_TEXCOMPCAMODE01_ENABLE(__PERMEDIA_ENABLE)
| P3RX_TEXCOMPCAMODE01_ARG1(P3RX_TEXCOMP_OC)
| P3RX_TEXCOMPCAMODE01_INVARG1(__PERMEDIA_DISABLE)
| P3RX_TEXCOMPCAMODE01_ARG2(P3RX_TEXCOMP_FA)
| P3RX_TEXCOMPCAMODE01_INVARG2(__PERMEDIA_DISABLE)
| P3RX_TEXCOMPCAMODE01_A(P3RX_TEXCOMP_ARG1)
| P3RX_TEXCOMPCAMODE01_B(P3RX_TEXCOMP_ARG2)
| P3RX_TEXCOMPCAMODE01_OPERATION(P3RX_TEXCOMP_OPERATION_MODULATE_AB)
| P3RX_TEXCOMPCAMODE01_SCALE(P3RX_TEXCOMP_OPERATION_SCALE_TWO));
}
else
{
iTextureType = P3RX_TEXREADMODE_TEXTURETYPE_NORMAL;
iPixelSize = dwSrcPixelSize;
// Disable the composite units.
SEND_P3_DATA(TextureCompositeMode,
P3RX_TEXCOMPMODE_ENABLE ( __PERMEDIA_DISABLE ) );
}
// Pass through the texel.
SEND_P3_DATA(TextureApplicationMode,
P3RX_TEXAPPMODE_ENABLE ( __PERMEDIA_ENABLE )
| P3RX_TEXAPPMODE_BOTHA ( P3RX_TEXAPP_A_CC )
| P3RX_TEXAPPMODE_BOTHB ( P3RX_TEXAPP_B_TC )
| P3RX_TEXAPPMODE_BOTHI ( P3RX_TEXAPP_I_CA )
| P3RX_TEXAPPMODE_BOTHINVI ( __PERMEDIA_DISABLE )
| P3RX_TEXAPPMODE_BOTHOP ( P3RX_TEXAPP_OPERATION_PASS_B )
| P3RX_TEXAPPMODE_KDENABLE ( __PERMEDIA_DISABLE )
| P3RX_TEXAPPMODE_KSENABLE ( __PERMEDIA_DISABLE )
| P3RX_TEXAPPMODE_MOTIONCOMPENABLE ( __PERMEDIA_DISABLE )
);
TR0 = P3RX_TEXREADMODE_ENABLE ( __PERMEDIA_ENABLE )
| P3RX_TEXREADMODE_WIDTH ( 0 )
| P3RX_TEXREADMODE_HEIGHT ( 0 )
| P3RX_TEXREADMODE_TEXELSIZE ( iPixelSize )
| P3RX_TEXREADMODE_TEXTURE3D ( __PERMEDIA_DISABLE )
| P3RX_TEXREADMODE_COMBINECACHES ( __PERMEDIA_ENABLE )
| P3RX_TEXREADMODE_MAPBASELEVEL ( 0 )
| P3RX_TEXREADMODE_MAPMAXLEVEL ( 0 )
| P3RX_TEXREADMODE_LOGICALTEXTURE ( 0 )
| P3RX_TEXREADMODE_ORIGIN ( P3RX_TEXREADMODE_ORIGIN_TOPLEFT )
| P3RX_TEXREADMODE_TEXTURETYPE ( iTextureType )
| P3RX_TEXREADMODE_BYTESWAP ( P3RX_TEXREADMODE_BYTESWAP_NONE )
| P3RX_TEXREADMODE_MIRROR ( __PERMEDIA_DISABLE )
| P3RX_TEXREADMODE_INVERT ( __PERMEDIA_DISABLE )
| P3RX_TEXREADMODE_OPAQUESPAN ( __PERMEDIA_DISABLE )
;
SEND_P3_DATA(TextureReadMode0, TR0);
SEND_P3_DATA(TextureReadMode1, TR0);
SEND_P3_DATA(TextureMapWidth0,
P3RX_TEXMAPWIDTH_WIDTH(dwSrcPixelPitch) |
P3RX_TEXMAPWIDTH_LAYOUT(dwSrcPatchMode) |
P3RX_TEXMAPWIDTH_HOSTTEXTURE(bIsSourceAGP));
SEND_P3_DATA(TextureCacheReplacementMode,
P3RX_TEXCACHEREPLACEMODE_KEEPOLDEST0 ( __PERMEDIA_DISABLE )
| P3RX_TEXCACHEREPLACEMODE_KEEPOLDEST1 ( __PERMEDIA_DISABLE )
| P3RX_TEXCACHEREPLACEMODE_SHOWCACHEINFO ( __PERMEDIA_DISABLE )
);
SEND_P3_DATA(TextureMapSize, 0 );
if ( bDisableLUT )
{
SEND_P3_DATA(LUTMode, P3RX_LUTMODE_ENABLE ( __PERMEDIA_DISABLE ) );
}
if ( bFiltering )
{
// Texture index unit
SEND_P3_DATA(TextureIndexMode0,
P3RX_TEXINDEXMODE_ENABLE ( __PERMEDIA_ENABLE )
| P3RX_TEXINDEXMODE_WIDTH ( MAGIC_NUMBER_2D )
| P3RX_TEXINDEXMODE_HEIGHT ( MAGIC_NUMBER_2D )
| P3RX_TEXINDEXMODE_BORDER ( __PERMEDIA_DISABLE )
| P3RX_TEXINDEXMODE_WRAPU ( P3RX_TEXINDEXMODE_WRAP_REPEAT )
| P3RX_TEXINDEXMODE_WRAPV ( P3RX_TEXINDEXMODE_WRAP_REPEAT )
| P3RX_TEXINDEXMODE_MAPTYPE ( P3RX_TEXINDEXMODE_MAPTYPE_2D )
| P3RX_TEXINDEXMODE_MAGFILTER ( P3RX_TEXINDEXMODE_FILTER_LINEAR )
| P3RX_TEXINDEXMODE_MINFILTER ( P3RX_TEXINDEXMODE_FILTER_LINEAR )
| P3RX_TEXINDEXMODE_TEX3DENABLE ( __PERMEDIA_DISABLE )
| P3RX_TEXINDEXMODE_MIPMAPENABLE ( __PERMEDIA_DISABLE )
| P3RX_TEXINDEXMODE_NEARESTBIAS ( P3RX_TEXINDEXMODE_BIAS_ZERO )
| P3RX_TEXINDEXMODE_LINEARBIAS ( P3RX_TEXINDEXMODE_BIAS_ZERO )
| P3RX_TEXINDEXMODE_SOURCETEXELENABLE ( __PERMEDIA_DISABLE )
);
}
else
{
// Texture index unit
SEND_P3_DATA(TextureIndexMode0,
P3RX_TEXINDEXMODE_ENABLE ( __PERMEDIA_ENABLE )
| P3RX_TEXINDEXMODE_WIDTH ( MAGIC_NUMBER_2D )
| P3RX_TEXINDEXMODE_HEIGHT ( MAGIC_NUMBER_2D )
| P3RX_TEXINDEXMODE_BORDER ( __PERMEDIA_DISABLE )
| P3RX_TEXINDEXMODE_WRAPU ( P3RX_TEXINDEXMODE_WRAP_REPEAT )
| P3RX_TEXINDEXMODE_WRAPV ( P3RX_TEXINDEXMODE_WRAP_REPEAT )
| P3RX_TEXINDEXMODE_MAPTYPE ( P3RX_TEXINDEXMODE_MAPTYPE_2D )
| P3RX_TEXINDEXMODE_MAGFILTER ( P3RX_TEXINDEXMODE_FILTER_NEAREST )
| P3RX_TEXINDEXMODE_MINFILTER ( P3RX_TEXINDEXMODE_FILTER_NEAREST )
| P3RX_TEXINDEXMODE_TEX3DENABLE ( __PERMEDIA_DISABLE )
| P3RX_TEXINDEXMODE_MIPMAPENABLE ( __PERMEDIA_DISABLE )
| P3RX_TEXINDEXMODE_NEARESTBIAS ( P3RX_TEXINDEXMODE_BIAS_ZERO )
| P3RX_TEXINDEXMODE_LINEARBIAS ( P3RX_TEXINDEXMODE_BIAS_ZERO )
| P3RX_TEXINDEXMODE_SOURCETEXELENABLE ( __PERMEDIA_DISABLE )
);
}
ASSERTDD ( pFormatDest->DitherFormat >= 0,
"_DD_P3BltStretchSrcChDstCh: Destination format illegal" );
P3_DMA_COMMIT_BUFFER();
P3_DMA_GET_BUFFER_ENTRIES(10);
if ( bFiltering )
{
// Filtering, so dither.
SEND_P3_DATA(DitherMode,
P3RX_DITHERMODE_ENABLE ( __PERMEDIA_ENABLE )
| P3RX_DITHERMODE_DITHERENABLE ( __PERMEDIA_ENABLE )
| P3RX_DITHERMODE_COLORFORMAT ( pFormatDest->DitherFormat )
| P3RX_DITHERMODE_XOFFSET ( 0 )
| P3RX_DITHERMODE_YOFFSET ( 0 )
| P3RX_DITHERMODE_COLORORDER ( COLOR_MODE )
| P3RX_DITHERMODE_ALPHADITHER ( P3RX_DITHERMODE_ALPHADITHER_DITHER )
| P3RX_DITHERMODE_ROUNDINGMODE ( P3RX_DITHERMODE_ROUNDINGMODE_TRUNCATE )
);
}
else
{
// No filter, no dither (though it doesn't actually matter).
SEND_P3_DATA(DitherMode,
P3RX_DITHERMODE_ENABLE ( __PERMEDIA_ENABLE )
| P3RX_DITHERMODE_DITHERENABLE ( __PERMEDIA_DISABLE )
| P3RX_DITHERMODE_COLORFORMAT ( pFormatDest->DitherFormat )
| P3RX_DITHERMODE_XOFFSET ( 0 )
| P3RX_DITHERMODE_YOFFSET ( 0 )
| P3RX_DITHERMODE_COLORORDER ( COLOR_MODE )
| P3RX_DITHERMODE_ALPHADITHER ( P3RX_DITHERMODE_ALPHADITHER_DITHER )
| P3RX_DITHERMODE_ROUNDINGMODE ( P3RX_DITHERMODE_ROUNDINGMODE_TRUNCATE )
);
}
SEND_P3_DATA(LogicalOpMode,
P3RX_LOGICALOPMODE_ENABLE ( __PERMEDIA_DISABLE ) );
SEND_P3_DATA(PixelSize, (2 - dwDestPixelSize));
SEND_P3_DATA(FBWriteMode,
P3RX_FBWRITEMODE_WRITEENABLE(__PERMEDIA_ENABLE) |
P3RX_FBWRITEMODE_LAYOUT0(dwDestPatchMode)
);
WAIT_FIFO(22);
P3_ENSURE_DX_SPACE(22);
SEND_P3_DATA(Count, rMyDest.bottom - rMyDest.top );
SEND_P3_DATA(Render,
P3RX_RENDER_PRIMITIVETYPE ( P3RX_RENDER_PRIMITIVETYPE_TRAPEZOID )
| P3RX_RENDER_TEXTUREENABLE ( __PERMEDIA_ENABLE )
| P3RX_RENDER_FOGENABLE ( __PERMEDIA_DISABLE )
| P3RX_RENDER_FBSOURCEREADENABLE( (bDstKey ? __PERMEDIA_ENABLE : __PERMEDIA_DISABLE))
);
// Disable all the things I switched on.
SEND_P3_DATA(ChromaTestMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(AlphaBlendColorMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(AlphaBlendAlphaMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(TextureFilterMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(AlphaTestMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(AntialiasMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(TextureCoordMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(TextureReadMode0, __PERMEDIA_DISABLE );
SEND_P3_DATA(TextureIndexMode0, __PERMEDIA_DISABLE );
P3_ENSURE_DX_SPACE(20);
WAIT_FIFO(20);
SEND_P3_DATA(TextureCompositeMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(TextureCompositeColorMode0, __PERMEDIA_DISABLE);
SEND_P3_DATA(TextureCompositeAlphaMode0, __PERMEDIA_DISABLE);
SEND_P3_DATA(TextureCompositeColorMode1, __PERMEDIA_DISABLE);
SEND_P3_DATA(TextureCompositeAlphaMode1, __PERMEDIA_DISABLE);
SEND_P3_DATA(TextureApplicationMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(DitherMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(FBSourceReadMode, __PERMEDIA_DISABLE);
SEND_P3_DATA(LogicalOpMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(YUVMode, __PERMEDIA_DISABLE );
P3_DMA_COMMIT_BUFFER();
} // _DD_P3BltStretchSrcChDstCh
//-----------------------------------------------------------------------------
//
// _DD_P3BltStretchSrcChDstCh_DD
//
// Stretch blit with source and destination chroma keying
// This version takes as parameters DDraw objects
//
//-----------------------------------------------------------------------------
VOID
_DD_P3BltStretchSrcChDstCh_DD(
P3_THUNKEDDATA* pThisDisplay,
LPDDRAWI_DDRAWSURFACE_LCL pSource,
LPDDRAWI_DDRAWSURFACE_LCL pDest,
P3_SURF_FORMAT* pFormatSource,
P3_SURF_FORMAT* pFormatDest,
LPDDHAL_BLTDATA lpBlt,
RECTL *rSrc,
RECTL *rDest)
{
_DD_P3BltStretchSrcChDstCh(pThisDisplay,
// pSource data elements
pSource->lpGbl->fpVidMem,
pFormatSource,
DDSurf_GetChipPixelSize(pSource),
(int)pSource->lpGbl->wWidth,
(int)pSource->lpGbl->wHeight,
DDSurf_GetPixelPitch(pSource),
P3RX_LAYOUT_LINEAR,
DDSurf_SurfaceOffsetFromMemoryBase(pThisDisplay, pSource),
pSource->dwFlags,
&pSource->lpGbl->ddpfSurface,
DDSurf_IsAGP(pSource),
// pDest data elements
pDest->lpGbl->fpVidMem,
pFormatDest,
DDSurf_GetChipPixelSize(pDest),
(int)pDest->lpGbl->wWidth,
(int)pDest->lpGbl->wHeight,
DDSurf_GetPixelPitch(pDest),
P3RX_LAYOUT_LINEAR,
DDSurf_SurfaceOffsetFromMemoryBase(pThisDisplay, pDest),
// Others
lpBlt->dwFlags,
lpBlt->bltFX.dwDDFX,
lpBlt->bltFX.ddckSrcColorkey,
lpBlt->bltFX.ddckDestColorkey,
rSrc,
rDest);
} // _DD_P3BltStretchSrcChDstCh_DD
//-----------------------------------------------------------------------------
//
// __P3BltDestOveride
//
//-----------------------------------------------------------------------------
VOID
__P3BltDestOveride(
P3_THUNKEDDATA* pThisDisplay,
LPDDRAWI_DDRAWSURFACE_LCL pSource,
LPDDRAWI_DDRAWSURFACE_LCL pDest,
P3_SURF_FORMAT* pFormatSource,
P3_SURF_FORMAT* pFormatDest,
RECTL *rSrc,
RECTL *rDest,
DWORD logicop,
DWORD dwDestPointer)
{
DWORD renderData;
LONG rSrctop, rSrcleft, rDesttop, rDestleft;
DWORD dwSourceOffset;
BOOL bBlocking;
DWORD dwRenderDirection;
DWORD dwDestPatchMode, dwSourcePatchMode;
P3_DMA_DEFS();
// Beacuse of a bug in RL we sometimes have to fiddle with these values
rSrctop = rSrc->top;
rSrcleft = rSrc->left;
rDesttop = rDest->top;
rDestleft = rDest->left;
// Fix coords origin
if(!_DD_BLT_FixRectlOrigin("__P3BltDestOveride", rSrc, rDest))
{
// Nothing to be blitted
return;
}
// Determine the direction of the blt
dwRenderDirection = _DD_BLT_GetBltDirection(pSource->lpGbl->fpVidMem,
pDest->lpGbl->fpVidMem,
rSrc,
rDest,
&bBlocking);
P3_DMA_GET_BUFFER();
P3_ENSURE_DX_SPACE(30);
WAIT_FIFO(30);
SEND_P3_DATA(PixelSize, (2 - DDSurf_GetChipPixelSize(pDest)));
SEND_P3_DATA(FBWriteBufferAddr0, dwDestPointer);
SEND_P3_DATA(FBWriteBufferWidth0, DDSurf_GetPixelPitch(pDest));
SEND_P3_DATA(FBWriteBufferOffset0, 0);
SEND_P3_DATA(FBSourceReadBufferAddr,
DDSurf_SurfaceOffsetFromMemoryBase(pThisDisplay, pSource));
SEND_P3_DATA(FBSourceReadBufferWidth, DDSurf_GetPixelPitch(pSource));
dwSourceOffset = (( rSrc->top - rDest->top ) << 16 ) |
(( rSrc->left - rDest->left ) & 0xffff );
SEND_P3_DATA(FBSourceReadBufferOffset, dwSourceOffset);
dwDestPatchMode = P3RX_LAYOUT_LINEAR;
dwSourcePatchMode = P3RX_LAYOUT_LINEAR;
SEND_P3_DATA(FBDestReadMode,
P3RX_FBDESTREAD_READENABLE(__PERMEDIA_DISABLE));
SEND_P3_DATA(FBSourceReadMode,
P3RX_FBSOURCEREAD_READENABLE(__PERMEDIA_ENABLE) |
P3RX_FBSOURCEREAD_LAYOUT(dwSourcePatchMode) |
P3RX_FBSOURCEREAD_BLOCKING( bBlocking ));
SEND_P3_DATA(FBWriteMode,
P3RX_FBWRITEMODE_WRITEENABLE(__PERMEDIA_ENABLE) |
P3RX_FBWRITEMODE_LAYOUT0(dwDestPatchMode));
P3_ENSURE_DX_SPACE(16);
WAIT_FIFO(16);
SEND_P3_DATA(RectanglePosition,
P3RX_RECTANGLEPOSITION_Y(rDest->top) |
P3RX_RECTANGLEPOSITION_X(rDest->left));
renderData =
P3RX_RENDER2D_WIDTH(( rDest->right - rDest->left ) & 0xfff ) |
P3RX_RENDER2D_HEIGHT(( rDest->bottom - rDest->top ) & 0xfff ) |
P3RX_RENDER2D_FBREADSOURCEENABLE(__PERMEDIA_ENABLE) |
P3RX_RENDER2D_SPANOPERATION( P3RX_RENDER2D_SPAN_VARIABLE ) |
P3RX_RENDER2D_INCREASINGX( dwRenderDirection ) |
P3RX_RENDER2D_INCREASINGY( dwRenderDirection );
SEND_P3_DATA(Render2D, renderData);
// Put back the values if we changed them.
rSrc->top = rSrctop;
rSrc->left = rSrcleft;
rDest->top = rDesttop;
rDest->left = rDestleft;
P3_DMA_COMMIT_BUFFER();
} // __P3BltDestOveride
//-----------------------------------------------------------------------------
//
// __P3BltStretchSrcChDstChSourceOveride
//
//-----------------------------------------------------------------------------
VOID
__P3BltStretchSrcChDstChSourceOveride(
P3_THUNKEDDATA* pThisDisplay,
LPDDRAWI_DDRAWSURFACE_LCL pSource,
LPDDRAWI_DDRAWSURFACE_LCL pDest,
P3_SURF_FORMAT* pFormatSource,
P3_SURF_FORMAT* pFormatDest,
LPDDHAL_BLTDATA lpBlt,
RECTL *rSrc,
RECTL *rDest,
DWORD dwNewSource
)
{
ULONG renderData;
RECTL rMySrc, rMyDest;
int iXScale, iYScale;
int iSrcWidth, iSrcHeight;
int iDstWidth, iDstHeight;
DWORD texSStart, texTStart;
DWORD dwRenderDirection;
BOOL bXMirror, bYMirror;
BOOL bFiltering;
BOOL bSrcKey, bDstKey;
BOOL bDisableLUT;
BOOL bBlocking;
int iTemp;
BOOL b8to8blit;
BOOL bYUVMode;
DWORD TR0;
int iTextureType;
int iPixelSize;
int iTextureFilterModeColorOrder;
SurfFilterDeviceFormat sfdfTextureFilterModeFormat;
P3_DMA_DEFS();
bDisableLUT = FALSE;
// Make local copies that we can mangle.
rMySrc = *rSrc;
rMyDest = *rDest;
// Fix coords origin
if(!_DD_BLT_FixRectlOrigin("__P3BltStretchSrcChDstChSourceOveride",
&rMySrc, &rMyDest))
{
// Nothing to be blitted
return;
}
iSrcWidth = rMySrc.right - rMySrc.left;
iSrcHeight = rMySrc.bottom - rMySrc.top;
iDstWidth = rMyDest.right - rMyDest.left;
iDstHeight = rMyDest.bottom - rMyDest.top;
if (pFormatSource->DeviceFormat == SURF_YUV422)
{
bYUVMode = TRUE;
// Always use ABGR for YUV;
iTextureFilterModeColorOrder = 0;
}
else
{
bYUVMode = FALSE;
iTextureFilterModeColorOrder = COLOR_MODE;
}
sfdfTextureFilterModeFormat = pFormatSource->FilterFormat;
if ( ( pFormatDest->DeviceFormat == SURF_CI8 ) && ( pFormatSource->DeviceFormat == SURF_CI8 ) )
{
// An 8bit->8bit blit. This is treated specially, since no LUT translation is involved.
// Fake this up in a wacky way to stop the LUT
// getting it's hands on it.
sfdfTextureFilterModeFormat = SURF_FILTER_L8;
bDisableLUT = TRUE;
b8to8blit = TRUE;
}
else
{
b8to8blit = FALSE;
}
// Let's see if anyone uses this flag - might be good to get it working
// now that we know what it means (use bilinear filtering instead of point).
ASSERTDD ( ( lpBlt->dwFlags & DDBLTFX_ARITHSTRETCHY ) == 0, "** _DD_P3BltStretchSrcChDstCh: DDBLTFX_ARITHSTRETCHY used - please tell TomF" );
// Is this a stretch blit?
if (((iSrcWidth != iDstWidth) ||
(iSrcHeight != iDstHeight)) &&
((pFormatSource->DeviceFormat == SURF_YUV422)))
{
bFiltering = TRUE;
}
else
{
bFiltering = FALSE;
}
if ( ( lpBlt->dwFlags & DDBLT_KEYSRCOVERRIDE ) != 0 )
{
bSrcKey = TRUE;
}
else
{
bSrcKey = FALSE;
}
if ( ( lpBlt->dwFlags & DDBLT_KEYDESTOVERRIDE ) != 0 )
{
bDstKey = TRUE;
}
else
{
bDstKey = FALSE;
}
// Determine the direction of the blt
dwRenderDirection = _DD_BLT_GetBltDirection(pSource->lpGbl->fpVidMem,
pDest->lpGbl->fpVidMem,
&rMySrc,
&rMyDest,
&bBlocking);
// If we are doing special effects, and we are mirroring,
// we need to fix up the rectangles and change the sense of
// the render operation - we need to be carefull with overlapping
// rectangles
if (dwRenderDirection)
{
if(lpBlt->dwFlags & DDBLT_DDFX)
{
if(lpBlt->bltFX.dwDDFX & DDBLTFX_MIRRORUPDOWN)
{
if (pThisDisplay->dwDXVersion < DX6_RUNTIME)
{
// Need to fix up the rectangles
iTemp = rMySrc.bottom;
rMySrc.bottom = pSource->lpGbl->wHeight - rMySrc.top;
rMySrc.top = pSource->lpGbl->wHeight - iTemp;
}
bYMirror = TRUE;
}
else
{
bYMirror = FALSE;
}
if(lpBlt->bltFX.dwDDFX & DDBLTFX_MIRRORLEFTRIGHT)
{
if (pThisDisplay->dwDXVersion < DX6_RUNTIME)
{
// Need to fix up the rectangles
iTemp = rMySrc.right;
rMySrc.right = pSource->lpGbl->wWidth - rMySrc.left;
rMySrc.left = pSource->lpGbl->wWidth - iTemp;
}
bXMirror = TRUE;
}
else
{
bXMirror = FALSE;
}
}
else
{
bXMirror = FALSE;
bYMirror = FALSE;
}
}
else
{
if(lpBlt->dwFlags & DDBLT_DDFX)
{
if(lpBlt->bltFX.dwDDFX & DDBLTFX_MIRRORUPDOWN)
{
if (pThisDisplay->dwDXVersion < DX6_RUNTIME)
{
// Fix up the rectangles
iTemp = rMySrc.bottom;
rMySrc.bottom = pSource->lpGbl->wHeight - rMySrc.top;
rMySrc.top = pSource->lpGbl->wHeight - iTemp;
}
bYMirror = FALSE;
}
else
{
bYMirror = TRUE;
}
if(lpBlt->bltFX.dwDDFX & DDBLTFX_MIRRORLEFTRIGHT)
{
if (pThisDisplay->dwDXVersion < DX6_RUNTIME)
{
// Need to fix up the rectangles
iTemp = rMySrc.right;
rMySrc.right = pSource->lpGbl->wWidth - rMySrc.left;
rMySrc.left = pSource->lpGbl->wWidth - iTemp;
}
bXMirror = FALSE;
}
else
{
bXMirror = TRUE;
}
}
else
{
// Not mirroring, but need to render from the other side.
bXMirror = TRUE;
bYMirror = TRUE;
}
}
// MAGIC_NUMBER_2D can be anything, but it needs to be at least as
// big as the widest texture, but not too big or you'll lose fractional
// precision. Valid range for a P3 is 0->11
ASSERTDD ( iSrcWidth <= ( 1 << MAGIC_NUMBER_2D ), "** _DD_P3BltStretchSrcChDstCh: MAGIC_NUMBER_2D is too small" );
ASSERTDD ( iSrcHeight <= ( 1 << MAGIC_NUMBER_2D ), "** _DD_P3BltStretchSrcChDstCh: MAGIC_NUMBER_2D is too small" );
ASSERTDD ( ( iSrcWidth > 0 ) && ( iSrcHeight > 0 ) && ( iDstWidth > 0 ) && ( iDstHeight > 0 ), "** _DD_P3BltStretchSrcChDstCh: width or height negative" );
if ( bFiltering )
{
// This must be an unsigned divide, because we need the top bit.
iXScale = ( ( ( (unsigned)iSrcWidth ) << (32-MAGIC_NUMBER_2D) ) / (unsigned)( iDstWidth ) );
iYScale = ( ( ( (unsigned)iSrcHeight ) << (32-MAGIC_NUMBER_2D) ) / (unsigned)( iDstHeight ) );
}
else
{
// This must be an unsigned divide, because we need the top bit.
iXScale = ( ( (unsigned)iSrcWidth << (32-MAGIC_NUMBER_2D)) / (unsigned)( iDstWidth ) );
iYScale = ( ( (unsigned)iSrcHeight << (32-MAGIC_NUMBER_2D)) / (unsigned)( iDstHeight) );
}
if (bXMirror)
{
texSStart = ( rMySrc.right - 1 ) << (32-MAGIC_NUMBER_2D);
iXScale = -iXScale;
}
else
{
texSStart = rMySrc.left << (32-MAGIC_NUMBER_2D);
}
if (bYMirror)
{
texTStart = ( rMySrc.bottom - 1 ) << (32-MAGIC_NUMBER_2D);
iYScale = -iYScale;
}
else
{
texTStart = rMySrc.top << (32-MAGIC_NUMBER_2D);
}
// Move pixel centres to 0.5, 0.5.
if ( bFiltering )
{
texSStart -= 1 << (31-MAGIC_NUMBER_2D);
texTStart -= 1 << (31-MAGIC_NUMBER_2D);
}
DISPDBG((DBGLVL, "Blt from (%d, %d) to (%d,%d) (%d, %d)",
rMySrc.left, rMySrc.top,
rMyDest.left, rMyDest.top,
rMyDest.right, rMyDest.bottom));
P3_DMA_GET_BUFFER_ENTRIES(24);
SEND_P3_DATA(PixelSize, (2 - DDSurf_GetChipPixelSize(pDest)));
// Vape the cache.
P3RX_INVALIDATECACHE(__PERMEDIA_ENABLE, __PERMEDIA_ENABLE);
// The write buffer is the destination for the pixels
SEND_P3_DATA(FBWriteBufferAddr0, DDSurf_SurfaceOffsetFromMemoryBase(pThisDisplay, pDest));
SEND_P3_DATA(FBWriteBufferWidth0, DDSurf_GetPixelPitch(pDest));
SEND_P3_DATA(FBWriteBufferOffset0, 0);
SEND_P3_DATA(PixelSize, (2 - DDSurf_GetChipPixelSize(pDest)));
SEND_P3_DATA(RectanglePosition, P3RX_RECTANGLEPOSITION_X( rMyDest.left )
| P3RX_RECTANGLEPOSITION_Y( rMyDest.top ));
renderData = P3RX_RENDER2D_WIDTH(( rMyDest.right - rMyDest.left ) & 0xfff )
| P3RX_RENDER2D_FBREADSOURCEENABLE( __PERMEDIA_ENABLE )
| P3RX_RENDER2D_HEIGHT ( 0 )
| P3RX_RENDER2D_INCREASINGX( __PERMEDIA_ENABLE )
| P3RX_RENDER2D_INCREASINGY( __PERMEDIA_ENABLE )
| P3RX_RENDER2D_TEXTUREENABLE( __PERMEDIA_ENABLE );
SEND_P3_DATA(Render2D, renderData);
// This is the alpha blending unit.
// AlphaBlendxxxMode are set up by the context code.
ASSERTDD ( pFormatDest->DitherFormat >= 0, "** _DD_P3BltStretchSrcChDstCh: Destination format illegal" );
// The colour format, order and conversion fields are used by the chroma keying,
// even though this register is disabled.
SEND_P3_DATA(AlphaBlendColorMode, P3RX_ALPHABLENDCOLORMODE_ENABLE ( __PERMEDIA_DISABLE )
| P3RX_ALPHABLENDCOLORMODE_COLORFORMAT ( pFormatDest->DitherFormat )
| P3RX_ALPHABLENDCOLORMODE_COLORORDER ( COLOR_MODE )
| P3RX_ALPHABLENDCOLORMODE_COLORCONVERSION ( P3RX_ALPHABLENDMODE_CONVERT_SHIFT )
);
SEND_P3_DATA(AlphaBlendAlphaMode, P3RX_ALPHABLENDALPHAMODE_ENABLE ( __PERMEDIA_DISABLE )
| P3RX_ALPHABLENDALPHAMODE_NOALPHABUFFER( __PERMEDIA_DISABLE )
| P3RX_ALPHABLENDALPHAMODE_ALPHATYPE ( P3RX_ALPHABLENDMODE_ALPHATYPE_OGL )
| P3RX_ALPHABLENDALPHAMODE_ALPHACONVERSION ( P3RX_ALPHABLENDMODE_CONVERT_SHIFT )
);
P3_DMA_COMMIT_BUFFER();
P3_DMA_GET_BUFFER_ENTRIES(30);
// If there is only one chromakey needed, use the proper chromakey
// This is mainly because the alphamap version doesn't work yet.
if ( bDstKey )
{
// Dest keying.
// The conventional chroma test is set up to key off the dest - the framebuffer.
SEND_P3_DATA(ChromaTestMode, P3RX_CHROMATESTMODE_ENABLE(__PERMEDIA_ENABLE) |
P3RX_CHROMATESTMODE_SOURCE(P3RX_CHROMATESTMODE_SOURCE_FBDATA) |
P3RX_CHROMATESTMODE_PASSACTION(P3RX_CHROMATESTMODE_ACTION_PASS) |
P3RX_CHROMATESTMODE_FAILACTION(P3RX_CHROMATESTMODE_ACTION_REJECT)
);
SEND_P3_DATA(ChromaLower, lpBlt->bltFX.ddckDestColorkey.dwColorSpaceLowValue);
SEND_P3_DATA(ChromaUpper, lpBlt->bltFX.ddckDestColorkey.dwColorSpaceHighValue);
// The source buffer is the source for the destination color key
SEND_P3_DATA(FBSourceReadBufferAddr, DDSurf_SurfaceOffsetFromMemoryBase(pThisDisplay, pDest));
SEND_P3_DATA(FBSourceReadBufferWidth, DDSurf_GetPixelPitch(pDest));
SEND_P3_DATA(FBSourceReadBufferOffset, 0);
// Enable source reads to get the colorkey color
SEND_P3_DATA(FBSourceReadMode, P3RX_FBSOURCEREAD_READENABLE(__PERMEDIA_ENABLE) |
P3RX_FBSOURCEREAD_LAYOUT(P3RX_LAYOUT_LINEAR));
}
else
{
// Don't need source reads - the source data comes from the texturemap
SEND_P3_DATA(FBSourceReadMode, P3RX_FBSOURCEREAD_READENABLE(__PERMEDIA_DISABLE));
if ( bSrcKey )
{
DWORD dwLowerSrcBound = 0;
DWORD dwUpperSrcBound = 0;
// Source keying, no dest keying.
// The conventional chroma test is set up to key off the source.
// Note we are keying off the input from the texture here, so we use the INPUTCOLOR as the chroma test
// source
SEND_P3_DATA(ChromaTestMode, P3RX_CHROMATESTMODE_ENABLE(__PERMEDIA_ENABLE) |
P3RX_CHROMATESTMODE_SOURCE(P3RX_CHROMATESTMODE_SOURCE_INPUTCOLOR) |
P3RX_CHROMATESTMODE_PASSACTION(P3RX_CHROMATESTMODE_ACTION_REJECT) |
P3RX_CHROMATESTMODE_FAILACTION(P3RX_CHROMATESTMODE_ACTION_PASS)
);
if ( b8to8blit )
{
// No conversion, just use the index value in the R channel.
dwLowerSrcBound = lpBlt->bltFX.ddckSrcColorkey.dwColorSpaceLowValue & 0x000000ff;
dwUpperSrcBound = lpBlt->bltFX.ddckSrcColorkey.dwColorSpaceHighValue | 0xffffff00;
}
else
{
// Don't scale, do a shift instead.
Get8888ScaledChroma(pThisDisplay,
pSource->dwFlags,
&pSource->lpGbl->ddpfSurface,
lpBlt->bltFX.ddckSrcColorkey.dwColorSpaceLowValue,
lpBlt->bltFX.ddckSrcColorkey.dwColorSpaceHighValue,
&dwLowerSrcBound,
&dwUpperSrcBound,
NULL, // NULL palette
FALSE,
TRUE);
}
DISPDBG((DBGLVL,"P3 Src Chroma: Upper = 0x%08x, Lower = 0x%08x",
lpBlt->bltFX.ddckSrcColorkey.dwColorSpaceLowValue,
lpBlt->bltFX.ddckSrcColorkey.dwColorSpaceHighValue));
DISPDBG((DBGLVL,"P3 Src Chroma(after): "
"Upper = 0x%08x, Lower = 0x%08x",
dwUpperSrcBound,
dwLowerSrcBound));
SEND_P3_DATA(ChromaLower, dwLowerSrcBound);
SEND_P3_DATA(ChromaUpper, dwUpperSrcBound);
}
else if ( !bSrcKey && !bDstKey )
{
// No chroma keying at all.
SEND_P3_DATA(ChromaTestMode, P3RX_CHROMATESTMODE_ENABLE(__PERMEDIA_DISABLE ) );
}
}
if ( bDstKey && bSrcKey )
{
DWORD dwLowerSrcBound;
DWORD dwUpperSrcBound;
if ( b8to8blit )
{
DISPDBG((ERRLVL,"Er... don't know what to do in this situation."));
}
// Enable source reads to get the colorkey color during dest colorkeys
SEND_P3_DATA(FBSourceReadMode, P3RX_FBSOURCEREAD_READENABLE(__PERMEDIA_ENABLE) |
P3RX_FBSOURCEREAD_LAYOUT(P3RX_LAYOUT_LINEAR));
// Don't scale, do a shift instead.
Get8888ZeroExtendedChroma(pThisDisplay,
pSource->dwFlags,
&pSource->lpGbl->ddpfSurface,
lpBlt->bltFX.ddckSrcColorkey.dwColorSpaceLowValue,
lpBlt->bltFX.ddckSrcColorkey.dwColorSpaceHighValue,
&dwLowerSrcBound,
&dwUpperSrcBound);
// If both colourkeys are needed, the source keying is done by counting
// chroma test fails in the texture filter unit.
SEND_P3_DATA(TextureChromaLower0, dwLowerSrcBound);
SEND_P3_DATA(TextureChromaUpper0, dwUpperSrcBound);
SEND_P3_DATA(TextureChromaLower1, dwLowerSrcBound);
SEND_P3_DATA(TextureChromaUpper1, dwUpperSrcBound);
SEND_P3_DATA(TextureFilterMode, P3RX_TEXFILTERMODE_ENABLE ( __PERMEDIA_ENABLE )
| P3RX_TEXFILTERMODE_FORMATBOTH ( sfdfTextureFilterModeFormat )
| P3RX_TEXFILTERMODE_COLORORDERBOTH ( COLOR_MODE )
| P3RX_TEXFILTERMODE_ALPHAMAPENABLEBOTH ( __PERMEDIA_ENABLE )
| P3RX_TEXFILTERMODE_ALPHAMAPSENSEBOTH ( P3RX_ALPHAMAPSENSE_INRANGE )
| P3RX_TEXFILTERMODE_COMBINECACHES ( __PERMEDIA_ENABLE )
| P3RX_TEXFILTERMODE_SHIFTBOTH ( __PERMEDIA_ENABLE )
| P3RX_TEXFILTERMODE_ALPHAMAPFILTERING ( __PERMEDIA_ENABLE )
| P3RX_TEXFILTERMODE_ALPHAMAPFILTERLIMIT0 ( bFiltering ? 3 : 0 )
| P3RX_TEXFILTERMODE_ALPHAMAPFILTERLIMIT1 ( 4 )
| P3RX_TEXFILTERMODE_ALPHAMAPFILTERLIMIT01 ( 8 )
);
}
else
{
SEND_P3_DATA(TextureFilterMode, P3RX_TEXFILTERMODE_ENABLE ( __PERMEDIA_ENABLE )
| P3RX_TEXFILTERMODE_FORMATBOTH ( sfdfTextureFilterModeFormat )
| P3RX_TEXFILTERMODE_COLORORDERBOTH ( iTextureFilterModeColorOrder )
| P3RX_TEXFILTERMODE_ALPHAMAPENABLEBOTH ( __PERMEDIA_DISABLE )
| P3RX_TEXFILTERMODE_COMBINECACHES ( __PERMEDIA_ENABLE )
| P3RX_TEXFILTERMODE_ALPHAMAPFILTERING ( __PERMEDIA_DISABLE )
| P3RX_TEXFILTERMODE_FORCEALPHATOONEBOTH ( __PERMEDIA_DISABLE )
| P3RX_TEXFILTERMODE_SHIFTBOTH ( __PERMEDIA_ENABLE )
);
// And now the alpha test (alpha test unit)
SEND_P3_DATA ( AlphaTestMode, P3RX_ALPHATESTMODE_ENABLE ( __PERMEDIA_DISABLE ) );
}
SEND_P3_DATA ( AntialiasMode, P3RX_ANTIALIASMODE_ENABLE ( __PERMEDIA_DISABLE ) );
// Texture coordinate unit.
SEND_P3_DATA(TextureCoordMode, P3RX_TEXCOORDMODE_ENABLE ( __PERMEDIA_ENABLE )
| P3RX_TEXCOORDMODE_WRAPS ( P3RX_TEXCOORDMODE_WRAP_REPEAT )
| P3RX_TEXCOORDMODE_WRAPT ( P3RX_TEXCOORDMODE_WRAP_REPEAT )
| P3RX_TEXCOORDMODE_OPERATION ( P3RX_TEXCOORDMODE_OPERATION_2D )
| P3RX_TEXCOORDMODE_INHIBITDDAINIT ( __PERMEDIA_DISABLE )
| P3RX_TEXCOORDMODE_ENABLELOD ( __PERMEDIA_DISABLE )
| P3RX_TEXCOORDMODE_ENABLEDY ( __PERMEDIA_DISABLE )
| P3RX_TEXCOORDMODE_WIDTH ( log2 ( (int)pDest->lpGbl->wWidth ) )
| P3RX_TEXCOORDMODE_HEIGHT ( log2 ( (int)pDest->lpGbl->wHeight ) )
| P3RX_TEXCOORDMODE_TEXTUREMAPTYPE ( P3RX_TEXCOORDMODE_TEXTUREMAPTYPE_2D )
| P3RX_TEXCOORDMODE_WRAPS1 ( P3RX_TEXCOORDMODE_WRAP_CLAMP )
| P3RX_TEXCOORDMODE_WRAPT1 ( P3RX_TEXCOORDMODE_WRAP_CLAMP )
);
P3_DMA_COMMIT_BUFFER();
P3_DMA_GET_BUFFER_ENTRIES(30);
SEND_P3_DATA(SStart, texSStart);
SEND_P3_DATA(TStart, texTStart);
SEND_P3_DATA(dSdx, iXScale);
SEND_P3_DATA(dSdyDom, 0);
SEND_P3_DATA(dTdx, 0);
SEND_P3_DATA(dTdyDom, iYScale);
SEND_P3_DATA(TextureBaseAddr0, dwNewSource);
if ( bYUVMode )
{
// Set up the YUV unit.
SEND_P3_DATA ( YUVMode, P3RX_YUVMODE_ENABLE ( __PERMEDIA_ENABLE ) );
iTextureType = P3RX_TEXREADMODE_TEXTURETYPE_VYUY422;
iPixelSize = P3RX_TEXREADMODE_TEXELSIZE_16;
// The idea here is to do ((colorcomp - 16) * 1.14), but in YUV space because the
// YUV unit comes after the texture composite unit. The reason for this change is
// to make our YUV conversion more like the ATI conversion. It isn't more correct this way,
// just different, but the WHQL tests were probably written on the ATI card and our colors
// aren't close enough to match what they do so we fail the test
SEND_P3_DATA(TextureCompositeMode, P3RX_TEXCOMPMODE_ENABLE ( __PERMEDIA_ENABLE ));
SEND_P3_DATA(TextureCompositeColorMode0, P3RX_TEXCOMPCAMODE01_ENABLE(__PERMEDIA_ENABLE)
| P3RX_TEXCOMPCAMODE01_ARG1(P3RX_TEXCOMP_T0C)
| P3RX_TEXCOMPCAMODE01_INVARG1(__PERMEDIA_DISABLE)
| P3RX_TEXCOMPCAMODE01_ARG2(P3RX_TEXCOMP_FC)
| P3RX_TEXCOMPCAMODE01_INVARG2(__PERMEDIA_DISABLE)
| P3RX_TEXCOMPCAMODE01_A(P3RX_TEXCOMP_ARG1)
| P3RX_TEXCOMPCAMODE01_B(P3RX_TEXCOMP_ARG2)
| P3RX_TEXCOMPCAMODE01_OPERATION(P3RX_TEXCOMP_OPERATION_SUBTRACT_AB)
| P3RX_TEXCOMPCAMODE01_SCALE(P3RX_TEXCOMP_OPERATION_SCALE_ONE));
SEND_P3_DATA(TextureCompositeAlphaMode0, P3RX_TEXCOMPCAMODE01_ENABLE(__PERMEDIA_ENABLE)
| P3RX_TEXCOMPCAMODE01_ARG1(P3RX_TEXCOMP_T0A)
| P3RX_TEXCOMPCAMODE01_INVARG1(__PERMEDIA_DISABLE)
| P3RX_TEXCOMPCAMODE01_ARG2(P3RX_TEXCOMP_FA)
| P3RX_TEXCOMPCAMODE01_INVARG2(__PERMEDIA_DISABLE)
| P3RX_TEXCOMPCAMODE01_A(P3RX_TEXCOMP_ARG1)
| P3RX_TEXCOMPCAMODE01_B(P3RX_TEXCOMP_ARG2)
| P3RX_TEXCOMPCAMODE01_OPERATION(P3RX_TEXCOMP_OPERATION_SUBTRACT_AB)
| P3RX_TEXCOMPCAMODE01_SCALE(P3RX_TEXCOMP_OPERATION_SCALE_ONE));
// This subtracts 16 from Y
SEND_P3_DATA(TextureCompositeFactor0, ((0 << 24) | (0x0 << 16) | (0x0 << 8) | 0x10));
// This multiplies the channels by 0.57.
SEND_P3_DATA(TextureCompositeFactor1, ((0x80 << 24) | (0x80 << 16) | (0x80 << 8) | 0x91));
SEND_P3_DATA(TextureCompositeColorMode1, P3RX_TEXCOMPCAMODE01_ENABLE(__PERMEDIA_ENABLE)
| P3RX_TEXCOMPCAMODE01_ARG1(P3RX_TEXCOMP_OC)
| P3RX_TEXCOMPCAMODE01_INVARG1(__PERMEDIA_DISABLE)
| P3RX_TEXCOMPCAMODE01_ARG2(P3RX_TEXCOMP_FC)
| P3RX_TEXCOMPCAMODE01_INVARG2(__PERMEDIA_DISABLE)
| P3RX_TEXCOMPCAMODE01_A(P3RX_TEXCOMP_ARG1)
| P3RX_TEXCOMPCAMODE01_B(P3RX_TEXCOMP_ARG2)
| P3RX_TEXCOMPCAMODE01_OPERATION(P3RX_TEXCOMP_OPERATION_MODULATE_AB)
| P3RX_TEXCOMPCAMODE01_SCALE(P3RX_TEXCOMP_OPERATION_SCALE_TWO));
SEND_P3_DATA(TextureCompositeAlphaMode1, P3RX_TEXCOMPCAMODE01_ENABLE(__PERMEDIA_ENABLE)
| P3RX_TEXCOMPCAMODE01_ARG1(P3RX_TEXCOMP_OC)
| P3RX_TEXCOMPCAMODE01_INVARG1(__PERMEDIA_DISABLE)
| P3RX_TEXCOMPCAMODE01_ARG2(P3RX_TEXCOMP_FA)
| P3RX_TEXCOMPCAMODE01_INVARG2(__PERMEDIA_DISABLE)
| P3RX_TEXCOMPCAMODE01_A(P3RX_TEXCOMP_ARG1)
| P3RX_TEXCOMPCAMODE01_B(P3RX_TEXCOMP_ARG2)
| P3RX_TEXCOMPCAMODE01_OPERATION(P3RX_TEXCOMP_OPERATION_MODULATE_AB)
| P3RX_TEXCOMPCAMODE01_SCALE(P3RX_TEXCOMP_OPERATION_SCALE_TWO));
}
else
{
iTextureType = P3RX_TEXREADMODE_TEXTURETYPE_NORMAL;
iPixelSize = DDSurf_GetChipPixelSize(pSource);
// Disable the composite units.
SEND_P3_DATA(TextureCompositeMode, P3RX_TEXCOMPMODE_ENABLE ( __PERMEDIA_DISABLE ) );
}
P3_DMA_COMMIT_BUFFER();
P3_DMA_GET_BUFFER_ENTRIES(24);
// Pass through the texel.
SEND_P3_DATA(TextureApplicationMode, P3RX_TEXAPPMODE_ENABLE ( __PERMEDIA_ENABLE )
| P3RX_TEXAPPMODE_BOTHA ( P3RX_TEXAPP_A_CC )
| P3RX_TEXAPPMODE_BOTHB ( P3RX_TEXAPP_B_TC )
| P3RX_TEXAPPMODE_BOTHI ( P3RX_TEXAPP_I_CA )
| P3RX_TEXAPPMODE_BOTHINVI ( __PERMEDIA_DISABLE )
| P3RX_TEXAPPMODE_BOTHOP ( P3RX_TEXAPP_OPERATION_PASS_B )
| P3RX_TEXAPPMODE_KDENABLE ( __PERMEDIA_DISABLE )
| P3RX_TEXAPPMODE_KSENABLE ( __PERMEDIA_DISABLE )
| P3RX_TEXAPPMODE_MOTIONCOMPENABLE ( __PERMEDIA_DISABLE )
);
TR0 = P3RX_TEXREADMODE_ENABLE ( __PERMEDIA_ENABLE )
| P3RX_TEXREADMODE_WIDTH ( 0 )
| P3RX_TEXREADMODE_HEIGHT ( 0 )
| P3RX_TEXREADMODE_TEXELSIZE ( iPixelSize )
| P3RX_TEXREADMODE_TEXTURE3D ( __PERMEDIA_DISABLE )
| P3RX_TEXREADMODE_COMBINECACHES ( __PERMEDIA_ENABLE )
| P3RX_TEXREADMODE_MAPBASELEVEL ( 0 )
| P3RX_TEXREADMODE_MAPMAXLEVEL ( 0 )
| P3RX_TEXREADMODE_LOGICALTEXTURE ( __PERMEDIA_DISABLE )
| P3RX_TEXREADMODE_ORIGIN ( P3RX_TEXREADMODE_ORIGIN_TOPLEFT )
| P3RX_TEXREADMODE_TEXTURETYPE ( iTextureType )
| P3RX_TEXREADMODE_BYTESWAP ( P3RX_TEXREADMODE_BYTESWAP_NONE )
| P3RX_TEXREADMODE_MIRROR ( __PERMEDIA_DISABLE )
| P3RX_TEXREADMODE_INVERT ( __PERMEDIA_DISABLE )
| P3RX_TEXREADMODE_OPAQUESPAN ( __PERMEDIA_DISABLE )
;
SEND_P3_DATA(TextureReadMode0, TR0);
SEND_P3_DATA(TextureReadMode1, TR0);
SEND_P3_DATA(TextureMapWidth0, P3RX_TEXMAPWIDTH_WIDTH(DDSurf_GetPixelPitch(pSource)) |
P3RX_TEXMAPWIDTH_LAYOUT(P3RX_LAYOUT_LINEAR) |
P3RX_TEXMAPWIDTH_HOSTTEXTURE(DDSurf_IsAGP(pSource)));
SEND_P3_DATA(TextureCacheReplacementMode,
P3RX_TEXCACHEREPLACEMODE_KEEPOLDEST0 ( __PERMEDIA_DISABLE )
| P3RX_TEXCACHEREPLACEMODE_KEEPOLDEST1 ( __PERMEDIA_DISABLE )
| P3RX_TEXCACHEREPLACEMODE_SHOWCACHEINFO ( __PERMEDIA_DISABLE )
);
SEND_P3_DATA(TextureMapSize, 0 );
if ( bDisableLUT )
{
SEND_P3_DATA(LUTMode, P3RX_LUTMODE_ENABLE ( __PERMEDIA_DISABLE ) );
}
if ( bFiltering )
{
// Texture index unit
SEND_P3_DATA(TextureIndexMode0,
P3RX_TEXINDEXMODE_ENABLE ( __PERMEDIA_ENABLE )
| P3RX_TEXINDEXMODE_WIDTH ( MAGIC_NUMBER_2D )
| P3RX_TEXINDEXMODE_HEIGHT ( MAGIC_NUMBER_2D )
| P3RX_TEXINDEXMODE_BORDER ( __PERMEDIA_DISABLE )
| P3RX_TEXINDEXMODE_WRAPU ( P3RX_TEXINDEXMODE_WRAP_REPEAT )
| P3RX_TEXINDEXMODE_WRAPV ( P3RX_TEXINDEXMODE_WRAP_REPEAT )
| P3RX_TEXINDEXMODE_MAPTYPE ( P3RX_TEXINDEXMODE_MAPTYPE_2D )
| P3RX_TEXINDEXMODE_MAGFILTER ( P3RX_TEXINDEXMODE_FILTER_LINEAR )
| P3RX_TEXINDEXMODE_MINFILTER ( P3RX_TEXINDEXMODE_FILTER_LINEAR )
| P3RX_TEXINDEXMODE_TEX3DENABLE ( __PERMEDIA_DISABLE )
| P3RX_TEXINDEXMODE_MIPMAPENABLE ( __PERMEDIA_DISABLE )
| P3RX_TEXINDEXMODE_NEARESTBIAS ( P3RX_TEXINDEXMODE_BIAS_ZERO )
| P3RX_TEXINDEXMODE_LINEARBIAS ( P3RX_TEXINDEXMODE_BIAS_ZERO )
| P3RX_TEXINDEXMODE_SOURCETEXELENABLE ( __PERMEDIA_DISABLE )
);
}
else
{
// Texture index unit
SEND_P3_DATA(TextureIndexMode0,
P3RX_TEXINDEXMODE_ENABLE ( __PERMEDIA_ENABLE )
| P3RX_TEXINDEXMODE_WIDTH ( MAGIC_NUMBER_2D )
| P3RX_TEXINDEXMODE_HEIGHT ( MAGIC_NUMBER_2D )
| P3RX_TEXINDEXMODE_BORDER ( __PERMEDIA_DISABLE )
| P3RX_TEXINDEXMODE_WRAPU ( P3RX_TEXINDEXMODE_WRAP_REPEAT )
| P3RX_TEXINDEXMODE_WRAPV ( P3RX_TEXINDEXMODE_WRAP_REPEAT )
| P3RX_TEXINDEXMODE_MAPTYPE ( P3RX_TEXINDEXMODE_MAPTYPE_2D )
| P3RX_TEXINDEXMODE_MAGFILTER ( P3RX_TEXINDEXMODE_FILTER_NEAREST )
| P3RX_TEXINDEXMODE_MINFILTER ( P3RX_TEXINDEXMODE_FILTER_NEAREST )
| P3RX_TEXINDEXMODE_TEX3DENABLE ( __PERMEDIA_DISABLE )
| P3RX_TEXINDEXMODE_MIPMAPENABLE ( __PERMEDIA_DISABLE )
| P3RX_TEXINDEXMODE_NEARESTBIAS ( P3RX_TEXINDEXMODE_BIAS_ZERO )
| P3RX_TEXINDEXMODE_LINEARBIAS ( P3RX_TEXINDEXMODE_BIAS_ZERO )
| P3RX_TEXINDEXMODE_SOURCETEXELENABLE ( __PERMEDIA_DISABLE )
);
}
ASSERTDD ( pFormatDest->DitherFormat >= 0, "** _DD_P3BltStretchSrcChDstCh: Destination format illegal" );
if ( bFiltering )
{
// Filtering, so dither.
SEND_P3_DATA(DitherMode,
P3RX_DITHERMODE_ENABLE ( __PERMEDIA_ENABLE )
| P3RX_DITHERMODE_DITHERENABLE ( __PERMEDIA_ENABLE )
| P3RX_DITHERMODE_COLORFORMAT ( pFormatDest->DitherFormat )
| P3RX_DITHERMODE_XOFFSET ( 0 )
| P3RX_DITHERMODE_YOFFSET ( 0 )
| P3RX_DITHERMODE_COLORORDER ( COLOR_MODE )
| P3RX_DITHERMODE_ALPHADITHER ( P3RX_DITHERMODE_ALPHADITHER_DITHER )
| P3RX_DITHERMODE_ROUNDINGMODE ( P3RX_DITHERMODE_ROUNDINGMODE_TRUNCATE )
);
}
else
{
// No filter, no dither (though it doesn't actually matter).
SEND_P3_DATA(DitherMode,
P3RX_DITHERMODE_ENABLE ( __PERMEDIA_ENABLE )
| P3RX_DITHERMODE_DITHERENABLE ( __PERMEDIA_DISABLE )
| P3RX_DITHERMODE_COLORFORMAT ( pFormatDest->DitherFormat )
| P3RX_DITHERMODE_XOFFSET ( 0 )
| P3RX_DITHERMODE_YOFFSET ( 0 )
| P3RX_DITHERMODE_COLORORDER ( COLOR_MODE )
| P3RX_DITHERMODE_ALPHADITHER ( P3RX_DITHERMODE_ALPHADITHER_DITHER )
| P3RX_DITHERMODE_ROUNDINGMODE ( P3RX_DITHERMODE_ROUNDINGMODE_TRUNCATE )
);
}
SEND_P3_DATA(LogicalOpMode,
P3RX_LOGICALOPMODE_ENABLE ( __PERMEDIA_DISABLE ) );
SEND_P3_DATA(PixelSize, (2 - DDSurf_GetChipPixelSize(pDest)));
SEND_P3_DATA(FBWriteMode,
P3RX_FBWRITEMODE_WRITEENABLE(__PERMEDIA_ENABLE) |
P3RX_FBWRITEMODE_LAYOUT0(P3RX_LAYOUT_LINEAR));
WAIT_FIFO(32);
P3_ENSURE_DX_SPACE(32);
SEND_P3_DATA(Count, rMyDest.bottom - rMyDest.top );
SEND_P3_DATA(Render,
P3RX_RENDER_PRIMITIVETYPE ( P3RX_RENDER_PRIMITIVETYPE_TRAPEZOID )
| P3RX_RENDER_TEXTUREENABLE ( __PERMEDIA_ENABLE )
| P3RX_RENDER_FOGENABLE ( __PERMEDIA_DISABLE )
| P3RX_RENDER_FBSOURCEREADENABLE( (bDstKey ? __PERMEDIA_ENABLE : __PERMEDIA_DISABLE))
);
// Disable all the things I switched on.
SEND_P3_DATA(ChromaTestMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(AlphaBlendColorMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(AlphaBlendAlphaMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(TextureFilterMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(AlphaTestMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(AntialiasMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(TextureCoordMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(TextureReadMode0, __PERMEDIA_DISABLE );
SEND_P3_DATA(TextureIndexMode0, __PERMEDIA_DISABLE );
WAIT_FIFO(20);
P3_ENSURE_DX_SPACE(20);
SEND_P3_DATA(TextureCompositeMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(TextureCompositeColorMode0, __PERMEDIA_DISABLE);
SEND_P3_DATA(TextureCompositeAlphaMode0, __PERMEDIA_DISABLE);
SEND_P3_DATA(TextureCompositeColorMode1, __PERMEDIA_DISABLE);
SEND_P3_DATA(TextureCompositeAlphaMode1, __PERMEDIA_DISABLE);
SEND_P3_DATA(TextureApplicationMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(DitherMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(FBSourceReadMode, __PERMEDIA_DISABLE);
SEND_P3_DATA(LogicalOpMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(YUVMode, __PERMEDIA_DISABLE );
P3_DMA_COMMIT_BUFFER();
} // __P3BltStretchSrcChDstChSourceOveride
//-----------------------------------------------------------------------------
//
// _DD_P3BltStretchSrcChDstChOverlap
//
//-----------------------------------------------------------------------------
void
_DD_P3BltStretchSrcChDstChOverlap(
P3_THUNKEDDATA* pThisDisplay,
LPDDRAWI_DDRAWSURFACE_LCL pSource,
LPDDRAWI_DDRAWSURFACE_LCL pDest,
P3_SURF_FORMAT* pFormatSource,
P3_SURF_FORMAT* pFormatDest,
LPDDHAL_BLTDATA lpBlt,
RECTL *rSrc,
RECTL *rDest)
{
P3_MEMREQUEST mmrq;
DWORD dwResult;
ZeroMemory(&mmrq, sizeof(P3_MEMREQUEST));
mmrq.dwSize = sizeof(P3_MEMREQUEST);
mmrq.dwBytes = DDSurf_Pitch(pSource) * DDSurf_Height(pSource);
mmrq.dwAlign = 16;
mmrq.dwFlags = MEM3DL_FIRST_FIT | MEM3DL_FRONT;
dwResult = _DX_LIN_AllocateLinearMemory(&pThisDisplay->LocalVideoHeap0Info,
&mmrq);
if (dwResult != GLDD_SUCCESS)
{
// Couldn't get the memory, so try anyway. It probably won't look
// right but it is our best shot...
DISPDBG((WRNLVL,"Overlapped stretch blit unlikely to look correct!"));
_DD_P3BltStretchSrcChDstCh_DD(pThisDisplay,
pSource,
pDest,
pFormatSource,
pFormatDest,
lpBlt,
rSrc,
rDest);
return;
}
// Copy the source buffer to a temporary place.
__P3BltDestOveride(pThisDisplay,
pSource,
pSource,
pFormatSource,
pFormatSource,
rSrc,
rSrc,
__GLINT_LOGICOP_COPY,
(long)mmrq.pMem - (long)pThisDisplay->dwScreenFlatAddr);
// Do the blit, stretching to our temporary buffer
__P3BltStretchSrcChDstChSourceOveride(pThisDisplay,
pSource,
pDest,
pFormatSource,
pFormatDest,
lpBlt,
rSrc,
rDest,
(long)mmrq.pMem -
(long)pThisDisplay->dwScreenFlatAddr);
// Free the allocated source buffer.
_DX_LIN_FreeLinearMemory(&pThisDisplay->LocalVideoHeap0Info,
mmrq.pMem);
} // _DD_P3BltStretchSrcChDstChOverlap
#if DX8_MULTISAMPLING || DX7_ANTIALIAS
//-----------------------------------------------------------------------------
//
// Function: P3RX_AA_Shrink
//
// Does a 2x2 to 1x1 blit through the texture unit to shrink an AA buffer
//
//-----------------------------------------------------------------------------
VOID P3RX_AA_Shrink(P3_D3DCONTEXT* pContext)
{
ULONG renderData;
RECTL rMySrc, rMyDest;
int iSrcWidth, iSrcHeight;
int iDstWidth, iDstHeight;
DWORD TR0;
int iSourcePixelSize;
P3_THUNKEDDATA* pThisDisplay = pContext->pThisDisplay;
P3_SURF_INTERNAL* pSurf = pContext->pSurfRenderInt;
P3_SURF_FORMAT* pFormatSource;
P3_SURF_FORMAT* pFormatDest = pSurf->pFormatSurface;
P3_DMA_DEFS();
rMySrc.top = 0;
rMySrc.bottom = pSurf->wHeight * 2;
rMySrc.left = 0;
rMySrc.right = pSurf->wWidth * 2;
rMyDest.top = 0;
rMyDest.left = 0;
rMyDest.right = pSurf->wWidth;
rMyDest.bottom = pSurf->wHeight;
iSrcWidth = rMySrc.right - rMySrc.left;
iSrcHeight = rMySrc.bottom - rMySrc.top;
iDstWidth = rMyDest.right - rMyDest.left;
iDstHeight = rMyDest.bottom - rMyDest.top;
// MAGIC_NUMBER_2D can be anything, but it needs to be at least as
// big as the widest texture, but not too big or you'll lose fractional
// precision. Valid range for a P3 is 0->11
ASSERTDD ( iSrcWidth <= ( 1 << MAGIC_NUMBER_2D ),
"P3RX_AA_Shrink: MAGIC_NUMBER_2D is too small" );
ASSERTDD ( iSrcHeight <= ( 1 << MAGIC_NUMBER_2D ),
"P3RX_AA_Shrink: MAGIC_NUMBER_2D is too small" );
DISPDBG((DBGLVL, "Glint Blt from (%d, %d) to (%d,%d) (%d, %d)",
rMySrc.left, rMySrc.top,
rMyDest.left, rMyDest.top,
rMyDest.right, rMyDest.bottom));
iSourcePixelSize = pSurf->dwPixelSize;
pFormatSource = pFormatDest;
P3_DMA_GET_BUFFER();
P3_ENSURE_DX_SPACE(32);
WAIT_FIFO(32);
// Vape the cache.
P3RX_INVALIDATECACHE(__PERMEDIA_ENABLE, __PERMEDIA_ENABLE);
// Source read is same as write.
SEND_P3_DATA(FBSourceReadBufferAddr, pSurf->lOffsetFromMemoryBase );
SEND_P3_DATA(FBSourceReadBufferWidth, pSurf->dwPixelPitch);
SEND_P3_DATA(FBWriteMode,
P3RX_FBWRITEMODE_WRITEENABLE(__PERMEDIA_ENABLE) |
P3RX_FBWRITEMODE_LAYOUT0(pSurf->dwPatchMode));
// No offset - we read the dest pixels so that we can chroma-key off them.
SEND_P3_DATA(FBSourceReadBufferOffset, 0);
SEND_P3_DATA(FBWriteBufferOffset0, 0);
SEND_P3_DATA(PixelSize, pSurf->dwPixelSize);
SEND_P3_DATA(RectanglePosition,
P3RX_RECTANGLEPOSITION_X( rMyDest.left ) |
P3RX_RECTANGLEPOSITION_Y( rMyDest.top ));
renderData = P3RX_RENDER2D_WIDTH(( rMyDest.right - rMyDest.left ) & 0xfff )
| P3RX_RENDER2D_OPERATION( P3RX_RENDER2D_OPERATION_NORMAL )
| P3RX_RENDER2D_FBREADSOURCEENABLE( __PERMEDIA_DISABLE )
| P3RX_RENDER2D_HEIGHT ( 0 )
| P3RX_RENDER2D_INCREASINGX( __PERMEDIA_ENABLE )
| P3RX_RENDER2D_INCREASINGY( __PERMEDIA_ENABLE )
| P3RX_RENDER2D_AREASTIPPLEENABLE( __PERMEDIA_DISABLE )
| P3RX_RENDER2D_TEXTUREENABLE( __PERMEDIA_ENABLE );
SEND_P3_DATA(Render2D, renderData);
// This is the alpha blending unit.
// AlphaBlendxxxMode are set up by the context code.
// The colour format, order and conversion fields are used by the
// chroma keying, even though this register is disabled.
SEND_P3_DATA(AlphaBlendColorMode,
P3RX_ALPHABLENDCOLORMODE_ENABLE ( __PERMEDIA_DISABLE )
| P3RX_ALPHABLENDCOLORMODE_COLORFORMAT ( pFormatDest->DitherFormat )
| P3RX_ALPHABLENDCOLORMODE_COLORORDER ( COLOR_MODE )
| P3RX_ALPHABLENDCOLORMODE_COLORCONVERSION ( P3RX_ALPHABLENDMODE_CONVERT_SHIFT )
);
SEND_P3_DATA(AlphaBlendAlphaMode,
P3RX_ALPHABLENDALPHAMODE_ENABLE ( __PERMEDIA_DISABLE )
| P3RX_ALPHABLENDALPHAMODE_NOALPHABUFFER( __PERMEDIA_DISABLE )
| P3RX_ALPHABLENDALPHAMODE_ALPHATYPE ( P3RX_ALPHABLENDMODE_ALPHATYPE_OGL )
| P3RX_ALPHABLENDALPHAMODE_ALPHACONVERSION ( P3RX_ALPHABLENDMODE_CONVERT_SHIFT )
);
P3_ENSURE_DX_SPACE(32);
WAIT_FIFO(32);
// No chroma keying at all.
SEND_P3_DATA(ChromaTestMode, P3RX_CHROMATESTMODE_ENABLE(__PERMEDIA_DISABLE ) );
SEND_P3_DATA(TextureFilterMode, P3RX_TEXFILTERMODE_ENABLE ( __PERMEDIA_ENABLE )
| P3RX_TEXFILTERMODE_FORMATBOTH ( pFormatSource->FilterFormat )
| P3RX_TEXFILTERMODE_COLORORDERBOTH ( COLOR_MODE )
| P3RX_TEXFILTERMODE_ALPHAMAPENABLEBOTH ( __PERMEDIA_DISABLE )
| P3RX_TEXFILTERMODE_COMBINECACHES ( __PERMEDIA_ENABLE )
| P3RX_TEXFILTERMODE_ALPHAMAPFILTERING ( __PERMEDIA_DISABLE )
| P3RX_TEXFILTERMODE_FORCEALPHATOONEBOTH ( __PERMEDIA_DISABLE )
| P3RX_TEXFILTERMODE_SHIFTBOTH ( __PERMEDIA_DISABLE )
);
// And now the alpha test (alpha test unit)
SEND_P3_DATA ( AlphaTestMode, P3RX_ALPHATESTMODE_ENABLE ( __PERMEDIA_DISABLE ) );
SEND_P3_DATA ( AntialiasMode, P3RX_ANTIALIASMODE_ENABLE ( __PERMEDIA_DISABLE ) );
// Texture coordinate unit.
SEND_P3_DATA(TextureCoordMode,
P3RX_TEXCOORDMODE_ENABLE ( __PERMEDIA_ENABLE )
| P3RX_TEXCOORDMODE_WRAPS ( P3RX_TEXCOORDMODE_WRAP_REPEAT )
| P3RX_TEXCOORDMODE_WRAPT ( P3RX_TEXCOORDMODE_WRAP_REPEAT )
| P3RX_TEXCOORDMODE_OPERATION ( P3RX_TEXCOORDMODE_OPERATION_2D )
| P3RX_TEXCOORDMODE_INHIBITDDAINIT ( __PERMEDIA_DISABLE )
| P3RX_TEXCOORDMODE_ENABLELOD ( __PERMEDIA_DISABLE )
| P3RX_TEXCOORDMODE_ENABLEDY ( __PERMEDIA_DISABLE )
| P3RX_TEXCOORDMODE_WIDTH (0) // Only used for mipmapping
| P3RX_TEXCOORDMODE_HEIGHT (0)
| P3RX_TEXCOORDMODE_TEXTUREMAPTYPE ( P3RX_TEXCOORDMODE_TEXTUREMAPTYPE_2D )
| P3RX_TEXCOORDMODE_WRAPS1 ( P3RX_TEXCOORDMODE_WRAP_CLAMP )
| P3RX_TEXCOORDMODE_WRAPT1 ( P3RX_TEXCOORDMODE_WRAP_CLAMP )
);
SEND_P3_DATA(SStart, (1 << (31-MAGIC_NUMBER_2D)));
SEND_P3_DATA(TStart, (1 << (31-MAGIC_NUMBER_2D)));
SEND_P3_DATA(dSdx, (2 << (32-MAGIC_NUMBER_2D)));
SEND_P3_DATA(dSdyDom, 0);
SEND_P3_DATA(dTdx, 0);
SEND_P3_DATA(dTdyDom, (2 << (32-MAGIC_NUMBER_2D)));
SEND_P3_DATA(LBWriteMode, 0);
P3_ENSURE_DX_SPACE(32);
WAIT_FIFO(32);
SEND_P3_DATA(TextureBaseAddr0,
pContext->dwAliasBackBuffer -
pThisDisplay->dwScreenFlatAddr );
TR0 = P3RX_TEXREADMODE_ENABLE ( __PERMEDIA_ENABLE )
| P3RX_TEXREADMODE_WIDTH ( 0 )
| P3RX_TEXREADMODE_HEIGHT ( 0 )
| P3RX_TEXREADMODE_TEXELSIZE (iSourcePixelSize)
| P3RX_TEXREADMODE_TEXTURE3D ( __PERMEDIA_DISABLE )
| P3RX_TEXREADMODE_COMBINECACHES ( __PERMEDIA_ENABLE )
| P3RX_TEXREADMODE_MAPBASELEVEL ( 0 )
| P3RX_TEXREADMODE_MAPMAXLEVEL ( 0 )
| P3RX_TEXREADMODE_LOGICALTEXTURE ( __PERMEDIA_DISABLE )
| P3RX_TEXREADMODE_ORIGIN ( P3RX_TEXREADMODE_ORIGIN_TOPLEFT )
| P3RX_TEXREADMODE_TEXTURETYPE ( P3RX_TEXREADMODE_TEXTURETYPE_NORMAL)
| P3RX_TEXREADMODE_BYTESWAP ( P3RX_TEXREADMODE_BYTESWAP_NONE )
| P3RX_TEXREADMODE_MIRROR ( __PERMEDIA_DISABLE )
| P3RX_TEXREADMODE_INVERT ( __PERMEDIA_DISABLE )
| P3RX_TEXREADMODE_OPAQUESPAN ( __PERMEDIA_DISABLE )
;
SEND_P3_DATA(TextureReadMode0, TR0);
SEND_P3_DATA(TextureReadMode1, TR0);
SEND_P3_DATA(TextureMapWidth0,
P3RX_TEXMAPWIDTH_WIDTH(pSurf->dwPixelPitch * 2) |
P3RX_TEXMAPWIDTH_LAYOUT(pSurf->dwPatchMode));
SEND_P3_DATA(TextureCacheReplacementMode,
P3RX_TEXCACHEREPLACEMODE_KEEPOLDEST0 ( __PERMEDIA_DISABLE )
| P3RX_TEXCACHEREPLACEMODE_KEEPOLDEST1 ( __PERMEDIA_DISABLE )
| P3RX_TEXCACHEREPLACEMODE_SHOWCACHEINFO ( __PERMEDIA_DISABLE )
);
SEND_P3_DATA(TextureMapSize, 0 );
SEND_P3_DATA(LUTMode, P3RX_LUTMODE_ENABLE ( __PERMEDIA_DISABLE ) );
// Texture index unit
SEND_P3_DATA(TextureIndexMode0,
P3RX_TEXINDEXMODE_ENABLE ( __PERMEDIA_ENABLE )
| P3RX_TEXINDEXMODE_WIDTH ( MAGIC_NUMBER_2D )
| P3RX_TEXINDEXMODE_HEIGHT ( MAGIC_NUMBER_2D )
| P3RX_TEXINDEXMODE_BORDER ( __PERMEDIA_DISABLE )
| P3RX_TEXINDEXMODE_WRAPU ( P3RX_TEXINDEXMODE_WRAP_REPEAT )
| P3RX_TEXINDEXMODE_WRAPV ( P3RX_TEXINDEXMODE_WRAP_REPEAT )
| P3RX_TEXINDEXMODE_MAPTYPE ( P3RX_TEXINDEXMODE_MAPTYPE_2D )
| P3RX_TEXINDEXMODE_MAGFILTER ( P3RX_TEXINDEXMODE_FILTER_LINEAR )
| P3RX_TEXINDEXMODE_MINFILTER ( P3RX_TEXINDEXMODE_FILTER_LINEAR )
| P3RX_TEXINDEXMODE_TEX3DENABLE ( __PERMEDIA_DISABLE )
| P3RX_TEXINDEXMODE_MIPMAPENABLE ( __PERMEDIA_DISABLE )
| P3RX_TEXINDEXMODE_NEARESTBIAS ( P3RX_TEXINDEXMODE_BIAS_ZERO )
| P3RX_TEXINDEXMODE_LINEARBIAS ( P3RX_TEXINDEXMODE_BIAS_ZERO )
| P3RX_TEXINDEXMODE_SOURCETEXELENABLE ( __PERMEDIA_DISABLE )
);
// Disable the composite units.
SEND_P3_DATA(TextureCompositeMode,
P3RX_TEXCOMPMODE_ENABLE ( __PERMEDIA_DISABLE ) );
// Pass through the texel.
SEND_P3_DATA(TextureApplicationMode,
P3RX_TEXAPPMODE_ENABLE ( __PERMEDIA_ENABLE )
| P3RX_TEXAPPMODE_BOTHA ( P3RX_TEXAPP_A_CC )
| P3RX_TEXAPPMODE_BOTHB ( P3RX_TEXAPP_B_TC )
| P3RX_TEXAPPMODE_BOTHI ( P3RX_TEXAPP_I_CA )
| P3RX_TEXAPPMODE_BOTHINVI ( __PERMEDIA_DISABLE )
| P3RX_TEXAPPMODE_BOTHOP ( P3RX_TEXAPP_OPERATION_PASS_B )
| P3RX_TEXAPPMODE_KDENABLE ( __PERMEDIA_DISABLE )
| P3RX_TEXAPPMODE_KSENABLE ( __PERMEDIA_DISABLE )
| P3RX_TEXAPPMODE_MOTIONCOMPENABLE ( __PERMEDIA_DISABLE )
);
// Filtering, so dither.
SEND_P3_DATA(DitherMode,
P3RX_DITHERMODE_ENABLE ( __PERMEDIA_ENABLE )
| P3RX_DITHERMODE_DITHERENABLE ( __PERMEDIA_DISABLE )
| P3RX_DITHERMODE_COLORFORMAT ( pFormatDest->DitherFormat )
| P3RX_DITHERMODE_XOFFSET ( 0 )
| P3RX_DITHERMODE_YOFFSET ( 0 )
| P3RX_DITHERMODE_COLORORDER ( COLOR_MODE )
| P3RX_DITHERMODE_ALPHADITHER ( P3RX_DITHERMODE_ALPHADITHER_DITHER )
| P3RX_DITHERMODE_ROUNDINGMODE ( P3RX_DITHERMODE_ROUNDINGMODE_TRUNCATE )
);
P3_ENSURE_DX_SPACE(32);
WAIT_FIFO(32);
SEND_P3_DATA(LogicalOpMode,
P3RX_LOGICALOPMODE_ENABLE ( __PERMEDIA_DISABLE ) );
SEND_P3_DATA(FBWriteBufferAddr0, pSurf->lOffsetFromMemoryBase );
SEND_P3_DATA(FBWriteBufferWidth0, pSurf->dwPixelPitch);
SEND_P3_DATA(Count, rMyDest.bottom - rMyDest.top );
SEND_P3_DATA(Render,
P3RX_RENDER_PRIMITIVETYPE ( P3RX_RENDER_PRIMITIVETYPE_TRAPEZOID )
| P3RX_RENDER_TEXTUREENABLE ( __PERMEDIA_ENABLE )
| P3RX_RENDER_FOGENABLE ( __PERMEDIA_DISABLE )
| P3RX_RENDER_FBSOURCEREADENABLE( __PERMEDIA_DISABLE)
);
P3_ENSURE_DX_SPACE(32);
WAIT_FIFO(32);
// Disable all the units that were switched on.
SEND_P3_DATA(ChromaTestMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(AlphaBlendColorMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(AlphaBlendAlphaMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(TextureFilterMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(AlphaTestMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(AntialiasMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(TextureCoordMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(TextureReadMode0, __PERMEDIA_DISABLE );
SEND_P3_DATA(TextureIndexMode0, __PERMEDIA_DISABLE );
SEND_P3_DATA(TextureCompositeMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(TextureApplicationMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(DitherMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(LogicalOpMode, __PERMEDIA_DISABLE );
SEND_P3_DATA(YUVMode, __PERMEDIA_DISABLE );
P3_DMA_COMMIT_BUFFER();
} // P3RX_AA_Shrink
#endif // DX8_MULTISAMPLING || DX7_ANTIALIAS