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
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);
|
|
|
|
}
|
|
|