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.
 
 
 
 
 
 

817 lines
28 KiB

/******************************Module*Header**********************************\
*
* *********************
* * DDraw SAMPLE CODE *
* *********************
*
* Module Name: ddstrblt.c
*
* Content:
*
* Copyright (c) 1994-1998 3Dlabs Inc. Ltd. All rights reserved.
* Copyright (c) 1995-1999 Microsoft Corporation. All rights reserved.
\*****************************************************************************/
#include "precomp.h"
#include "directx.h"
#include "dd.h"
//--------------------------------------------------------------------------
//
// ConvertColorKeys
//
// converts a color key to the Permedia internal format according to
// the given Permedia surface format
//
//--------------------------------------------------------------------------
VOID
ConvertColorKeys(PermediaSurfaceData *pSurface,
DWORD &dwLowerBound,
DWORD &dwUpperBound)
{
switch (pSurface->SurfaceFormat.Format)
{
case PERMEDIA_444_RGB:
dwLowerBound = CHROMA_LOWER_ALPHA(
FORMAT_4444_32BIT_BGR(dwLowerBound));
dwUpperBound = CHROMA_UPPER_ALPHA(
FORMAT_4444_32BIT_BGR(dwUpperBound));
break;
case PERMEDIA_332_RGB:
dwLowerBound = CHROMA_LOWER_ALPHA(
FORMAT_332_32BIT_BGR(dwLowerBound));
dwUpperBound = CHROMA_UPPER_ALPHA(
FORMAT_332_32BIT_BGR(dwUpperBound));
break;
case PERMEDIA_2321_RGB:
dwLowerBound = CHROMA_LOWER_ALPHA(
FORMAT_2321_32BIT_BGR(dwLowerBound));
dwUpperBound = CHROMA_UPPER_ALPHA(
FORMAT_2321_32BIT_BGR(dwUpperBound));
break;
case PERMEDIA_4BIT_PALETTEINDEX:
case PERMEDIA_8BIT_PALETTEINDEX:
dwLowerBound = CHROMA_LOWER_ALPHA(
FORMAT_PALETTE_32BIT(dwLowerBound));
dwUpperBound = CHROMA_UPPER_ALPHA(
FORMAT_PALETTE_32BIT(dwUpperBound));
break;
case PERMEDIA_5551_RGB:
dwLowerBound = CHROMA_LOWER_ALPHA(
FORMAT_5551_32BIT_BGR(dwLowerBound));
dwUpperBound = CHROMA_UPPER_ALPHA(
FORMAT_5551_32BIT_BGR(dwUpperBound));
dwLowerBound = dwLowerBound & 0xF8F8F8F8;
dwUpperBound = dwUpperBound | 0x07070707;
break;
case PERMEDIA_8888_RGB:
// The permedia 565 mode is an extension, so don't confuse it with
// the 8888 mode which has the same number
if (pSurface->SurfaceFormat.FormatExtension ==
PERMEDIA_565_RGB_EXTENSION)
{
dwLowerBound = CHROMA_LOWER_ALPHA(
FORMAT_565_32BIT_BGR(dwLowerBound));
dwUpperBound = CHROMA_UPPER_ALPHA(
FORMAT_565_32BIT_BGR(dwUpperBound));
dwLowerBound = dwLowerBound & 0xF8F8FcF8;
dwUpperBound = dwUpperBound | 0x07070307;
}
else
{
dwLowerBound = CHROMA_LOWER_ALPHA(
FORMAT_8888_32BIT_BGR(dwLowerBound));
dwUpperBound = CHROMA_UPPER_ALPHA(
FORMAT_8888_32BIT_BGR(dwUpperBound));
}
break;
case PERMEDIA_888_RGB:
dwLowerBound = CHROMA_LOWER_ALPHA(
FORMAT_8888_32BIT_BGR(dwLowerBound));
dwUpperBound = CHROMA_UPPER_ALPHA(
FORMAT_8888_32BIT_BGR(dwUpperBound));
break;
}
// swap blue and red if we have a RGB surface
if (!pSurface->SurfaceFormat.ColorOrder)
{
dwLowerBound = SWAP_BR(dwLowerBound);
dwUpperBound = SWAP_BR(dwUpperBound);
}
}
//--------------------------------------------------------------------------
//
// PermediaStretchCopyBlt
//
// stretched blt through texture unit. no keying.
// handle mirroring if the stretched image requires it.
//
//--------------------------------------------------------------------------
VOID
PermediaStretchCopyBlt( PPDev ppdev,
LPDDHAL_BLTDATA lpBlt,
PermediaSurfaceData* pDest,
PermediaSurfaceData* pSource,
RECTL *rDest,
RECTL *rSrc,
DWORD dwWindowBase,
DWORD dwSourceOffset
)
{
LONG lXScale;
LONG lYScale;
BOOL bYMirror=FALSE;
BOOL bXMirror=FALSE;
LONG lPixelSize=pDest->SurfaceFormat.PixelSize;
DWORD dwDestWidth = rDest->right - rDest->left;
DWORD dwDestHeight = rDest->bottom - rDest->top;
DWORD dwSourceWidth = rSrc->right - rSrc->left;
DWORD dwSourceHeight = rSrc->bottom - rSrc->top;
DWORD dwTexSStart, dwTexTStart;
DWORD dwRenderDirection;
PERMEDIA_DEFS(ppdev);
DBG_DD(( 5, "DDraw:PermediaStretchCopyBlt dwWindowBase=%08lx "
"dwSourceOffset=%08lx", dwWindowBase, dwSourceOffset));
ASSERTDD(pDest, "Not valid private surface in destination");
ASSERTDD(pSource, "Not valid private surface in source");
lXScale = (dwSourceWidth << 20) / dwDestWidth;
lYScale = (dwSourceHeight << 20) / dwDestHeight;
// Changes pixel depth to Dest buffer pixel depth if neccessary.
RESERVEDMAPTR(28);
SEND_PERMEDIA_DATA( FBPixelOffset, 0x0);
SEND_PERMEDIA_DATA( FBReadPixel, pDest->SurfaceFormat.FBReadPixel);
if (lPixelSize != 0)
{
// set writeback to dest surface...
SEND_PERMEDIA_DATA( DitherMode,
(pDest->SurfaceFormat.ColorOrder <<
PM_DITHERMODE_COLORORDER) |
(pDest->SurfaceFormat.Format <<
PM_DITHERMODE_COLORFORMAT) |
(pDest->SurfaceFormat.FormatExtension <<
PM_DITHERMODE_COLORFORMATEXTENSION) |
(__PERMEDIA_ENABLE << PM_DITHERMODE_ENABLE));
}
SEND_PERMEDIA_DATA(FBWindowBase, dwWindowBase);
// set no read of dest.
SEND_PERMEDIA_DATA(FBReadMode, pDest->ulPackedPP);
SEND_PERMEDIA_DATA(LogicalOpMode, __PERMEDIA_DISABLE);
// set base of source
SEND_PERMEDIA_DATA(TextureBaseAddress, dwSourceOffset);
SEND_PERMEDIA_DATA(TextureAddressMode,(1 << PM_TEXADDRESSMODE_ENABLE));
SEND_PERMEDIA_DATA(TextureColorMode, (1 << PM_TEXCOLORMODE_ENABLE) |
(_P2_TEXTURE_COPY <<
PM_TEXCOLORMODE_APPLICATION));
SEND_PERMEDIA_DATA(TextureReadMode,
PM_TEXREADMODE_ENABLE(__PERMEDIA_ENABLE)|
PM_TEXREADMODE_FILTER(__PERMEDIA_DISABLE)|
PM_TEXREADMODE_WIDTH(11) |
PM_TEXREADMODE_HEIGHT(11) );
// set source bitmap format
SEND_PERMEDIA_DATA(TextureDataFormat,
(pSource->SurfaceFormat.Format <<
PM_TEXDATAFORMAT_FORMAT) |
(pSource->SurfaceFormat.FormatExtension <<
PM_TEXDATAFORMAT_FORMATEXTENSION) |
(pSource->SurfaceFormat.ColorOrder <<
PM_TEXDATAFORMAT_COLORORDER));
SEND_PERMEDIA_DATA(TextureMapFormat, (pSource->ulPackedPP) |
(pSource->SurfaceFormat.PixelSize <<
PM_TEXMAPFORMAT_TEXELSIZE) );
// 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 (dwWindowBase != dwSourceOffset)
{
dwRenderDirection = 1;
}
else
{
if(rSrc->top < rDest->top)
{
dwRenderDirection = 0;
}
else if(rSrc->top > rDest->top)
{
dwRenderDirection = 1;
}
else if(rSrc->left < rDest->left)
{
dwRenderDirection = 0;
}
else dwRenderDirection = 1;
}
if(NULL != lpBlt && lpBlt->dwFlags & DDBLT_DDFX)
{
bYMirror = lpBlt->bltFX.dwDDFX & DDBLTFX_MIRRORUPDOWN;
bXMirror = lpBlt->bltFX.dwDDFX & DDBLTFX_MIRRORLEFTRIGHT;
} else
{
if (dwRenderDirection==0)
{
bXMirror = TRUE;
bYMirror = TRUE;
}
}
if (bXMirror)
{
dwTexSStart = rSrc->right - 1;
lXScale = -lXScale;
}
else
{
dwTexSStart = rSrc->left;
}
if (bYMirror)
{
dwTexTStart = rSrc->bottom - 1;
lYScale = -lYScale;
}
else
{
dwTexTStart = rSrc->top;
}
SEND_PERMEDIA_DATA(SStart, dwTexSStart << 20);
SEND_PERMEDIA_DATA(TStart, dwTexTStart << 20);
SEND_PERMEDIA_DATA(dSdx, lXScale);
SEND_PERMEDIA_DATA(dSdyDom, 0);
SEND_PERMEDIA_DATA(dTdx, 0);
SEND_PERMEDIA_DATA(dTdyDom, lYScale);
// Render the rectangle
if (dwRenderDirection)
{
SEND_PERMEDIA_DATA(StartXDom, INTtoFIXED(rDest->left));
SEND_PERMEDIA_DATA(StartXSub, INTtoFIXED(rDest->right));
SEND_PERMEDIA_DATA(StartY, INTtoFIXED(rDest->top));
SEND_PERMEDIA_DATA(dY, INTtoFIXED(1));
SEND_PERMEDIA_DATA(Count, rDest->bottom - rDest->top);
SEND_PERMEDIA_DATA(Render, __RENDER_TRAPEZOID_PRIMITIVE |
__RENDER_TEXTURED_PRIMITIVE);
}
else
{
// Render right to left, bottom to top
SEND_PERMEDIA_DATA(StartXDom, INTtoFIXED(rDest->right));
SEND_PERMEDIA_DATA(StartXSub, INTtoFIXED(rDest->left));
SEND_PERMEDIA_DATA(StartY, INTtoFIXED(rDest->bottom - 1));
SEND_PERMEDIA_DATA(dY, (DWORD)INTtoFIXED(-1));
SEND_PERMEDIA_DATA(Count, rDest->bottom - rDest->top);
SEND_PERMEDIA_DATA(Render, __RENDER_TRAPEZOID_PRIMITIVE |
__RENDER_TEXTURED_PRIMITIVE);
}
SEND_PERMEDIA_DATA(DitherMode, __PERMEDIA_DISABLE);
SEND_PERMEDIA_DATA(TextureAddressMode, __PERMEDIA_DISABLE);
SEND_PERMEDIA_DATA(TextureColorMode, __PERMEDIA_DISABLE);
SEND_PERMEDIA_DATA(TextureReadMode, __PERMEDIA_DISABLE);
COMMITDMAPTR();
FLUSHDMA();
} // PermediaStretchCopyBlt
//--------------------------------------------------------------------------
//
// PermediaSourceChromaBlt
//
// Does a blit through the texture unit to allow chroma keying.
// Note the unpacking of the colour key to fit into the Permedia format.
//
//--------------------------------------------------------------------------
VOID
PermediaSourceChromaBlt( PPDev ppdev,
LPDDHAL_BLTDATA lpBlt,
PermediaSurfaceData* pDest,
PermediaSurfaceData* pSource,
RECTL *rDest,
RECTL *rSrc,
DWORD dwWindowBase,
DWORD dwSourceOffset
)
{
DWORD dwLowerBound = lpBlt->bltFX.ddckSrcColorkey.dwColorSpaceLowValue;
DWORD dwUpperBound = lpBlt->bltFX.ddckSrcColorkey.dwColorSpaceHighValue;
DWORD dwRenderDirection;
LONG lPixelSize=pDest->SurfaceFormat.PixelSize;
PERMEDIA_DEFS(ppdev);
DBG_DD(( 5, "DDraw:PermediaSourceChromaBlt"));
ASSERTDD(pDest, "Not valid private surface in destination");
ASSERTDD(pSource, "Not valid private surface in source");
// Changes pixel depth to Frame buffer pixel depth if neccessary.
ConvertColorKeys( pSource, dwLowerBound, dwUpperBound);
RESERVEDMAPTR(31);
SEND_PERMEDIA_DATA(FBReadPixel, pDest->SurfaceFormat.FBReadPixel);
if (lPixelSize != 0)
{
// set writeback to dest surface...
SEND_PERMEDIA_DATA( DitherMode,
(pDest->SurfaceFormat.ColorOrder <<
PM_DITHERMODE_COLORORDER) |
(pDest->SurfaceFormat.Format <<
PM_DITHERMODE_COLORFORMAT) |
(pDest->SurfaceFormat.FormatExtension <<
PM_DITHERMODE_COLORFORMATEXTENSION) |
(1 << PM_DITHERMODE_ENABLE));
}
// Reject range
SEND_PERMEDIA_DATA(YUVMode, PM_YUVMODE_CHROMATEST_FAILWITHIN << 1);
SEND_PERMEDIA_DATA(FBWindowBase, dwWindowBase);
// set no read of source.
// add read src/dest enable
SEND_PERMEDIA_DATA(FBReadMode,pDest->ulPackedPP);
SEND_PERMEDIA_DATA(LogicalOpMode, __PERMEDIA_DISABLE);
// set base of source
SEND_PERMEDIA_DATA(TextureBaseAddress, dwSourceOffset);
SEND_PERMEDIA_DATA(TextureAddressMode,(1 << PM_TEXADDRESSMODE_ENABLE));
//
// modulate & ramp??
SEND_PERMEDIA_DATA(TextureColorMode, (1 << PM_TEXCOLORMODE_ENABLE) |
(_P2_TEXTURE_COPY <<
PM_TEXCOLORMODE_APPLICATION));
SEND_PERMEDIA_DATA(TextureReadMode,
PM_TEXREADMODE_ENABLE(__PERMEDIA_ENABLE) |
PM_TEXREADMODE_FILTER(__PERMEDIA_DISABLE) |
PM_TEXREADMODE_WIDTH(11) |
PM_TEXREADMODE_HEIGHT(11) );
SEND_PERMEDIA_DATA(TextureDataFormat,
(pSource->SurfaceFormat.Format <<
PM_TEXDATAFORMAT_FORMAT) |
(pSource->SurfaceFormat.FormatExtension <<
PM_TEXDATAFORMAT_FORMATEXTENSION) |
(pSource->SurfaceFormat.ColorOrder <<
PM_TEXDATAFORMAT_COLORORDER));
SEND_PERMEDIA_DATA( TextureMapFormat,
(pSource->ulPackedPP) |
(pSource->SurfaceFormat.PixelSize <<
PM_TEXMAPFORMAT_TEXELSIZE) );
SEND_PERMEDIA_DATA(ChromaLowerBound, dwLowerBound);
SEND_PERMEDIA_DATA(ChromaUpperBound, dwUpperBound);
if ((lpBlt->lpDDDestSurface->lpGbl->fpVidMem) !=
(lpBlt->lpDDSrcSurface->lpGbl->fpVidMem))
{
dwRenderDirection = 1;
}
else
{
if(rSrc->top < rDest->top)
{
dwRenderDirection = 0;
}
else if(rSrc->top > rDest->top)
{
dwRenderDirection = 1;
}
else if(rSrc->left < rDest->left)
{
dwRenderDirection = 0;
}
else dwRenderDirection = 1;
}
/*
* Render the rectangle
*/
// Left -> right, top->bottom
if (dwRenderDirection)
{
// set offset of source
SEND_PERMEDIA_DATA(SStart, rSrc->left<<20);
SEND_PERMEDIA_DATA(TStart, rSrc->top<<20);
SEND_PERMEDIA_DATA(dSdx, 1 << 20);
SEND_PERMEDIA_DATA(dSdyDom, 0);
SEND_PERMEDIA_DATA(dTdx, 0);
SEND_PERMEDIA_DATA(dTdyDom, 1 << 20);
SEND_PERMEDIA_DATA(StartXDom, INTtoFIXED(rDest->left));
SEND_PERMEDIA_DATA(StartXSub, INTtoFIXED(rDest->right));
SEND_PERMEDIA_DATA(StartY, INTtoFIXED(rDest->top));
SEND_PERMEDIA_DATA(dY, INTtoFIXED(1));
SEND_PERMEDIA_DATA(Count, rDest->bottom - rDest->top);
SEND_PERMEDIA_DATA(Render, __RENDER_TRAPEZOID_PRIMITIVE |
__RENDER_TEXTURED_PRIMITIVE);
}
else
// right->left, bottom->top
{
// set offset of source
SEND_PERMEDIA_DATA(SStart, rSrc->right << 20);
SEND_PERMEDIA_DATA(TStart, (rSrc->bottom - 1) << 20);
SEND_PERMEDIA_DATA(dSdx, (DWORD)(-1 << 20));
SEND_PERMEDIA_DATA(dSdyDom, 0);
SEND_PERMEDIA_DATA(dTdx, 0);
SEND_PERMEDIA_DATA(dTdyDom, (DWORD)(-1 << 20));
// Render right to left, bottom to top
SEND_PERMEDIA_DATA(StartXDom, INTtoFIXED(rDest->right));
SEND_PERMEDIA_DATA(StartXSub, INTtoFIXED(rDest->left));
SEND_PERMEDIA_DATA(StartY, INTtoFIXED(rDest->bottom - 1));
SEND_PERMEDIA_DATA(dY, (DWORD)INTtoFIXED(-1));
SEND_PERMEDIA_DATA(Count, rDest->bottom - rDest->top);
SEND_PERMEDIA_DATA(Render, __RENDER_TRAPEZOID_PRIMITIVE |
__RENDER_TEXTURED_PRIMITIVE);
}
// Turn off chroma key
SEND_PERMEDIA_DATA(YUVMode, 0x0);
SEND_PERMEDIA_DATA(TextureAddressMode, __PERMEDIA_DISABLE);
SEND_PERMEDIA_DATA(TextureColorMode, __PERMEDIA_DISABLE);
SEND_PERMEDIA_DATA(TextureReadMode, __PERMEDIA_DISABLE);
if (pSource->SurfaceFormat.PixelSize != 0)
{
SEND_PERMEDIA_DATA(DitherMode, 0);
}
COMMITDMAPTR();
FLUSHDMA();
} // PermediaSourceChromaBlt
//--------------------------------------------------------------------------
//
// PermediaStretchCopyChromaBlt
//
// Does a blit through the texture unit to allow stretching. Also
// handle mirroring and chroma keying if the stretched image requires it.
//
//--------------------------------------------------------------------------
VOID
PermediaStretchCopyChromaBlt( PPDev ppdev,
LPDDHAL_BLTDATA lpBlt,
PermediaSurfaceData* pDest,
PermediaSurfaceData* pSource,
RECTL *rDest,
RECTL *rSrc,
DWORD dwWindowBase,
DWORD dwSourceOffset
)
{
LONG lXScale;
LONG lYScale;
BOOL bYMirror;
BOOL bXMirror;
DWORD dwDestWidth = rDest->right - rDest->left;
DWORD dwDestHeight = rDest->bottom - rDest->top;
DWORD dwSourceWidth = rSrc->right - rSrc->left;
DWORD dwSourceHeight = rSrc->bottom - rSrc->top;
DWORD dwTexSStart, dwTexTStart;
DWORD dwRenderDirection;
LONG lPixelSize=pDest->SurfaceFormat.PixelSize;
DWORD dwLowerBound = lpBlt->bltFX.ddckSrcColorkey.dwColorSpaceLowValue;
DWORD dwUpperBound = lpBlt->bltFX.ddckSrcColorkey.dwColorSpaceHighValue;
PERMEDIA_DEFS(ppdev);
DBG_DD(( 5, "DDraw:PermediaStretchCopyChromaBlt"));
ASSERTDD(pDest, "Not valid private surface in destination");
ASSERTDD(pSource, "Not valid private surface in source");
// Changes pixel depth to Frame buffer pixel depth if neccessary.
ConvertColorKeys( pSource, dwLowerBound, dwUpperBound);
RESERVEDMAPTR(31);
SEND_PERMEDIA_DATA(FBReadPixel, pDest->SurfaceFormat.FBReadPixel);
if (lPixelSize != 0)
{
// set writeback to dest surface...
SEND_PERMEDIA_DATA( DitherMode,
(pDest->SurfaceFormat.ColorOrder <<
PM_DITHERMODE_COLORORDER) |
(pDest->SurfaceFormat.Format <<
PM_DITHERMODE_COLORFORMAT) |
(pDest->SurfaceFormat.FormatExtension <<
PM_DITHERMODE_COLORFORMATEXTENSION) |
(1 << PM_DITHERMODE_ENABLE));
}
// Reject range
SEND_PERMEDIA_DATA(YUVMode, PM_YUVMODE_CHROMATEST_FAILWITHIN <<1);
SEND_PERMEDIA_DATA(FBWindowBase, dwWindowBase);
// set no read of source.
SEND_PERMEDIA_DATA(FBReadMode, pDest->ulPackedPP);
SEND_PERMEDIA_DATA(LogicalOpMode, __PERMEDIA_DISABLE);
// set base of source
SEND_PERMEDIA_DATA(TextureBaseAddress, dwSourceOffset);
SEND_PERMEDIA_DATA(TextureAddressMode,(1 << PM_TEXADDRESSMODE_ENABLE));
SEND_PERMEDIA_DATA( TextureColorMode,
(1 << PM_TEXCOLORMODE_ENABLE) |
(_P2_TEXTURE_COPY << PM_TEXCOLORMODE_APPLICATION));
SEND_PERMEDIA_DATA( TextureReadMode,
PM_TEXREADMODE_ENABLE(__PERMEDIA_ENABLE) |
PM_TEXREADMODE_FILTER(__PERMEDIA_DISABLE) |
PM_TEXREADMODE_WIDTH(11) |
PM_TEXREADMODE_HEIGHT(11));
lXScale = (dwSourceWidth << 20) / (dwDestWidth);
lYScale = (dwSourceHeight << 20) / (dwDestHeight);
SEND_PERMEDIA_DATA( TextureDataFormat,
(pSource->SurfaceFormat.Format <<
PM_TEXDATAFORMAT_FORMAT) |
(pSource->SurfaceFormat.FormatExtension <<
PM_TEXDATAFORMAT_FORMATEXTENSION) |
(pSource->SurfaceFormat.ColorOrder <<
PM_TEXDATAFORMAT_COLORORDER));
SEND_PERMEDIA_DATA( TextureMapFormat,
(pSource->ulPackedPP) |
(pSource->SurfaceFormat.PixelSize <<
PM_TEXMAPFORMAT_TEXELSIZE) );
bYMirror = FALSE;
bXMirror = FALSE;
if ((lpBlt->lpDDDestSurface->lpGbl->fpVidMem) !=
(lpBlt->lpDDSrcSurface->lpGbl->fpVidMem))
{
dwRenderDirection = 1;
}
else
{
if(rSrc->top < rDest->top)
{
dwRenderDirection = 0;
}
else if(rSrc->top > rDest->top)
{
dwRenderDirection = 1;
}
else if(rSrc->left < rDest->left)
{
dwRenderDirection = 0;
}
else dwRenderDirection = 1;
}
if(lpBlt->dwFlags & DDBLT_DDFX)
{
bYMirror = lpBlt->bltFX.dwDDFX & DDBLTFX_MIRRORUPDOWN;
bXMirror = lpBlt->bltFX.dwDDFX & DDBLTFX_MIRRORLEFTRIGHT;
} else
{
if (dwRenderDirection==0)
{
bXMirror = TRUE;
bYMirror = TRUE;
}
}
if (bXMirror)
{
dwTexSStart = rSrc->right - 1;
lXScale = -lXScale;
}
else
{
dwTexSStart = rSrc->left;
}
if (bYMirror)
{
dwTexTStart = rSrc->bottom - 1;
lYScale = -lYScale;
}
else
{
dwTexTStart = rSrc->top;
}
SEND_PERMEDIA_DATA(dTdyDom, lYScale);
SEND_PERMEDIA_DATA(ChromaLowerBound, dwLowerBound);
SEND_PERMEDIA_DATA(ChromaUpperBound, dwUpperBound);
// set texture coordinates
SEND_PERMEDIA_DATA(SStart, dwTexSStart << 20);
SEND_PERMEDIA_DATA(TStart, dwTexTStart << 20);
SEND_PERMEDIA_DATA(dSdx, lXScale);
SEND_PERMEDIA_DATA(dSdyDom, 0);
SEND_PERMEDIA_DATA(dTdx, 0);
//
// Render the rectangle
//
if (dwRenderDirection)
{
SEND_PERMEDIA_DATA(StartXDom, INTtoFIXED(rDest->left));
SEND_PERMEDIA_DATA(StartXSub, INTtoFIXED(rDest->right));
SEND_PERMEDIA_DATA(StartY, INTtoFIXED(rDest->top));
SEND_PERMEDIA_DATA(dY, INTtoFIXED(1));
}
else
{
SEND_PERMEDIA_DATA(StartXDom, INTtoFIXED(rDest->right));
SEND_PERMEDIA_DATA(StartXSub, INTtoFIXED(rDest->left));
SEND_PERMEDIA_DATA(StartY, INTtoFIXED(rDest->bottom - 1));
SEND_PERMEDIA_DATA(dY, (DWORD)INTtoFIXED(-1));
}
SEND_PERMEDIA_DATA(Count, rDest->bottom - rDest->top);
SEND_PERMEDIA_DATA(Render, __RENDER_TRAPEZOID_PRIMITIVE |
__RENDER_TEXTURED_PRIMITIVE);
// Turn off units
SEND_PERMEDIA_DATA(YUVMode, __PERMEDIA_DISABLE);
SEND_PERMEDIA_DATA(TextureAddressMode, __PERMEDIA_DISABLE);
SEND_PERMEDIA_DATA(TextureColorMode, __PERMEDIA_DISABLE);
SEND_PERMEDIA_DATA(TextureReadMode, __PERMEDIA_DISABLE);
if (pSource->SurfaceFormat.PixelSize != 0)
{
SEND_PERMEDIA_DATA(DitherMode, 0);
}
COMMITDMAPTR();
FLUSHDMA();
} // PermediaStretchCopyChromaBlt
//--------------------------------------------------------------------------
//
// PermediaYUVtoRGB
//
// Permedia2 YUV to RGB conversion blt
//
//--------------------------------------------------------------------------
VOID
PermediaYUVtoRGB( PPDev ppdev,
DDBLTFX* lpBltFX,
PermediaSurfaceData* pDest,
PermediaSurfaceData* pSource,
RECTL *rDest,
RECTL *rSrc,
DWORD dwWindowBase,
DWORD dwSourceOffset)
{
DWORD lXScale;
DWORD lYScale;
DWORD dwDestWidth = rDest->right - rDest->left;
DWORD dwDestHeight = rDest->bottom - rDest->top;
DWORD dwSourceWidth = rSrc->right - rSrc->left;
DWORD dwSourceHeight = rSrc->bottom - rSrc->top;
PERMEDIA_DEFS(ppdev);
ASSERTDD(pDest, "Not valid private surface in destination");
ASSERTDD(pSource, "Not valid private surface in source");
lXScale = (dwSourceWidth << 20) / dwDestWidth;
lYScale = (dwSourceHeight << 20) / dwDestHeight;
// Changes pixel depth to Frame buffer pixel depth if neccessary.
RESERVEDMAPTR(29);
SEND_PERMEDIA_DATA(FBReadPixel,ppdev->bPixShift);
if (pDest->SurfaceFormat.PixelSize != __PERMEDIA_8BITPIXEL)
{
SEND_PERMEDIA_DATA(DitherMode,
(COLOR_MODE << PM_DITHERMODE_COLORORDER) |
(pDest->SurfaceFormat.Format << PM_DITHERMODE_COLORFORMAT) |
(pDest->SurfaceFormat.FormatExtension <<
PM_DITHERMODE_COLORFORMATEXTENSION) |
(1 << PM_DITHERMODE_ENABLE) |
(1 << PM_DITHERMODE_DITHERENABLE));
}
SEND_PERMEDIA_DATA(FBWindowBase, dwWindowBase);
// set no read of source.
SEND_PERMEDIA_DATA(FBReadMode, pDest->ulPackedPP);
SEND_PERMEDIA_DATA(LogicalOpMode, __PERMEDIA_DISABLE);
// set base of source
SEND_PERMEDIA_DATA(TextureBaseAddress, dwSourceOffset);
SEND_PERMEDIA_DATA(TextureAddressMode,(1 << PM_TEXADDRESSMODE_ENABLE));
SEND_PERMEDIA_DATA( TextureColorMode,
(1 << PM_TEXCOLORMODE_ENABLE) |
(_P2_TEXTURE_COPY << PM_TEXCOLORMODE_APPLICATION));
SEND_PERMEDIA_DATA( TextureReadMode,
PM_TEXREADMODE_ENABLE(__PERMEDIA_ENABLE) |
PM_TEXREADMODE_FILTER(__PERMEDIA_ENABLE) |
PM_TEXREADMODE_WIDTH(11) |
PM_TEXREADMODE_HEIGHT(11) );
SEND_PERMEDIA_DATA( TextureDataFormat,
(pSource->SurfaceFormat.Format <<
PM_TEXDATAFORMAT_FORMAT) |
(pSource->SurfaceFormat.FormatExtension <<
PM_TEXDATAFORMAT_FORMATEXTENSION) |
(INV_COLOR_MODE << PM_TEXDATAFORMAT_COLORORDER));
SEND_PERMEDIA_DATA( TextureMapFormat,
(pSource->ulPackedPP) |
(pSource->SurfaceFormat.PixelSize <<
PM_TEXMAPFORMAT_TEXELSIZE) );
// Turn on the YUV unit
SEND_PERMEDIA_DATA(YUVMode, 0x1);
SEND_PERMEDIA_DATA(LogicalOpMode, 0);
// set offset of source
SEND_PERMEDIA_DATA(SStart, rSrc->left << 20);
SEND_PERMEDIA_DATA(TStart, rSrc->top << 20);
SEND_PERMEDIA_DATA(dSdx, lXScale);
SEND_PERMEDIA_DATA(dSdyDom, 0);
SEND_PERMEDIA_DATA(dTdx, 0);
SEND_PERMEDIA_DATA(dTdyDom, lYScale);
// Render the rectangle
//
SEND_PERMEDIA_DATA(StartXDom, INTtoFIXED(rDest->left));
SEND_PERMEDIA_DATA(StartXSub, INTtoFIXED(rDest->right));
SEND_PERMEDIA_DATA(StartY, INTtoFIXED(rDest->top));
SEND_PERMEDIA_DATA(dY, INTtoFIXED(1));
SEND_PERMEDIA_DATA(Count, rDest->bottom - rDest->top);
SEND_PERMEDIA_DATA(Render, __RENDER_TRAPEZOID_PRIMITIVE |
__RENDER_TEXTURED_PRIMITIVE);
if (pSource->SurfaceFormat.PixelSize != __PERMEDIA_8BITPIXEL)
{
SEND_PERMEDIA_DATA(DitherMode, 0);
}
// Turn off units
SEND_PERMEDIA_DATA(YUVMode, 0x0);
SEND_PERMEDIA_DATA( TextureAddressMode,
(0 << PM_TEXADDRESSMODE_ENABLE));
SEND_PERMEDIA_DATA( TextureColorMode,
(0 << PM_TEXCOLORMODE_ENABLE));
COMMITDMAPTR();
FLUSHDMA();
}