smi_exa.c revision 09885543
109885543Smrg/* 209885543SmrgCopyright (C) 2006 Dennis De Winter All Rights Reserved. 309885543SmrgCopyright (C) 2007 Alex Deucher All Rights Reserved. 409885543Smrg 509885543SmrgPermission is hereby granted, free of charge, to any person obtaining a copy of 609885543Smrgthis software and associated documentation files (the "Software"), to deal in 709885543Smrgthe Software without restriction, including without limitation the rights to 809885543Smrguse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 909885543Smrgof the Software, and to permit persons to whom the Software is furnished to do 1009885543Smrgso, subject to the following conditions: 1109885543Smrg 1209885543SmrgThe above copyright notice and this permission notice shall be included in all 1309885543Smrgcopies or substantial portions of the Software. 1409885543Smrg 1509885543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1609885543SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- 1709885543SmrgNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1809885543SmrgXFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 1909885543SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 2009885543SmrgWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2109885543Smrg 2209885543Smrg*/ 2309885543Smrg 2409885543Smrg#ifdef HAVE_CONFIG_H 2509885543Smrg#include "config.h" 2609885543Smrg#endif 2709885543Smrg 2809885543Smrg#include "smi.h" 2909885543Smrg 3009885543Smrg 3109885543Smrgstatic void 3209885543SmrgSMI_EXASync(ScreenPtr pScreen, int marker); 3309885543Smrg 3409885543Smrgstatic Bool 3509885543SmrgSMI_PrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, 3609885543Smrg int xdir, int ydir, int alu, Pixel planemask); 3709885543Smrg 3809885543Smrgstatic void 3909885543SmrgSMI_Copy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int width, int height); 4009885543Smrg 4109885543Smrgstatic void 4209885543SmrgSMI_DoneCopy(PixmapPtr pDstPixmap); 4309885543Smrg 4409885543Smrgstatic Bool 4509885543SmrgSMI_PrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg); 4609885543Smrg 4709885543Smrgstatic void 4809885543SmrgSMI_Solid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2); 4909885543Smrg 5009885543Smrgstatic void 5109885543SmrgSMI_DoneSolid(PixmapPtr pPixmap); 5209885543Smrg 5309885543SmrgBool 5409885543SmrgSMI_UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, int src_pitch); 5509885543Smrg 5609885543SmrgBool 5709885543SmrgSMI_DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst, int dst_pitch); 5809885543Smrg 5909885543SmrgBool 6009885543SmrgSMI_EXAInit(ScreenPtr pScreen) 6109885543Smrg{ 6209885543Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 6309885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 6409885543Smrg 6509885543Smrg ENTER_PROC("SMI_EXAInit"); 6609885543Smrg 6709885543Smrg if (!(pSmi->EXADriverPtr = exaDriverAlloc())) { 6809885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate EXADriverRec.\n"); 6909885543Smrg LEAVE_PROC("SMI_EXAInit"); 7009885543Smrg return FALSE; 7109885543Smrg } 7209885543Smrg 7309885543Smrg pSmi->EXADriverPtr->exa_major = 2; 7409885543Smrg pSmi->EXADriverPtr->exa_minor = 0; 7509885543Smrg 7609885543Smrg SMI_EngineReset(pScrn); 7709885543Smrg 7809885543Smrg /* Memory Manager */ 7909885543Smrg pSmi->EXADriverPtr->memoryBase = pSmi->FBBase + pSmi->FBOffset; 8009885543Smrg pSmi->EXADriverPtr->memorySize = pSmi->FBReserved - 1024; 8109885543Smrg pSmi->EXADriverPtr->offScreenBase = pSmi->width * pSmi->height * pSmi->Bpp + 1024; 8209885543Smrg 8309885543Smrg /* Flags */ 8409885543Smrg pSmi->EXADriverPtr->flags = EXA_TWO_BITBLT_DIRECTIONS; 8509885543Smrg if (pSmi->EXADriverPtr->memorySize > pSmi->EXADriverPtr->offScreenBase) { 8609885543Smrg /* Offscreen Pixmaps */ 8709885543Smrg pSmi->EXADriverPtr->flags |= EXA_OFFSCREEN_PIXMAPS; 8809885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 8909885543Smrg "EXA offscreen memory manager enabled.\n"); 9009885543Smrg } else { 9109885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 9209885543Smrg "Not enough video RAM for EXA offscreen memory manager.\n"); 9309885543Smrg } 9409885543Smrg 9509885543Smrg /* 12 bit coordinates */ 9609885543Smrg pSmi->EXADriverPtr->maxX = 4096; 9709885543Smrg pSmi->EXADriverPtr->maxY = 4096; 9809885543Smrg 9909885543Smrg pSmi->EXADriverPtr->pixmapPitchAlign = 16; 10009885543Smrg pSmi->EXADriverPtr->pixmapOffsetAlign = 8; 10109885543Smrg 10209885543Smrg /* Sync */ 10309885543Smrg pSmi->EXADriverPtr->WaitMarker = SMI_EXASync; 10409885543Smrg 10509885543Smrg /* Copy */ 10609885543Smrg pSmi->EXADriverPtr->PrepareCopy = SMI_PrepareCopy; 10709885543Smrg pSmi->EXADriverPtr->Copy = SMI_Copy; 10809885543Smrg pSmi->EXADriverPtr->DoneCopy = SMI_DoneCopy; 10909885543Smrg 11009885543Smrg /* Solid */ 11109885543Smrg pSmi->EXADriverPtr->PrepareSolid = SMI_PrepareSolid; 11209885543Smrg pSmi->EXADriverPtr->Solid = SMI_Solid; 11309885543Smrg pSmi->EXADriverPtr->DoneSolid = SMI_DoneSolid; 11409885543Smrg 11509885543Smrg /* DFS & UTS */ 11609885543Smrg#if 0 11709885543Smrg pSmi->EXADriverPtr->UploadToScreen = SMI_UploadToScreen; 11809885543Smrg pSmi->EXADriverPtr->DownloadFromScreen = SMI_DownloadFromScreen; 11909885543Smrg#endif 12009885543Smrg 12109885543Smrg if(!exaDriverInit(pScreen, pSmi->EXADriverPtr)) { 12209885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "exaDriverInit failed.\n"); 12309885543Smrg LEAVE_PROC("SMI_EXAInit"); 12409885543Smrg return FALSE; 12509885543Smrg } else { 12609885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EXA Acceleration enabled.\n"); 12709885543Smrg LEAVE_PROC("SMI_EXAInit"); 12809885543Smrg return TRUE; 12909885543Smrg } 13009885543Smrg} 13109885543Smrg 13209885543Smrgstatic void 13309885543SmrgSMI_EXASync(ScreenPtr pScreen, int marker) 13409885543Smrg{ 13509885543Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 13609885543Smrg SMIPtr pSmi = SMIPTR(xf86Screens[pScreen->myNum]); 13709885543Smrg 13809885543Smrg ENTER_PROC("SMI_EXASync"); 13909885543Smrg 14009885543Smrg WaitIdleEmpty(); 14109885543Smrg 14209885543Smrg LEAVE_PROC("SMI_EXASync"); 14309885543Smrg} 14409885543Smrg 14509885543Smrgstatic CARD32 14609885543SmrgSMI_DEDataFormat(PixmapPtr pPixmap) { 14709885543Smrg CARD32 DEDataFormat = 0; 14809885543Smrg 14909885543Smrg switch (pPixmap->drawable.bitsPerPixel) { 15009885543Smrg case 8: 15109885543Smrg DEDataFormat = 0x00000000; 15209885543Smrg break; 15309885543Smrg case 16: 15409885543Smrg DEDataFormat = 0x00100000; 15509885543Smrg break; 15609885543Smrg case 24: 15709885543Smrg DEDataFormat = 0x00300000; 15809885543Smrg break; 15909885543Smrg case 32: 16009885543Smrg DEDataFormat = 0x00200000; 16109885543Smrg break; 16209885543Smrg } 16309885543Smrg return DEDataFormat; 16409885543Smrg} 16509885543Smrg 16609885543Smrg/* ----------------------------------------------------- EXA Copy ---------------------------------------------- */ 16709885543Smrg 16809885543SmrgCARD8 SMI_BltRop[16] = /* table stolen from KAA */ 16909885543Smrg{ 17009885543Smrg /* GXclear */ 0x00, /* 0 */ 17109885543Smrg /* GXand */ 0x88, /* src AND dst */ 17209885543Smrg /* GXandReverse */ 0x44, /* src AND NOT dst */ 17309885543Smrg /* GXcopy */ 0xCC, /* src */ 17409885543Smrg /* GXandInverted*/ 0x22, /* NOT src AND dst */ 17509885543Smrg /* GXnoop */ 0xAA, /* dst */ 17609885543Smrg /* GXxor */ 0x66, /* src XOR dst */ 17709885543Smrg /* GXor */ 0xEE, /* src OR dst */ 17809885543Smrg /* GXnor */ 0x11, /* NOT src AND NOT dst */ 17909885543Smrg /* GXequiv */ 0x99, /* NOT src XOR dst */ 18009885543Smrg /* GXinvert */ 0x55, /* NOT dst */ 18109885543Smrg /* GXorReverse */ 0xDD, /* src OR NOT dst */ 18209885543Smrg /* GXcopyInverted*/ 0x33, /* NOT src */ 18309885543Smrg /* GXorInverted */ 0xBB, /* NOT src OR dst */ 18409885543Smrg /* GXnand */ 0x77, /* NOT src OR NOT dst */ 18509885543Smrg /* GXset */ 0xFF, /* 1 */ 18609885543Smrg}; 18709885543Smrg 18809885543Smrgstatic Bool 18909885543SmrgSMI_PrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, int ydir, 19009885543Smrg int alu, Pixel planemask) 19109885543Smrg{ 19209885543Smrg ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 19309885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 19409885543Smrg int src_pitch, dst_pitch; 19509885543Smrg unsigned long src_offset, dst_offset; 19609885543Smrg 19709885543Smrg ENTER_PROC("SMI_PrepareCopy"); 19809885543Smrg DEBUG((VERBLEV, "xdir=%d ydir=%d alu=%02X", xdir, ydir, alu)); 19909885543Smrg 20009885543Smrg /* Bit Mask not supported > 16 bpp */ 20109885543Smrg if ((pSrcPixmap->drawable.bitsPerPixel > 16) && 20209885543Smrg (!EXA_PM_IS_SOLID(&pSrcPixmap->drawable, planemask))) { 20309885543Smrg LEAVE_PROC("SMI_PrepareCopy"); 20409885543Smrg return FALSE; 20509885543Smrg } 20609885543Smrg 20709885543Smrg /* calculate pitch in pixel unit */ 20809885543Smrg src_pitch = exaGetPixmapPitch(pSrcPixmap) / (pSrcPixmap->drawable.bitsPerPixel >> 3); 20909885543Smrg dst_pitch = exaGetPixmapPitch(pDstPixmap) / (pDstPixmap->drawable.bitsPerPixel >> 3); 21009885543Smrg /* calculate offset in 8 byte (64 bit) unit */ 21109885543Smrg src_offset = exaGetPixmapOffset(pSrcPixmap) >> 3; 21209885543Smrg dst_offset = exaGetPixmapOffset(pDstPixmap) >> 3; 21309885543Smrg 21409885543Smrg pSmi->AccelCmd = SMI_BltRop[alu] 21509885543Smrg | SMI_BITBLT 21609885543Smrg | SMI_QUICK_START; 21709885543Smrg 21809885543Smrg if (xdir < 0 || (ydir < 0)) { 21909885543Smrg pSmi->AccelCmd |= SMI_RIGHT_TO_LEFT; 22009885543Smrg } 22109885543Smrg 22209885543Smrg WaitQueue(7); 22309885543Smrg /* Destination and Source Window Widths */ 22409885543Smrg WRITE_DPR(pSmi, 0x3C, (dst_pitch << 16) | (src_pitch & 0xFFFF)); 22509885543Smrg 22609885543Smrg if (pDstPixmap->drawable.bitsPerPixel == 24) { 22709885543Smrg src_pitch *= 3; 22809885543Smrg dst_pitch *= 3; 22909885543Smrg } 23009885543Smrg 23109885543Smrg /* Bit Mask (planemask) - 16 bit only */ 23209885543Smrg if (pSrcPixmap->drawable.bitsPerPixel == 16) { 23309885543Smrg WRITE_DPR(pSmi, 0x28, planemask | 0xFFFF0000); 23409885543Smrg } else { 23509885543Smrg WRITE_DPR(pSmi, 0x28, 0xFFFFFFFF); 23609885543Smrg } 23709885543Smrg 23809885543Smrg /* Destination and Source Row Pitch */ 23909885543Smrg WRITE_DPR(pSmi, 0x10, (dst_pitch << 16) | (src_pitch & 0xFFFF)); 24009885543Smrg /* Drawing engine data format */ 24109885543Smrg WRITE_DPR(pSmi, 0x1C, SMI_DEDataFormat(pDstPixmap)); 24209885543Smrg /* Destination and Source Base Address (offset) */ 24309885543Smrg WRITE_DPR(pSmi, 0x40, src_offset); 24409885543Smrg WRITE_DPR(pSmi, 0x44, dst_offset); 24509885543Smrg 24609885543Smrg WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd); 24709885543Smrg 24809885543Smrg LEAVE_PROC("SMI_PrepareCopy"); 24909885543Smrg return TRUE; 25009885543Smrg} 25109885543Smrg 25209885543Smrgstatic void 25309885543SmrgSMI_Copy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, 25409885543Smrg int dstY, int width, int height) 25509885543Smrg{ 25609885543Smrg ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 25709885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 25809885543Smrg 25909885543Smrg ENTER_PROC("SMI_Copy"); 26009885543Smrg DEBUG((VERBLEV, "srcX=%d srcY=%d dstX=%d dstY=%d width=%d height=%d\n", 26109885543Smrg srcX, srcY, dstX, dstY, width, height)); 26209885543Smrg 26309885543Smrg if (pSmi->AccelCmd & SMI_RIGHT_TO_LEFT) { 26409885543Smrg srcX += width - 1; 26509885543Smrg srcY += height - 1; 26609885543Smrg dstX += width - 1; 26709885543Smrg dstY += height - 1; 26809885543Smrg } 26909885543Smrg 27009885543Smrg if (pDstPixmap->drawable.bitsPerPixel == 24) { 27109885543Smrg srcX *= 3; 27209885543Smrg dstX *= 3; 27309885543Smrg width *= 3; 27409885543Smrg 27509885543Smrg if (pSmi->Chipset == SMI_LYNX) { 27609885543Smrg srcY *= 3; 27709885543Smrg dstY *= 3; 27809885543Smrg } 27909885543Smrg 28009885543Smrg if (pSmi->AccelCmd & SMI_RIGHT_TO_LEFT) { 28109885543Smrg srcX += 2; 28209885543Smrg dstX += 2; 28309885543Smrg } 28409885543Smrg } 28509885543Smrg 28609885543Smrg WaitQueue(3); 28709885543Smrg WRITE_DPR(pSmi, 0x00, (srcX << 16) + (srcY & 0xFFFF)); 28809885543Smrg WRITE_DPR(pSmi, 0x04, (dstX << 16) + (dstY & 0xFFFF)); 28909885543Smrg WRITE_DPR(pSmi, 0x08, (width << 16) + (height & 0xFFFF)); 29009885543Smrg 29109885543Smrg LEAVE_PROC("SMI_Copy"); 29209885543Smrg} 29309885543Smrg 29409885543Smrgstatic void 29509885543SmrgSMI_DoneCopy(PixmapPtr pDstPixmap) 29609885543Smrg{ 29709885543Smrg ENTER_PROC("SMI_DoneCopy"); 29809885543Smrg 29909885543Smrg LEAVE_PROC("SMI_DoneCopy"); 30009885543Smrg} 30109885543Smrg 30209885543Smrg/* ----------------------------------------------------- EXA Solid --------------------------------------------- */ 30309885543Smrg 30409885543SmrgCARD8 SMI_SolidRop[16] = /* table stolen from KAA */ 30509885543Smrg{ 30609885543Smrg /* GXclear */ 0x00, /* 0 */ 30709885543Smrg /* GXand */ 0xA0, /* src AND dst */ 30809885543Smrg /* GXandReverse */ 0x50, /* src AND NOT dst */ 30909885543Smrg /* GXcopy */ 0xF0, /* src */ 31009885543Smrg /* GXandInverted*/ 0x0A, /* NOT src AND dst */ 31109885543Smrg /* GXnoop */ 0xAA, /* dst */ 31209885543Smrg /* GXxor */ 0x5A, /* src XOR dst */ 31309885543Smrg /* GXor */ 0xFA, /* src OR dst */ 31409885543Smrg /* GXnor */ 0x05, /* NOT src AND NOT dst */ 31509885543Smrg /* GXequiv */ 0xA5, /* NOT src XOR dst */ 31609885543Smrg /* GXinvert */ 0x55, /* NOT dst */ 31709885543Smrg /* GXorReverse */ 0xF5, /* src OR NOT dst */ 31809885543Smrg /* GXcopyInverted*/ 0x0F, /* NOT src */ 31909885543Smrg /* GXorInverted */ 0xAF, /* NOT src OR dst */ 32009885543Smrg /* GXnand */ 0x5F, /* NOT src OR NOT dst */ 32109885543Smrg /* GXset */ 0xFF, /* 1 */ 32209885543Smrg}; 32309885543Smrg 32409885543Smrgstatic Bool 32509885543SmrgSMI_PrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) 32609885543Smrg{ 32709885543Smrg ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 32809885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 32909885543Smrg int dst_pitch; 33009885543Smrg unsigned long dst_offset; 33109885543Smrg 33209885543Smrg ENTER_PROC("SMI_PrepareSolid"); 33309885543Smrg DEBUG((VERBLEV, "alu=%02X\n", alu)); 33409885543Smrg 33509885543Smrg /* HW ignores alpha */ 33609885543Smrg if (pPixmap->drawable.bitsPerPixel == 32) 33709885543Smrg return FALSE; 33809885543Smrg 33909885543Smrg /* Bit Mask not supported > 16 bpp */ 34009885543Smrg if ((pPixmap->drawable.bitsPerPixel > 16) && 34109885543Smrg (!EXA_PM_IS_SOLID(&pPixmap->drawable, planemask))) { 34209885543Smrg LEAVE_PROC("SMI_PrepareCopy"); 34309885543Smrg return FALSE; 34409885543Smrg } 34509885543Smrg 34609885543Smrg /* calculate pitch in pixel unit */ 34709885543Smrg dst_pitch = exaGetPixmapPitch(pPixmap) / (pPixmap->drawable.bitsPerPixel >> 3); 34809885543Smrg /* calculate offset in 8 byte (64 bit) unit */ 34909885543Smrg dst_offset = exaGetPixmapOffset(pPixmap) >> 3; 35009885543Smrg 35109885543Smrg pSmi->AccelCmd = SMI_SolidRop[alu] 35209885543Smrg | SMI_BITBLT 35309885543Smrg | SMI_QUICK_START; 35409885543Smrg 35509885543Smrg WaitQueue(10); 35609885543Smrg /* Destination Window Width */ 35709885543Smrg WRITE_DPR(pSmi, 0x3C, (dst_pitch << 16) | (dst_pitch & 0xFFFF)); 35809885543Smrg 35909885543Smrg if (pPixmap->drawable.bitsPerPixel == 24) { 36009885543Smrg dst_pitch *= 3; 36109885543Smrg } 36209885543Smrg 36309885543Smrg /* Bit Mask (planemask) - 16 bit only */ 36409885543Smrg if (pPixmap->drawable.bitsPerPixel == 16) { 36509885543Smrg WRITE_DPR(pSmi, 0x28, planemask | 0xFFFF0000); 36609885543Smrg } else { 36709885543Smrg WRITE_DPR(pSmi, 0x28, 0xFFFFFFFF); 36809885543Smrg } 36909885543Smrg 37009885543Smrg /* Destination Row Pitch */ 37109885543Smrg WRITE_DPR(pSmi, 0x10, (dst_pitch << 16) | (dst_pitch & 0xFFFF)); 37209885543Smrg /* Drawing engine data format */ 37309885543Smrg WRITE_DPR(pSmi, 0x1C, SMI_DEDataFormat(pPixmap)); 37409885543Smrg /* Source and Destination Base Address (offset) */ 37509885543Smrg WRITE_DPR(pSmi, 0x40, dst_offset); 37609885543Smrg WRITE_DPR(pSmi, 0x44, dst_offset); 37709885543Smrg /* Foreground Color */ 37809885543Smrg WRITE_DPR(pSmi, 0x14, fg); 37909885543Smrg /* Mono Pattern High and Low */ 38009885543Smrg WRITE_DPR(pSmi, 0x34, 0xFFFFFFFF); 38109885543Smrg WRITE_DPR(pSmi, 0x38, 0xFFFFFFFF); 38209885543Smrg 38309885543Smrg WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd); 38409885543Smrg 38509885543Smrg LEAVE_PROC("SMI_PrepareSolid"); 38609885543Smrg return TRUE; 38709885543Smrg} 38809885543Smrg 38909885543Smrgstatic void 39009885543SmrgSMI_Solid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) 39109885543Smrg{ 39209885543Smrg ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 39309885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 39409885543Smrg int w, h; 39509885543Smrg 39609885543Smrg ENTER_PROC("SMI_Solid"); 39709885543Smrg DEBUG((VERBLEV, "x1=%d y1=%d x2=%d y2=%d\n", x1, y1, x2, y2)); 39809885543Smrg 39909885543Smrg w = (x2 - x1); 40009885543Smrg h = (y2 - y1); 40109885543Smrg 40209885543Smrg if (pPixmap->drawable.bitsPerPixel == 24) { 40309885543Smrg x1 *= 3; 40409885543Smrg w *= 3; 40509885543Smrg 40609885543Smrg if (pSmi->Chipset == SMI_LYNX) { 40709885543Smrg y1 *= 3; 40809885543Smrg } 40909885543Smrg } 41009885543Smrg 41109885543Smrg WaitQueue(2); 41209885543Smrg WRITE_DPR(pSmi, 0x04, (x1 << 16) | (y1 & 0xFFFF)); 41309885543Smrg WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF)); 41409885543Smrg 41509885543Smrg LEAVE_PROC("SMI_Solid"); 41609885543Smrg} 41709885543Smrg 41809885543Smrgstatic void 41909885543SmrgSMI_DoneSolid(PixmapPtr pPixmap) 42009885543Smrg{ 42109885543Smrg ENTER_PROC("SMI_DoneSolid"); 42209885543Smrg 42309885543Smrg LEAVE_PROC("SMI_DoneSolid"); 42409885543Smrg} 42509885543Smrg 42609885543Smrg/* --------------------------------------- EXA DFS & UTS ---------------------------------------- */ 42709885543Smrg 42809885543SmrgBool 42909885543SmrgSMI_DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, 43009885543Smrg char *dst, int dst_pitch) 43109885543Smrg{ 43209885543Smrg ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum]; 43309885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 43409885543Smrg 43509885543Smrg ENTER_PROC("SMI_DownloadFromScreen"); 43609885543Smrg DEBUG((VERBLEV, "x=%d y=%d w=%d h=%d dst=%d dst_pitch=%d\n", 43709885543Smrg x, y, w, h, dst, dst_pitch)); 43809885543Smrg 43909885543Smrg unsigned char *src = pSrc->devPrivate.ptr; 44009885543Smrg int src_pitch = exaGetPixmapPitch(pSrc); 44109885543Smrg 44209885543Smrg exaWaitSync(pSrc->drawable.pScreen); 44309885543Smrg 44409885543Smrg src += (y * src_pitch) + (x * pSmi->Bpp); 44509885543Smrg w *= pSmi->Bpp; 44609885543Smrg 44709885543Smrg while (h--) { 44809885543Smrg memcpy(dst, src, w); 44909885543Smrg src += src_pitch; 45009885543Smrg dst += dst_pitch; 45109885543Smrg } 45209885543Smrg 45309885543Smrg return TRUE; 45409885543Smrg LEAVE_PROC("SMI_DownloadFromScreen"); 45509885543Smrg} 45609885543Smrg 45709885543SmrgBool 45809885543SmrgSMI_UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, 45909885543Smrg char *src, int src_pitch) 46009885543Smrg{ 46109885543Smrg ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 46209885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 46309885543Smrg int i, j, dwords, Bpp, queue, dst_pitch; 46409885543Smrg CARD32 *srcp, *dataport; 46509885543Smrg unsigned long dst_offset; 46609885543Smrg 46709885543Smrg ENTER_PROC("SMI_UploadToScreen"); 46809885543Smrg DEBUG((VERBLEV, "x=%d y=%d w=%d h=%d src=%d src_pitch=%d\n", 46909885543Smrg x, y, w, h, src, src_pitch)); 47009885543Smrg 47109885543Smrg /* calculate pitch in pixel unit */ 47209885543Smrg dst_pitch = exaGetPixmapPitch(pDst) / (pDst->drawable.bitsPerPixel >> 3); 47309885543Smrg /* calculate offset in 8 byte (64 bit) unit */ 47409885543Smrg dst_offset = exaGetPixmapOffset(pDst) >> 3; 47509885543Smrg 47609885543Smrg Bpp = pDst->drawable.bitsPerPixel / 8; 47709885543Smrg dwords = (((w * Bpp) + 3) >> 2) * h; 47809885543Smrg 47909885543Smrg pSmi->AccelCmd = 0xCC /* GXcopy */ 48009885543Smrg | SMI_HOSTBLT_WRITE 48109885543Smrg | SMI_QUICK_START; 48209885543Smrg 48309885543Smrg 48409885543Smrg WaitQueue(1); 48509885543Smrg /* Destination Window Width */ 48609885543Smrg WRITE_DPR(pSmi, 0x3C, (dst_pitch << 16)); 48709885543Smrg 48809885543Smrg if (pDst->drawable.bitsPerPixel == 24) { 48909885543Smrg x *= 3; 49009885543Smrg w *= 3; 49109885543Smrg dst_pitch *= 3; 49209885543Smrg if (pSmi->Chipset == SMI_LYNX) { 49309885543Smrg y *= 3; 49409885543Smrg } 49509885543Smrg } 49609885543Smrg 49709885543Smrg WaitQueue(9); 49809885543Smrg /* Destination Row Pitch */ 49909885543Smrg WRITE_DPR(pSmi, 0x10, (dst_pitch << 16)); 50009885543Smrg /* Drawing engine data format */ 50109885543Smrg WRITE_DPR(pSmi, 0x1C, SMI_DEDataFormat(pDst)); 50209885543Smrg /* Destination Base Address (offset) */ 50309885543Smrg WRITE_DPR(pSmi, 0x44, dst_offset); 50409885543Smrg 50509885543Smrg /* set l/r clipping */ 50609885543Smrg WRITE_DPR(pSmi, 0x2C, (0xFFFF0000 | x | 0x2000)); 50709885543Smrg WRITE_DPR(pSmi, 0x30, (0xFFFF0000 | (x + w))); 50809885543Smrg 50909885543Smrg WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd); 51009885543Smrg WRITE_DPR(pSmi, 0x00, 0); 51109885543Smrg WRITE_DPR(pSmi, 0x04, (x << 16) | (y * 0xFFFF)); 51209885543Smrg WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF)); 51309885543Smrg 51409885543Smrg 51509885543Smrg srcp = (CARD32 *)src; 51609885543Smrg dataport = (CARD32 *)pSmi->DataPortBase; 51709885543Smrg queue = pSmi->DataPortSize; 51809885543Smrg while (dwords) { 51909885543Smrg if (queue < 4) { 52009885543Smrg /* XXX: check if the hw is ok with this */ 52109885543Smrg dataport = (CARD32 *)pSmi->DataPortBase; 52209885543Smrg queue = pSmi->DataPortSize; 52309885543Smrg } 52409885543Smrg memcpy(dataport, srcp, 4); 52509885543Smrg queue -= 4; 52609885543Smrg dwords--; 52709885543Smrg srcp++; 52809885543Smrg dataport++; 52909885543Smrg } 53009885543Smrg 53109885543Smrg WaitQueue(1); 53209885543Smrg /* disable clipping */ 53309885543Smrg WRITE_DPR(pSmi, 0x2C, 0); 53409885543Smrg 53509885543Smrg exaWaitSync(pDst->drawable.pScreen); 53609885543Smrg 53709885543Smrg LEAVE_PROC("SMI_UploadToScreen"); 53809885543Smrg 53909885543Smrg return TRUE; 54009885543Smrg} 54109885543Smrg 542