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