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.
 
 
 
 
 
 

1301 lines
44 KiB

/******************************Module*Header**********************************\
*
* *******************
* * GDI SAMPLE CODE *
* *******************
*
* Module Name: draw.c
*
* Contains the DrvFillPath routine. Permedia P2 optimised functions
*
* Copyright (c) 1994-1998 3Dlabs Inc. Ltd. All rights reserved.
* Copyright (c) 1995-1999 Microsoft Corporation. All rights reserved.
\*****************************************************************************/
#include "precomp.h"
#include "gdi.h"
#include "directx.h"
//-----------------------------------------------------------------------------
//
// void vAlphaBlendDownload(GFNPB * ppb)
//
// Doing an alpha blend on a source surface which is in a pre-multiplied alpha
// 32bpp "BGRA" format; that is, the surface type is BMF_32BPP and the palette
// type is BI_RGB.
//
// Argumentes needed from function block (GFNPB)
// ppdev-------PPDev
// psoSrc------Pointer to source SURFOBJ
// psurfDst----Destination surface
// pRects------Pointer to a list of rectangles information which needed to be
// filled
// lNumRects---Number of rectangles to fill
// prclDst-----Points to a RECTL structure that defines the rectangular area
// to be modified
// prclSrc-----Points to a RECTL structure that defines the rectangular area
// to be copied
// ucAlpha-----Alpha value
//
//-----------------------------------------------------------------------------
VOID
vAlphaBlendDownload(GFNPB * ppb)
{
PDev* ppdev = ppb->ppdev;
Surf* psurfDst = ppb->psurfDst;
RECTL* prcl = ppb->pRects;
LONG c = ppb->lNumRects;
RECTL* prclDst = ppb->prclDst;
RECTL* prclSrc = ppb->prclSrc;
DWORD dwRenderDirection;
UCHAR ucAlpha = ppb->ucAlpha;
SURFOBJ* psoSrc = ppb->psoSrc;
ULONG* pBuffer;
DBG_GDI((6, "vAlphaBlendDownload called"));
ASSERTDD(ppdev->cPelSize != 0,
"vAlphaBlend: expect not to be in 8bpp mode");
ASSERTDD(psoSrc->iBitmapFormat == BMF_32BPP,
"vAlphaBlend: expect source bitmap format to be 32bpp");
InputBufferReserve(ppdev, 20, &pBuffer);
pBuffer[0] = __Permedia2TagDitherMode;
pBuffer[1] = (COLOR_MODE << PM_DITHERMODE_COLORORDER) |
(ppdev->ulPermFormat << PM_DITHERMODE_COLORFORMAT) |
(ppdev->ulPermFormatEx << PM_DITHERMODE_COLORFORMATEXTENSION) |
(1 << PM_DITHERMODE_ENABLE);
pBuffer[2] = __Permedia2TagAlphaBlendMode;
pBuffer[3] = (1 << PM_ALPHABLENDMODE_BLENDTYPE) | // ramp
(1 << PM_ALPHABLENDMODE_COLORORDER) | // RGB
(1 << PM_ALPHABLENDMODE_ENABLE) |
(81 << PM_ALPHABLENDMODE_OPERATION) | // PreMult
(ppdev->ulPermFormat << PM_ALPHABLENDMODE_COLORFORMAT) |
(ppdev->ulPermFormatEx << PM_ALPHABLENDMODE_COLORFORMATEXTENSION);
// Reject range
pBuffer[4] = __Permedia2TagFBWindowBase;
pBuffer[5] = psurfDst->ulPixOffset;
// set no read of source.
pBuffer[6] = __Permedia2TagFBReadMode;
pBuffer[7] = 0x400 | psurfDst->ulPackedPP;
pBuffer[8] = __Permedia2TagLogicalOpMode;
pBuffer[9] = __PERMEDIA_DISABLE;
pBuffer[10] = __Permedia2TagTextureColorMode;
pBuffer[11] = (1 << PM_TEXCOLORMODE_ENABLE) |
(0 << 4) | // RGB
(0 << 1) ; // Modulate
pBuffer[12] = __Permedia2TagTextureDataFormat;
pBuffer[13] = (ppdev->ulPermFormat << PM_TEXDATAFORMAT_FORMAT) |
(ppdev->ulPermFormatEx << PM_TEXDATAFORMAT_FORMATEXTENSION) |
(COLOR_MODE << PM_TEXDATAFORMAT_COLORORDER);
pBuffer[14] = __Permedia2TagColorDDAMode;
pBuffer[15] = 1;
pBuffer[16] = __Permedia2TagConstantColor;
pBuffer[17] = ucAlpha << 24 | ucAlpha << 16 | ucAlpha << 8 | ucAlpha;
pBuffer[18] = __Permedia2TagTextureReadMode;
pBuffer[19] = PM_TEXREADMODE_ENABLE(__PERMEDIA_DISABLE);
pBuffer += 20;
InputBufferCommit(ppdev, pBuffer);
while(c--)
{
InputBufferReserve(ppdev, 12, &pBuffer);
pBuffer[0] = __Permedia2TagStartXDom;
pBuffer[1] = prcl->left << 16;
pBuffer[2] = __Permedia2TagStartXSub;
pBuffer[3] = prcl->right << 16;
pBuffer[4] = __Permedia2TagStartY;
pBuffer[5] = prcl->top << 16;
pBuffer[6] = __Permedia2TagdY;
pBuffer[7] = 1 << 16;
pBuffer[8] = __Permedia2TagCount;
pBuffer[9] = prcl->bottom - prcl->top;
pBuffer[10] = __Permedia2TagRender;
pBuffer[11] = __RENDER_TRAPEZOID_PRIMITIVE
| __RENDER_TEXTURED_PRIMITIVE
| __RENDER_SYNC_ON_HOST_DATA;
pBuffer += 12;
InputBufferCommit(ppdev, pBuffer);
// download data
{
LONG xOffset = prclSrc->left + (prcl->left - prclDst->left);
LONG yOffset = prclSrc->top + (prcl->top - prclDst->top);
ULONG * pulTexel = (ULONG *) psoSrc->pvScan0;
ULONG ulWidth = prcl->right - prcl->left;
ULONG ulHeight = prcl->bottom - prcl->top;
LONG ulPixDelta = psoSrc->lDelta >> 2;
LONG ulScanSkip = ulPixDelta - ulWidth;
ULONG* pulSentinel;
ASSERTDD(psoSrc->pvScan0 != NULL, "pvScan0 is null");
ASSERTDD((psoSrc->lDelta & 3) == 0, "lDelta not multiple of four");
ASSERTDD(xOffset >= 0, "xOffset is negative");
ASSERTDD(yOffset >= 0, "yOffset is negative");
ASSERTDD(ulWidth < MAX_INPUT_BUFFER_RESERVATION,
"vAlphaBlendDownload: width is too large");
pulTexel += xOffset;
pulTexel += ulPixDelta * yOffset;
while(ulHeight--)
{
pulSentinel = pulTexel + ulWidth;
InputBufferReserve(ppdev, ulWidth + 1, &pBuffer);
*pBuffer++ = __Permedia2TagTexel0 | ((ulWidth - 1) << 16);
while(pulTexel < pulSentinel)
{
ULONG texel = *pulTexel++;
*pBuffer++ = SWAP_BR(texel);
}
InputBufferCommit(ppdev, pBuffer);
pulTexel += ulScanSkip;
}
}
prcl++;
}
//
// Always restore default state
//
InputBufferReserve(ppdev, 16, &pBuffer);
pBuffer[0] = __Permedia2TagdY;
pBuffer[1] = INTtoFIXED(1);
pBuffer[2] = __Permedia2TagDitherMode;
pBuffer[3] = 0;
pBuffer[4] = __Permedia2TagYUVMode;
pBuffer[5] = 0;
pBuffer[6] = __Permedia2TagTextureAddressMode;
pBuffer[7] = __PERMEDIA_DISABLE;
pBuffer[8] = __Permedia2TagTextureColorMode;
pBuffer[9] = __PERMEDIA_DISABLE;
pBuffer[10] = __Permedia2TagTextureReadMode;
pBuffer[11] = __PERMEDIA_DISABLE;
pBuffer[12] = __Permedia2TagAlphaBlendMode;
pBuffer[13] = __PERMEDIA_DISABLE;
pBuffer[14] = __Permedia2TagColorDDAMode;
pBuffer[15] = __PERMEDIA_DISABLE;
pBuffer += 16;
InputBufferCommit(ppdev, pBuffer);
}// vAlphaBlend()
//-----------------------------------------------------------------------------
//
// void vConstantAlphaBlend(GFNPB * ppb)
//
// Using constant blend factor to apply to the entire source surface
//
// Argumentes needed from function block (GFNPB)
// ppdev-------PPDev
// psurfSrc----Source surface
// psurfDst----Destination surface
// pRects------Pointer to a list of rectangles information which needed to be
// filled
// lNumRects---Number of rectangles to fill
// prclDst-----Points to a RECTL structure that defines the rectangular area
// to be modified
// prclSrc-----Points to a RECTL structure that defines the rectangular area
// to be copied
// ucAlpha-----Alpha value
//
//-----------------------------------------------------------------------------
VOID
vConstantAlphaBlend(GFNPB * ppb)
{
PDev* ppdev = ppb->ppdev;
Surf* psurfSrc = ppb->psurfSrc;
Surf* psurfDst = ppb->psurfDst;
RECTL* prcl = ppb->pRects;
LONG c = ppb->lNumRects;
RECTL* prclDst = ppb->prclDst;
RECTL* prclSrc = ppb->prclSrc;
DWORD dwRenderDirection;
UCHAR alpha = ppb->ucAlpha;
ULONG* pBuffer;
DBG_GDI((6,"vConstantAlphaBlend called"));
ASSERTDD(ppdev->cPelSize != 0,
"vAlphaBlend: expect not to be in 8bpp mode");
// setup loop invariant state
InputBufferReserve(ppdev, 26, &pBuffer);
pBuffer[0] = __Permedia2TagDitherMode;
pBuffer[1] = (COLOR_MODE << PM_DITHERMODE_COLORORDER) |
(ppdev->ulPermFormat << PM_DITHERMODE_COLORFORMAT) |
(ppdev->ulPermFormatEx << PM_DITHERMODE_COLORFORMATEXTENSION) |
(1 << PM_DITHERMODE_ENABLE);
pBuffer[2] = __Permedia2TagAlphaBlendMode;
pBuffer[3] = ppdev->ulPermFormat << 8 |
ppdev->ulPermFormatEx << 16 |
( 1 << 0 ) | // enable blending
( 1 << 13) | // color order: BGR=0, RGB=1
( 1 << 14) | // BlendType: RGB=0, Ramp=1
(84 << 1); // Operation: Blend=84, PreMult=81
// Reject range
pBuffer[4] = __Permedia2TagFBWindowBase;
pBuffer[5] = psurfDst->ulPixOffset;
// set no read of source.
pBuffer[6] = __Permedia2TagFBReadMode;
pBuffer[7] = 0x400 // read destination enable
| psurfDst->ulPackedPP;
pBuffer[8] = __Permedia2TagLogicalOpMode;
pBuffer[9] = __PERMEDIA_DISABLE;
// set base of source
pBuffer[10] = __Permedia2TagTextureBaseAddress;
pBuffer[11] = psurfSrc->ulPixOffset;
pBuffer[12] = __Permedia2TagTextureAddressMode;
pBuffer[13] = (1 << PM_TEXADDRESSMODE_ENABLE);
pBuffer[14] = __Permedia2TagTextureColorMode;
pBuffer[15] = (1 << PM_TEXCOLORMODE_ENABLE) |
(0 << 4) | // RGB
(0 << 1); // Modulate
pBuffer[16] = __Permedia2TagTextureReadMode;
pBuffer[17] = PM_TEXREADMODE_ENABLE(__PERMEDIA_ENABLE) |
PM_TEXREADMODE_FILTER(__PERMEDIA_DISABLE) |
PM_TEXREADMODE_WIDTH(11) |
PM_TEXREADMODE_HEIGHT(11);
pBuffer[18] = __Permedia2TagTextureDataFormat;
pBuffer[19] = (ppdev->ulPermFormat << PM_TEXDATAFORMAT_FORMAT) |
(ppdev->ulPermFormatEx << PM_TEXDATAFORMAT_FORMATEXTENSION) |
(COLOR_MODE << PM_TEXDATAFORMAT_COLORORDER) |
(1 << 4); // no alpha
pBuffer[20] = __Permedia2TagTextureMapFormat;
pBuffer[21] = (psurfSrc->ulPackedPP) |
(ppdev->cPelSize << PM_TEXMAPFORMAT_TEXELSIZE);
pBuffer[22] = __Permedia2TagColorDDAMode;
pBuffer[23] = 1;
pBuffer[24] = __Permedia2TagConstantColor;
pBuffer[25] = alpha << 24 | 0xffffff ;
pBuffer += 26;
InputBufferCommit(ppdev, pBuffer);
while(c--)
{
RECTL rDest;
RECTL rSrc;
rDest = *prcl;
rSrc.left = prclSrc->left + (rDest.left - prclDst->left);
rSrc.top = prclSrc->top + (rDest.top - prclDst->top);
rSrc.right = rSrc.left + (rDest.right - rDest.left);
rSrc.bottom = rSrc.top + (rDest.bottom - rDest.top);
if (rSrc.top < 0) {
rDest.top -= rSrc.top;
rSrc.top = 0;
}
if (rSrc.left < 0) {
rDest.left -= rSrc.left;
rSrc.left = 0;
}
//@@BEGIN_DDKSPLIT
// TODO: remove some of the magic values
//@@END_DDKSPLIT
if (psurfSrc->ulPixOffset != psurfDst->ulPixOffset)
{
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;
}
InputBufferReserve(ppdev, 24, &pBuffer);
// Left -> right, top->bottom
if (dwRenderDirection)
{
// set offset of source
pBuffer[0] = __Permedia2TagSStart;
pBuffer[1] = rSrc.left << 20;
pBuffer[2] = __Permedia2TagTStart;
pBuffer[3] = rSrc.top << 20;
pBuffer[4] = __Permedia2TagdSdx;
pBuffer[5] = 1 << 20;
pBuffer[6] = __Permedia2TagdSdyDom;
pBuffer[7] = 0;
pBuffer[8] = __Permedia2TagdTdx;
pBuffer[9] = 0;
pBuffer[10] = __Permedia2TagdTdyDom;
pBuffer[11] = 1 << 20;
pBuffer[12] = __Permedia2TagStartXDom;
pBuffer[13] = rDest.left << 16;
pBuffer[14] = __Permedia2TagStartXSub;
pBuffer[15] = rDest.right << 16;
pBuffer[16] = __Permedia2TagStartY;
pBuffer[17] = rDest.top << 16;
pBuffer[18] = __Permedia2TagdY;
pBuffer[19] = 1 << 16;
pBuffer[20] = __Permedia2TagCount;
pBuffer[21] = rDest.bottom - rDest.top;
pBuffer[22] = __Permedia2TagRender;
pBuffer[23] = __RENDER_TRAPEZOID_PRIMITIVE
| __RENDER_TEXTURED_PRIMITIVE;
}
else
// right->left, bottom->top
{
// set offset of source
pBuffer[0] = __Permedia2TagSStart;
pBuffer[1] = rSrc.right << 20;
pBuffer[2] = __Permedia2TagTStart;
pBuffer[3] = (rSrc.bottom - 1) << 20;
pBuffer[4] = __Permedia2TagdSdx;
pBuffer[5] = (DWORD)(-1 << 20);
pBuffer[6] = __Permedia2TagdSdyDom;
pBuffer[7] = 0;
pBuffer[8] = __Permedia2TagdTdx;
pBuffer[9] = 0;
pBuffer[10] = __Permedia2TagdTdyDom;
pBuffer[11] = (DWORD)(-1 << 20);
// Render right to left, bottom to top
pBuffer[12] = __Permedia2TagStartXDom;
pBuffer[13] = rDest.right << 16;
pBuffer[14] = __Permedia2TagStartXSub;
pBuffer[15] = rDest.left << 16;
pBuffer[16] = __Permedia2TagStartY;
pBuffer[17] = (rDest.bottom - 1) << 16;
pBuffer[18] = __Permedia2TagdY;
pBuffer[19] = (DWORD)(-1 << 16);
pBuffer[20] = __Permedia2TagCount;
pBuffer[21] = rDest.bottom - rDest.top;
pBuffer[22] = __Permedia2TagRender;
pBuffer[23] = __RENDER_TRAPEZOID_PRIMITIVE
| __RENDER_TEXTURED_PRIMITIVE;
}
pBuffer += 24;
InputBufferCommit(ppdev, pBuffer);
prcl++;
}
InputBufferReserve(ppdev, 20, &pBuffer);
pBuffer[0] = __Permedia2TagdY;
pBuffer[1] = INTtoFIXED(1);
pBuffer[2] = __Permedia2TagDitherMode;
pBuffer[3] = 0;
pBuffer[4] = __Permedia2TagYUVMode;
pBuffer[5] = 0;
pBuffer[6] = __Permedia2TagTextureAddressMode;
pBuffer[7] = __PERMEDIA_DISABLE;
pBuffer[8] = __Permedia2TagTextureColorMode;
pBuffer[9] = __PERMEDIA_DISABLE;
pBuffer[10] = __Permedia2TagTextureReadMode;
pBuffer[11] = __PERMEDIA_DISABLE;
pBuffer[12] = __Permedia2TagAlphaBlendMode;
pBuffer[13] = __PERMEDIA_DISABLE;
pBuffer[14] = __Permedia2TagColorDDAMode;
pBuffer[15] = __PERMEDIA_DISABLE;
pBuffer[16] = __Permedia2TagTextureDataFormat;
pBuffer[17] = __PERMEDIA_DISABLE;
pBuffer[18] = __Permedia2TagTextureMapFormat;
pBuffer[19] = __PERMEDIA_DISABLE;
pBuffer += 20;
InputBufferCommit(ppdev, pBuffer);
}// vConstantAlphaBlend()
//-----------------------------------------------------------------------------
//
// void vAlphaBlend(GFNPB * ppb)
//
// Doing an alpha blend on a source surface which is in a pre-multiplied alpha
// 32bpp "BGRA" format; that is, the surface type is BMF_32BPP and the palette
// type is BI_RGB.
//
// Argumentes needed from function block (GFNPB)
// ppdev-------PPDev
// psurfSrc----Source surface
// psurfDst----Destination surface
// pRects------Pointer to a list of rectangles information which needed to be
// filled
// lNumRects---Number of rectangles to fill
// prclDst-----Points to a RECTL structure that defines the rectangular area
// to be modified
// prclSrc-----Points to a RECTL structure that defines the rectangular area
// to be copied
// ucAlpha-----Alpha value
//
//-----------------------------------------------------------------------------
VOID
vAlphaBlend(GFNPB * ppb)
{
PDev* ppdev = ppb->ppdev;
Surf* psurfSrc = ppb->psurfSrc;
Surf* psurfDst = ppb->psurfDst;
RECTL* prcl = ppb->pRects;
LONG c = ppb->lNumRects;
RECTL* prclDst = ppb->prclDst;
RECTL* prclSrc = ppb->prclSrc;
DWORD dwRenderDirection;
UCHAR ucAlpha = ppb->ucAlpha;
ULONG* pBuffer;
DBG_GDI((6, "vAlphaBlend called"));
DBG_GDI((7,"vAlphaBlend"));
ASSERTDD(ppdev->cPelSize != 0,
"vAlphaBlend: expect not to be in 8bpp mode");
InputBufferReserve(ppdev, 26, &pBuffer);
pBuffer[0] = __Permedia2TagDitherMode;
pBuffer[1] = (COLOR_MODE << PM_DITHERMODE_COLORORDER) |
(ppdev->ulPermFormat << PM_DITHERMODE_COLORFORMAT) |
(ppdev->ulPermFormatEx << PM_DITHERMODE_COLORFORMATEXTENSION) |
(1 << PM_DITHERMODE_ENABLE);
pBuffer[2] = __Permedia2TagAlphaBlendMode;
pBuffer[3] = (1 << PM_ALPHABLENDMODE_BLENDTYPE) | // ramp
(1 << PM_ALPHABLENDMODE_COLORORDER) | // RGB
(1 << PM_ALPHABLENDMODE_ENABLE) |
(81 << PM_ALPHABLENDMODE_OPERATION) | // PreMult
(ppdev->ulPermFormat << PM_ALPHABLENDMODE_COLORFORMAT) |
(ppdev->ulPermFormatEx << PM_ALPHABLENDMODE_COLORFORMATEXTENSION);
// Reject range
pBuffer[4] = __Permedia2TagFBWindowBase;
pBuffer[5] = psurfDst->ulPixOffset;
// set no read of source.
pBuffer[6] = __Permedia2TagFBReadMode;
pBuffer[7] = 0x400 | psurfDst->ulPackedPP;
pBuffer[8] = __Permedia2TagLogicalOpMode;
pBuffer[9] = __PERMEDIA_DISABLE;
// set base of source
pBuffer[10] = __Permedia2TagTextureBaseAddress;
pBuffer[11] = psurfSrc->ulPixOffset;
pBuffer[12] = __Permedia2TagTextureAddressMode;
pBuffer[13] = (1 << PM_TEXADDRESSMODE_ENABLE);
pBuffer[14] = __Permedia2TagTextureColorMode;
pBuffer[15] = (1 << PM_TEXCOLORMODE_ENABLE) |
(0 << 4) | // RGB
(0 << 1); // Modulate
pBuffer[16] = __Permedia2TagTextureReadMode;
pBuffer[17] = PM_TEXREADMODE_ENABLE(__PERMEDIA_ENABLE) |
PM_TEXREADMODE_FILTER(__PERMEDIA_DISABLE) |
PM_TEXREADMODE_WIDTH(11) |
PM_TEXREADMODE_HEIGHT(11);
pBuffer[18] = __Permedia2TagTextureDataFormat;
pBuffer[19] = (ppdev->ulPermFormat << PM_TEXDATAFORMAT_FORMAT) |
(ppdev->ulPermFormatEx << PM_TEXDATAFORMAT_FORMATEXTENSION) |
(COLOR_MODE << PM_TEXDATAFORMAT_COLORORDER);
pBuffer[20] = __Permedia2TagTextureMapFormat;
pBuffer[21] = (psurfSrc->ulPackedPP) |
(ppdev->cPelSize << PM_TEXMAPFORMAT_TEXELSIZE);
pBuffer[22] = __Permedia2TagColorDDAMode;
pBuffer[23] = 1;
pBuffer[24] = __Permedia2TagConstantColor;
pBuffer[25] = ucAlpha << 24 | ucAlpha << 16 | ucAlpha << 8 | ucAlpha;
pBuffer += 26;
InputBufferCommit(ppdev, pBuffer);
while(c--)
{
RECTL rDest;
RECTL rSrc;
rDest = *prcl;
rSrc.left = prclSrc->left + (rDest.left - prclDst->left);
rSrc.top = prclSrc->top + (rDest.top - prclDst->top);
rSrc.right = rSrc.left + (rDest.right - rDest.left);
rSrc.bottom = rSrc.top + (rDest.bottom - rDest.top);
if (rSrc.top < 0) {
rDest.top -= rSrc.top;
rSrc.top = 0;
}
if (rSrc.left < 0) {
rDest.left -= rSrc.left;
rSrc.left = 0;
}
//@@BEGIN_DDKSPLIT
// TODO: use continuation to save permedia writes
// TODO: remove some of the magic values
//@@END_DDKSPLIT
if (psurfSrc->ulPixOffset != psurfDst->ulPixOffset)
{
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
*/
InputBufferReserve(ppdev, 24, &pBuffer);
// Left -> right, top->bottom
if (dwRenderDirection)
{
// set offset of source
pBuffer[0] = __Permedia2TagSStart;
pBuffer[1] = rSrc.left << 20;
pBuffer[2] = __Permedia2TagTStart;
pBuffer[3] = rSrc.top << 20;
pBuffer[4] = __Permedia2TagdSdx;
pBuffer[5] = 1 << 20;
pBuffer[6] = __Permedia2TagdSdyDom;
pBuffer[7] = 0;
pBuffer[8] = __Permedia2TagdTdx;
pBuffer[9] = 0;
pBuffer[10] = __Permedia2TagdTdyDom;
pBuffer[11] = 1 << 20;
pBuffer[12] = __Permedia2TagStartXDom;
pBuffer[13] = rDest.left << 16;
pBuffer[14] = __Permedia2TagStartXSub;
pBuffer[15] = rDest.right << 16;
pBuffer[16] = __Permedia2TagStartY;
pBuffer[17] = rDest.top << 16;
pBuffer[18] = __Permedia2TagdY;
pBuffer[19] = 1 << 16;
pBuffer[20] = __Permedia2TagCount;
pBuffer[21] = rDest.bottom - rDest.top;
pBuffer[22] = __Permedia2TagRender;
pBuffer[23] = __RENDER_TRAPEZOID_PRIMITIVE
| __RENDER_TEXTURED_PRIMITIVE;
}
else
// right->left, bottom->top
{
// set offset of source
pBuffer[0] = __Permedia2TagSStart;
pBuffer[1] = rSrc.right << 20;
pBuffer[2] = __Permedia2TagTStart;
pBuffer[3] = (rSrc.bottom - 1) << 20;
pBuffer[4] = __Permedia2TagdSdx;
pBuffer[5] = (DWORD)(-1 << 20);
pBuffer[6] = __Permedia2TagdSdyDom;
pBuffer[7] = 0;
pBuffer[8] = __Permedia2TagdTdx;
pBuffer[9] = 0;
pBuffer[10] = __Permedia2TagdTdyDom;
pBuffer[11] = (DWORD)(-1 << 20);
// Render right to left, bottom to top
pBuffer[12] = __Permedia2TagStartXDom;
pBuffer[13] = rDest.right << 16;
pBuffer[14] = __Permedia2TagStartXSub;
pBuffer[15] = rDest.left << 16;
pBuffer[16] = __Permedia2TagStartY;
pBuffer[17] = (rDest.bottom - 1) << 16;
pBuffer[18] = __Permedia2TagdY;
pBuffer[19] = (DWORD)(-1 << 16);
pBuffer[20] = __Permedia2TagCount;
pBuffer[21] = rDest.bottom - rDest.top;
pBuffer[22] = __Permedia2TagRender;
pBuffer[23] = __RENDER_TRAPEZOID_PRIMITIVE
| __RENDER_TEXTURED_PRIMITIVE;
}
pBuffer += 24;
InputBufferCommit(ppdev, pBuffer);
prcl++;
}
//
// Always restore default state
//
InputBufferReserve(ppdev, 16, &pBuffer);
pBuffer[0] = __Permedia2TagdY;
pBuffer[1] = INTtoFIXED(1);
pBuffer[2] = __Permedia2TagDitherMode;
pBuffer[3] = 0;
pBuffer[4] = __Permedia2TagYUVMode;
pBuffer[5] = 0;
pBuffer[6] = __Permedia2TagTextureAddressMode;
pBuffer[7] = __PERMEDIA_DISABLE;
pBuffer[8] = __Permedia2TagTextureColorMode;
pBuffer[9] = __PERMEDIA_DISABLE;
pBuffer[10] = __Permedia2TagTextureReadMode;
pBuffer[11] = __PERMEDIA_DISABLE;
pBuffer[12] = __Permedia2TagAlphaBlendMode;
pBuffer[13] = __PERMEDIA_DISABLE;
pBuffer[14] = __Permedia2TagColorDDAMode;
pBuffer[15] = __PERMEDIA_DISABLE;
pBuffer += 16;
InputBufferCommit(ppdev, pBuffer);
}// vAlphaBlend()
//-----------------------------------------------------------------------------
//
// VOID vCopyBlt(GFNPB* ppb)
//
// Does a screen-to-screen copy blt of a list of rectangles.
//
// Argumentes needed from function block (GFNPB)
// ppdev-------PPDev
// psurfSrc----Source surface
// psurfDst----Destination surface
// pRects------Pointer to a list of rectangles information which needed to be
// filled
// lNumRects---Number of rectangles to fill
// prclDst-----Points to a RECTL structure that defines the rectangular area
// to be modified
// pptlSrc-----Original unclipped source point
//
//-----------------------------------------------------------------------------
VOID
vCopyBlt(GFNPB* ppb)
{
PDev* ppdev = ppb->ppdev;
Surf* psurfSrc = ppb->psurfSrc;
Surf* psurfDst = ppb->psurfDst;
RECTL* prcl = ppb->pRects;
LONG c = ppb->lNumRects;
RECTL* prclDst = ppb->prclDst;
POINTL* pptlSrc = ppb->pptlSrc;
DWORD renderBits = __RENDER_TRAPEZOID_PRIMITIVE;
DWORD offset;
LONG sourceOffset;
DWORD windowBase;
LONG windowOffset;
ULONG DestPitch = psurfDst->ulPixDelta;
ULONG SourcePitch = psurfSrc->ulPixDelta;
BOOL bEnablePacked = TRUE;
ULONG ulLogicOP = ulRop2ToLogicop(ppb->ulRop4 & 0xf);
DBG_GDI((6, "vCopyBlt called"));
windowBase = psurfDst->ulPixOffset;
windowOffset = (LONG) (psurfSrc->ulPixOffset - psurfDst->ulPixOffset);
// BUGFIX: Permedia hardware bug
// We can not enable if we have an overlapping blt with not vertical shift
// and a horizontal shift less or equal to ppdev->dwBppMask
if (psurfSrc == psurfDst && prclDst->top == pptlSrc->y)
{
LONG xShift = prclDst->left - pptlSrc->x;
if(xShift >= 0 && xShift <= (LONG) ppdev->dwBppMask)
bEnablePacked = FALSE;
}
// BUGFIX: Permedia hardware bug???
// We have intermittent failures of the copy operation
// when going from the screen to offscreen where the first
// four bytes (when in 8bpp) of every row are not copied.
// For now, I'm disabling until we can talk with the permedia folks.
bEnablePacked = FALSE;
// setup loop invariant state
ULONG* pBuffer;
InputBufferReserve(ppdev, 4, &pBuffer);
pBuffer[0] = __Permedia2TagLogicalOpMode;
pBuffer[1] = P2_ENABLED_LOGICALOP(ulLogicOP);
pBuffer[2] = __Permedia2TagFBWindowBase;
pBuffer[3] = windowBase;
pBuffer += 4;
InputBufferCommit(ppdev, pBuffer);
while(c--) {
RECTL rDest;
RECTL rSrc;
rDest = *prcl;
rSrc.left = pptlSrc->x + (rDest.left - prclDst->left);
rSrc.top = pptlSrc->y + (rDest.top - prclDst->top);
rSrc.right = rSrc.left + (rDest.right - rDest.left);
rSrc.bottom = rSrc.top + (rDest.bottom - rDest.top);
if (rSrc.top < 0) {
rDest.top -= rSrc.top;
rSrc.top = 0;
}
if (rSrc.left < 0) {
rDest.left -= rSrc.left;
rSrc.left = 0;
}
if(bEnablePacked)
{
offset = (((rDest.left & ppdev->dwBppMask)
- (rSrc.left & ppdev->dwBppMask)) & 7);
sourceOffset = windowOffset
+ ((rSrc.top * SourcePitch) + (rSrc.left & ~(ppdev->dwBppMask)))
- ((rDest.top * DestPitch) + (rDest.left & ~(ppdev->dwBppMask)))
+ ((DestPitch - SourcePitch) * rDest.top);
}
else
{
offset = 0;
sourceOffset = windowOffset + ((rSrc.top * SourcePitch) + rSrc.left)
- ((rDest.top * DestPitch) + rDest.left)
+ ((DestPitch - SourcePitch) * rDest.top);
}
// P2_DEFAULT_FB_DEPTH;
ULONG readMode = PM_FBREADMODE_PARTIAL(psurfSrc->ulPackedPP) |
PM_FBREADMODE_READSOURCE(__PERMEDIA_ENABLE) |
PM_FBREADMODE_RELATIVEOFFSET(offset) |
LogicopReadDest[ulLogicOP];
ULONG writeConfig = PM_FBREADMODE_PARTIAL(psurfDst->ulPackedPP) |
PM_FBREADMODE_READSOURCE(__PERMEDIA_ENABLE) |
PM_FBREADMODE_RELATIVEOFFSET(offset) |
LogicopReadDest[ulLogicOP];
if(bEnablePacked)
{
readMode |= PM_FBREADMODE_PACKEDDATA(__PERMEDIA_ENABLE);
writeConfig |= PM_FBREADMODE_PACKEDDATA(__PERMEDIA_ENABLE);
}
// Render the rectangle
ULONG startXDom;
ULONG startXSub;
ULONG packedDataLimits;
ULONG startY;
ULONG dy;
if (sourceOffset >= 0) {
// Use left to right and top to bottom
if(bEnablePacked)
{
startXDom = (rDest.left >> ppdev->bBppShift) << 16;
startXSub = ((rDest.right >> ppdev->bBppShift)
+ ppdev->dwBppMask) << 16;
packedDataLimits = PM_PACKEDDATALIMITS_OFFSET(offset) |
PM_PACKEDDATALIMITS_XSTART(rDest.left) |
PM_PACKEDDATALIMITS_XEND(rDest.right);
}
else
{
startXDom = rDest.left << 16;
startXSub = rDest.right << 16;
}
startY = rDest.top << 16;
dy = 1 << 16;
}
else
{
// Use right to left and bottom to top
if(bEnablePacked)
{
startXDom = (((rDest.right) >> ppdev->bBppShift)
+ ppdev->dwBppMask) << 16;
startXSub = (rDest.left >> ppdev->bBppShift) << 16;
packedDataLimits = PM_PACKEDDATALIMITS_OFFSET(offset) |
PM_PACKEDDATALIMITS_XSTART(rDest.right) |
PM_PACKEDDATALIMITS_XEND(rDest.left);
}
else
{
startXDom = rDest.right << 16;
startXSub = rDest.left << 16;
}
startY = (rDest.bottom - 1) << 16;
dy = (DWORD)((-1) << 16);
}
ULONG count = rDest.bottom - rDest.top;
InputBufferReserve(ppdev, 18, &pBuffer);
pBuffer[0] = __Permedia2TagFBSourceOffset;
pBuffer[1] = sourceOffset;
pBuffer[2] = __Permedia2TagFBReadMode;
pBuffer[3] = readMode;
pBuffer[4] = __Permedia2TagFBWriteConfig;
pBuffer[5] = writeConfig;
pBuffer[6] = __Permedia2TagStartXDom;
pBuffer[7] = startXDom;
pBuffer[8] = __Permedia2TagStartXSub;
pBuffer[9] = startXSub;
#if 0
if(bEnablePacked)
{
pBuffer[0] = __Permedia2TagPackedDataLimits;
pBuffer[1] = packedDataLimits;
}
#endif
pBuffer[10] = __Permedia2TagStartY;
pBuffer[11] = startY;
pBuffer[12] = __Permedia2TagdY;
pBuffer[13] = dy;
pBuffer[14] = __Permedia2TagCount;
pBuffer[15] = count;
pBuffer[16] = __Permedia2TagRender;
pBuffer[17] = renderBits;
pBuffer += 18;
InputBufferCommit(ppdev, pBuffer);
prcl++;
}
InputBufferReserve(ppdev, 2, &pBuffer);
pBuffer[0] = __Permedia2TagdY;
pBuffer[1] = INTtoFIXED(1);
pBuffer += 2;
InputBufferCommit(ppdev, pBuffer);
}// vCopyBlt()
//-----------------------------------------------------------------------------
//
// VOID vCopyBltNative(GFNPB* ppb)
//
// Does a screen-to-screen copy blt of a list of rectangles.
//
// Note: The difference between this function and vCopyBlt() is that this
// function will be called only when the source and dest has the same pitch
// size. The reason is that we are using the Permedia2 packed data feature to
// do a 32 bits copy. Unfortunately when the source and dest has the different
// pitch, the hardware has some problems to implement it right. So in
// vCopyBlt(), we have to disable PackedData copy which slows down a lot
//
// Argumentes needed from function block (GFNPB)
// ppdev-------PPDev
// psurfSrc----Source surface
// psurfDst----Destination surface
// pRects------Pointer to a list of rectangles information which needed to be
// filled
// lNumRects---Number of rectangles to fill
// prclDst-----Points to a RECTL structure that defines the rectangular area
// to be modified
// pptlSrc-----Original unclipped source point
//
//-----------------------------------------------------------------------------
VOID
vCopyBltNative(GFNPB* ppb)
{
PDev* ppdev = ppb->ppdev;
Surf* psurfDst = ppb->psurfDst;
Surf* psurfSrc = ppb->psurfSrc;
RECTL* prcl = ppb->pRects;
RECTL* prclDst = ppb->prclDst;
POINTL* pptlSrc = ppb->pptlSrc;
LONG lNumRects = ppb->lNumRects;
LONG lSourceOffset;
LONG lWindowOffset;
DWORD dwOffset;
ULONG ulLogicOP = ulRop2ToLogicop(ppb->ulRop4 & 0xf);
ULONG ulPitch = psurfDst->ulPixDelta;
DBG_GDI((6, "vCopyBltNative called, ulPitch=%d", ulPitch));
lWindowOffset = (LONG)(psurfSrc->ulPixOffset - psurfDst->ulPixOffset);
//
// Setup loop invariant state
//
ULONG* pBuffer;
InputBufferReserve(ppdev, 4, &pBuffer);
pBuffer[0] = __Permedia2TagLogicalOpMode;
pBuffer[1] = P2_ENABLED_LOGICALOP(ulLogicOP);
pBuffer[2] = __Permedia2TagFBWindowBase;
pBuffer[3] = psurfDst->ulPixOffset;
pBuffer += 4;
InputBufferCommit(ppdev, pBuffer);
while( lNumRects-- )
{
RECTL rDest;
RECTL rSrc;
rDest = *prcl;
rSrc.left = pptlSrc->x + (rDest.left - prclDst->left);
rSrc.top = pptlSrc->y + (rDest.top - prclDst->top);
rSrc.right = rSrc.left + (rDest.right - rDest.left);
rSrc.bottom = rSrc.top + (rDest.bottom - rDest.top);
if ( rSrc.top < 0 )
{
rDest.top -= rSrc.top;
rSrc.top = 0;
}
if ( rSrc.left < 0 )
{
rDest.left -= rSrc.left;
rSrc.left = 0;
}
dwOffset = (((rDest.left & ppdev->dwBppMask)
- (rSrc.left & ppdev->dwBppMask)) & 7);
lSourceOffset = lWindowOffset
+ ( (rSrc.top - rDest.top) * ulPitch )
+ ( rSrc.left & ~(ppdev->dwBppMask) )
- ( rDest.left & ~(ppdev->dwBppMask) );
//
// Render the rectangle
//
ULONG ulStartXDom;
ULONG ulStartXSub;
ULONG ulPackedDataLimits;
ULONG ulStartY;
ULONG ulDY;
DBG_GDI((6, "lSourceOffset=%d", lSourceOffset));
if ( lSourceOffset >= 0 )
{
//
// Use left to right and top to bottom
//
ulStartXDom = (rDest.left >> ppdev->bBppShift) << 16;
ulStartXSub = ((rDest.right >> ppdev->bBppShift)
+ ppdev->dwBppMask) << 16;
ulPackedDataLimits = PM_PACKEDDATALIMITS_OFFSET(dwOffset)
| (rDest.left << 16)
| (rDest.right);
ulStartY = rDest.top << 16;
ulDY = 1 << 16;
}// if ( lSourceOffset >= 0 )
else
{
//
// Use right to left and bottom to top
//
ulStartXDom = (((rDest.right) >> ppdev->bBppShift)
+ ppdev->dwBppMask) << 16;
ulStartXSub = (rDest.left >> ppdev->bBppShift) << 16;
ulPackedDataLimits = PM_PACKEDDATALIMITS_OFFSET(dwOffset)
| (rDest.right << 16)
| (rDest.left);
ulStartY = (rDest.bottom - 1) << 16;
ulDY = (DWORD)((-1) << 16);
}// if ( lSourceOffset < 0 )
InputBufferReserve(ppdev, 18, &pBuffer);
pBuffer[0] = __Permedia2TagFBSourceOffset;
pBuffer[1] = lSourceOffset;
pBuffer[2] = __Permedia2TagFBReadMode;
pBuffer[3] = PM_FBREADMODE_PARTIAL(psurfSrc->ulPackedPP)
| PM_FBREADMODE_READSOURCE(__PERMEDIA_ENABLE)
| PM_FBREADMODE_RELATIVEOFFSET(dwOffset)
| PM_FBREADMODE_PACKEDDATA(__PERMEDIA_ENABLE)
| LogicopReadDest[ulLogicOP];
pBuffer[4] = __Permedia2TagPackedDataLimits;
pBuffer[5] = ulPackedDataLimits;
pBuffer[6] = __Permedia2TagStartXDom;
pBuffer[7] = ulStartXDom;
pBuffer[8] = __Permedia2TagStartXSub;
pBuffer[9] = ulStartXSub;
pBuffer[10] = __Permedia2TagStartY;
pBuffer[11] = ulStartY;
pBuffer[12] = __Permedia2TagdY;
pBuffer[13] = ulDY;
pBuffer[14] = __Permedia2TagCount;
pBuffer[15] = rDest.bottom - rDest.top;
pBuffer[16] = __Permedia2TagRender;
pBuffer[17] = __RENDER_TRAPEZOID_PRIMITIVE;
pBuffer += 18;
InputBufferCommit(ppdev, pBuffer);
prcl++;
}// while( lNumRects-- )
//
// Restore dY register value
//
InputBufferReserve(ppdev, 2, &pBuffer);
pBuffer[0] = __Permedia2TagdY;
pBuffer[1] = INTtoFIXED(1);
pBuffer += 2;
InputBufferCommit(ppdev, pBuffer);
}// vCopyBltNative()
//-----------------------------------------------------------------------------
//
// VOID vRop2Blt
//
// Does a screen-to-screen blt of a list of rectangles.
//
// Argumentes needed from function block (GFNPB)
// ppdev-------PPDev
// psurfSrc----Source surface
// psurfDst----Destination surface
// pRects------Pointer to a list of rectangles information which needed to be
// filled
// lNumRects---Number of rectangles to fill
// prclDst-----Points to a RECTL structure that defines the rectangular area
// to be modified
// pptlSrc-----Original unclipped source point
// usRop4------Rop4
//
//-----------------------------------------------------------------------------
VOID
vRop2Blt(GFNPB * ppb)
{
PDev* ppdev = ppb->ppdev;
Surf* psurfSrc = ppb->psurfSrc;
Surf* psurfDst = ppb->psurfDst;
RECTL* prcl = ppb->pRects;
LONG c = ppb->lNumRects;
RECTL* prclDst = ppb->prclDst;
POINTL* pptlSrc = ppb->pptlSrc;
ULONG ulLogicOP = ulRop2ToLogicop(ppb->ulRop4 & 0xf);
ULONG* pBuffer;
// PERMEDIA_DECL_VARS;
// PERMEDIA_DECL_INIT;
ASSERTDD(psurfSrc != psurfDst, "vRop2Blt: unexpected psurfSrc == psurfDst");
InputBufferReserve(ppdev, 32, &pBuffer);
pBuffer[0] = __Permedia2TagFBWindowBase;
pBuffer[1] = psurfDst->ulPixOffset;
pBuffer[2] = __Permedia2TagLogicalOpMode;
pBuffer[3] = P2_ENABLED_LOGICALOP(ulLogicOP);
pBuffer[4] = __Permedia2TagFBReadMode;
pBuffer[5] = PM_FBREADMODE_PARTIAL(psurfDst->ulPackedPP)
| LogicopReadDest[ulLogicOP];
pBuffer[6] = __Permedia2TagFBWriteConfig;
pBuffer[7] = PM_FBREADMODE_PARTIAL(psurfDst->ulPackedPP)
| LogicopReadDest[ulLogicOP];
pBuffer[8] = __Permedia2TagDitherMode;
pBuffer[9] = (COLOR_MODE << PM_DITHERMODE_COLORORDER) |
(ppdev->ulPermFormat << PM_DITHERMODE_COLORFORMAT) |
(ppdev->ulPermFormatEx << PM_DITHERMODE_COLORFORMATEXTENSION) |
(1 << PM_DITHERMODE_ENABLE);
pBuffer[10] = __Permedia2TagTextureAddressMode;
pBuffer[11] = (1 << PM_TEXADDRESSMODE_ENABLE);
pBuffer[12] = __Permedia2TagTextureColorMode;
pBuffer[13] = (1 << PM_TEXCOLORMODE_ENABLE) |
(0 << 4) | // RGB
(3 << 1); // Copy
pBuffer[14] = __Permedia2TagTextureReadMode;
pBuffer[15] = PM_TEXREADMODE_ENABLE(__PERMEDIA_ENABLE) |
PM_TEXREADMODE_WIDTH(11) |
PM_TEXREADMODE_HEIGHT(11);
pBuffer[16] = __Permedia2TagTextureDataFormat;
pBuffer[17] = (ppdev->ulPermFormat << PM_TEXDATAFORMAT_FORMAT) |
(ppdev->ulPermFormatEx << PM_TEXDATAFORMAT_FORMATEXTENSION) |
(COLOR_MODE << PM_TEXDATAFORMAT_COLORORDER);
pBuffer[18] = __Permedia2TagTextureMapFormat;
pBuffer[19] = (psurfSrc->ulPackedPP) |
(ppdev->cPelSize << PM_TEXMAPFORMAT_TEXELSIZE);
pBuffer[20] = __Permedia2TagSStart;
pBuffer[21] = 0;
pBuffer[22] = __Permedia2TagTStart;
pBuffer[23] = 0;
pBuffer[24] = __Permedia2TagdSdx;
pBuffer[25] = 1 << 20;
pBuffer[26] = __Permedia2TagdSdyDom;
pBuffer[27] = 0;
pBuffer[28] = __Permedia2TagdTdx;
pBuffer[29] = 0;
pBuffer[30] = __Permedia2TagdTdyDom;
pBuffer[31] = 1 << 20;
pBuffer += 32;
InputBufferCommit(ppdev, pBuffer);
while(c--) {
// Render the rectangle
ULONG ulSrcOffset = psurfSrc->ulPixOffset
+ pptlSrc->x + (prcl->left - prclDst->left)
+ (pptlSrc->y + (prcl->top - prclDst->top))
* psurfSrc->ulPixDelta;
InputBufferReserve(ppdev, 12, &pBuffer);
pBuffer[0] = __Permedia2TagTextureBaseAddress;
pBuffer[1] = ulSrcOffset;
pBuffer[2] = __Permedia2TagStartXDom;
pBuffer[3] = prcl->left << 16;
pBuffer[4] = __Permedia2TagStartXSub;
pBuffer[5] = prcl->right << 16;
pBuffer[6] = __Permedia2TagStartY;
pBuffer[7] = prcl->top << 16;
pBuffer[8] = __Permedia2TagCount;
pBuffer[9] = prcl->bottom - prcl->top;
pBuffer[10] = __Permedia2TagRender;
pBuffer[11] = __RENDER_TRAPEZOID_PRIMITIVE
| __RENDER_TEXTURED_PRIMITIVE;
pBuffer += 12;
InputBufferCommit(ppdev, pBuffer);
prcl++;
}
// Restore default state
InputBufferReserve(ppdev, 8, &pBuffer);
pBuffer[0] = __Permedia2TagDitherMode;
pBuffer[1] = 0;
pBuffer[2] = __Permedia2TagTextureAddressMode;
pBuffer[3] = __PERMEDIA_DISABLE;
pBuffer[4] = __Permedia2TagTextureColorMode;
pBuffer[5] = __PERMEDIA_DISABLE;
pBuffer[6] = __Permedia2TagTextureReadMode;
pBuffer[7] = __PERMEDIA_DISABLE;
pBuffer += 8;
InputBufferCommit(ppdev, pBuffer);
}