diff options
Diffstat (limited to 'src/amd_gx_shadow.c')
-rw-r--r-- | src/amd_gx_shadow.c | 423 |
1 files changed, 423 insertions, 0 deletions
diff --git a/src/amd_gx_shadow.c b/src/amd_gx_shadow.c new file mode 100644 index 0000000..feba8aa --- /dev/null +++ b/src/amd_gx_shadow.c @@ -0,0 +1,423 @@ +/* Copyright (c) 2003-2005 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Neither the name of the Advanced Micro Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * */ + +/* + * File Contents: Direct graphics display routines are implemented and + * graphics rendering are all done in memory. + * + * Project: Geode Xfree Frame buffer device driver. + */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86_ansic.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "amd.h" +#include "shadowfb.h" +#include "servermd.h" + +#define CLIP(sip,bp,u1,v1,u2,v2) \ + u1 = bp->x1; v1 = bp->y1; \ + u2 = bp->x2; v2 = bp->y2; \ + if ( u1 < 0 ) \ + u1 = 0; \ + if ( v1 < 0 ) \ + v1 = 0; \ + if ( u1 > sip->virtualX ) \ + u1 = sip->virtualX; \ + if ( v1 > sip->virtualY ) \ + v1 = sip->virtualY; \ + if ( u2 < 0 ) \ + u2 = 0; \ + if ( v2 < 0 ) \ + v2 = 0; \ + if ( u2 > sip->virtualX ) \ + u2 = sip->virtualX; \ + if ( v2 > sip->virtualY ) \ + v2 = sip->virtualY; + +void GXAccelSync(ScrnInfoPtr pScrni); + +void +GXRotation0(int x, int y, int w, int h, int *newX, int *newY) +{ + *newX = x; + *newY = y; +} + +void +GXRotation1(int x, int y, int w, int h, int *newX, int *newY) +{ + *newX = (h - 1) - y; + *newY = x; +} + +void +GXRotation2(int x, int y, int w, int h, int *newX, int *newY) +{ + *newX = (w - 1) - x; + *newY = (h - 1) - y; +} + +void +GXRotation3(int x, int y, int w, int h, int *newX, int *newY) +{ + *newY = (w - 1) - x; + *newX = y; +} + +void +GXRBltXlat0(int x, int y, int w, int h, int *newX, int *newY) +{ + *newX = x; + *newY = y; +} + +void +GXRBltXlat1(int x, int y, int w, int h, int *newX, int *newY) +{ + *newX = x - (h - 1); + *newY = y; +} + +void +GXRBltXlat2(int x, int y, int w, int h, int *newX, int *newY) +{ + *newX = x - (w - 1); + *newY = y - (h - 1); +} + +void +GXRBltXlat3(int x, int y, int w, int h, int *newX, int *newY) +{ + *newX = x; + *newY = y - (w - 1); +} + +/*---------------------------------------------------------------------------- + * GXPointerMoved. + * + * Description :This function moves one screen memory from one area to other. + * + * Parameters. + * index :Pointer to screen index. + * x :Specifies the new x co-ordinates of new area. + * y :Specifies the new y co-ordinates of new area. + * Returns :none + * + * Comments :none + * + *---------------------------------------------------------------------------- + */ +void +GXPointerMoved(int index, int x, int y) +{ + ScrnInfoPtr pScrni = xf86Screens[index]; + GeodeRec *pGeode = GEODEPTR(pScrni); + Bool frameChanged = FALSE; + + if (x < 0) + x = 0; + else if (x >= pScrni->virtualX) + x = pScrni->virtualX - 1; + + if (y < 0) + y = 0; + else if (y >= pScrni->virtualY) + y = pScrni->virtualY - 1; + + if (pScrni->frameX0 > x) { + pScrni->frameX0 = x; + pScrni->frameX1 = x + pGeode->HDisplay - 1; + frameChanged = TRUE; + } + + if (pScrni->frameX1 < x) { + pScrni->frameX1 = x + 1; + pScrni->frameX0 = x - pGeode->HDisplay + 1; + frameChanged = TRUE; + } + + if (pScrni->frameY0 > y) { + pScrni->frameY0 = y; + pScrni->frameY1 = y + pGeode->VDisplay - 1; + frameChanged = TRUE; + } + + if (pScrni->frameY1 < y) { + pScrni->frameY1 = y; + pScrni->frameY0 = y - pGeode->VDisplay + 1; + frameChanged = TRUE; + } + + if (frameChanged && pScrni->AdjustFrame != NULL) + pScrni->AdjustFrame(pScrni->scrnIndex, pScrni->frameX0, + pScrni->frameY0, 0); +} + +void +GXRefreshArea_Cpy(ScrnInfoPtr pScrni, int num, BoxPtr pbox) +{ + GeodeRec *pGeode = GEODEPTR(pScrni); + int x1, y1, x2, y2, width, height; + unsigned long src, dst; + int Bpp = pScrni->bitsPerPixel >> 3; + + gfx_set_raster_operation(0xcc); /* copy dst=src */ + for (; --num >= 0; ++pbox) { + CLIP(pScrni, pbox, x1, y1, x2, y2); + if ((width = x2 - x1) <= 0 || (height = y2 - y1) <= 0) + continue; + + src = y1 * pGeode->ShadowPitch + x1 * Bpp; + dst = pGeode->FBOffset + y1 * pGeode->Pitch + x1 * Bpp; + gfx2_set_destination_stride(pGeode->Pitch); + gfx2_color_bitmap_to_screen_blt(0, 0, dst, width, height, + pGeode->ShadowPtr + src, pGeode->ShadowPitch); + } +} + +/*---------------------------------------------------------------------------- + * GXRefreshArea8. + * + * Description :This function copies the memory to be displayed from the + * shadow pointer by 8bpp. + * Parameters. + * pScrni :Pointer to ScrnInfo structure. + * num :Specifies the num of squarebox area to be displayed. + * pbox :Points to square of memory to be displayed. + * + * Returns :none + * + * Comments :none + * + *---------------------------------------------------------------------------- + */ +void +GXRefreshArea0_Cpu(ScrnInfoPtr pScrni, int num, BoxPtr pbox) +{ + GeodeRec *pGeode = GEODEPTR(pScrni); + int width, height, x1, y1, x2, y2; + unsigned char *src, *dst; + int Bpp = pScrni->bitsPerPixel >> 3; + + GXAccelSync(pScrni); + for (; --num >= 0; ++pbox) { + CLIP(pScrni, pbox, x1, y1, x2, y2); + if ((width = x2 - x1) <= 0 || (height = y2 - y1) <= 0) + continue; + + src = pGeode->ShadowPtr + y1 * pGeode->ShadowPitch + x1 * Bpp; + dst = + pGeode->FBBase + pGeode->FBOffset + y1 * pGeode->Pitch + x1 * Bpp; + width *= Bpp; + while (--height >= 0) { + memcpy(dst, src, width); + dst += pGeode->Pitch; + src += pGeode->ShadowPitch; + } + } +} + +#define RefreshArea1_Cpu(nm,typ) \ +void GXRefreshArea1_Cpu##nm(ScrnInfoPtr pScrni, int num, BoxPtr pbox) \ +{ \ + GeodeRec *pGeode = GEODEPTR(pScrni); \ + int l, width, height, x1, y1, x2, y2, newX, newY; \ + unsigned long src, dst, dp; \ + typ *sp; \ + GXAccelSync(pScrni); \ + for( ; --num>=0; ++pbox ) { \ + CLIP(pScrni,pbox,x1,y1,x2,y2); \ + if( (width=x2-x1) <=0 || (height=y2-y1) <= 0 ) \ + continue; \ + src = y1*pGeode->ShadowPitch + x1*sizeof(typ); \ + newX = pScrni->virtualY-1 - y1; \ + newY = x1; \ + dst = pGeode->FBOffset + newY*pGeode->Pitch + newX*sizeof(typ); \ + while( --height >= 0 ) { \ + sp = (typ *)(pGeode->ShadowPtr + src); \ + dp = (unsigned long)(pGeode->FBBase + dst); \ + for( l=width; --l>=0; ) { \ + *(typ *)dp = *sp++; \ + dp += pGeode->Pitch; \ + } \ + dst -= sizeof(typ); \ + src += pGeode->ShadowPitch; \ + } \ + } \ +} + +RefreshArea1_Cpu(8, unsigned char) +RefreshArea1_Cpu(16, unsigned short) +RefreshArea1_Cpu(32, unsigned int) +#define RefreshArea2_Cpu(nm,typ) \ +void GXRefreshArea2_Cpu##nm(ScrnInfoPtr pScrni, int num, BoxPtr pbox) \ +{ \ + GeodeRec *pGeode = GEODEPTR(pScrni); \ + int l, width, height, x1, y1, x2, y2, newX, newY; \ + unsigned long src, dst, dp; \ + typ *sp; \ + GXAccelSync(pScrni); \ + for( ; --num>=0; ++pbox ) { \ + CLIP(pScrni,pbox,x1,y1,x2,y2); \ + if( (width=x2-x1) <=0 || (height=y2-y1) <= 0 ) \ + continue; \ + src = y1*pGeode->ShadowPitch + x1*sizeof(typ); \ + newX = pScrni->virtualX-1 - x1; \ + newY = pScrni->virtualY-1 - y1; \ + dst = pGeode->FBOffset + newY*pGeode->Pitch + newX*sizeof(typ); \ + while( --height >= 0 ) { \ + sp = (typ *)(pGeode->ShadowPtr + src); \ + dp = (unsigned long)(pGeode->FBBase + dst); \ + for( l=width; --l>=0; ) { \ + *(typ *)dp = *sp++; \ + dp -= sizeof(typ); \ + } \ + src += pGeode->ShadowPitch; \ + dst -= pGeode->Pitch; \ + } \ + } \ +} +RefreshArea2_Cpu(8, unsigned char) +RefreshArea2_Cpu(16, unsigned short) +RefreshArea2_Cpu(32, unsigned int) +#define RefreshArea3_Cpu(nm,typ) \ +void GXRefreshArea3_Cpu##nm(ScrnInfoPtr pScrni, int num, BoxPtr pbox) \ +{ \ + GeodeRec *pGeode = GEODEPTR(pScrni); \ + int l, width, height, x1, y1, x2, y2, newX, newY; \ + unsigned long src, dst, dp; \ + typ *sp; \ + GXAccelSync(pScrni); \ + for( ; --num>=0; ++pbox ) { \ + CLIP(pScrni,pbox,x1,y1,x2,y2); \ + if( (width=x2-x1) <=0 || (height=y2-y1) <= 0 ) \ + continue; \ + src = y1*pGeode->ShadowPitch + x1*sizeof(typ); \ + newX = y1; \ + newY = pScrni->virtualX-1 - x1; \ + dst = pGeode->FBOffset + newY*pGeode->Pitch + newX*sizeof(typ); \ + while( --height >= 0 ) { \ + sp = (typ *)(pGeode->ShadowPtr + src); \ + dp = (unsigned long)(pGeode->FBBase + dst); \ + for( l=width; --l>=0; ) { \ + *(typ *)dp = *sp++; \ + dp -= pGeode->Pitch; \ + } \ + dst += sizeof(typ); \ + src += pGeode->ShadowPitch; \ + } \ + } \ +} +RefreshArea3_Cpu(8, unsigned char) +RefreshArea3_Cpu(16, unsigned short) +RefreshArea3_Cpu(32, unsigned int) + + void GXRotationInit(ScrnInfoPtr pScrni) +{ + GeodeRec *pGeode = GEODEPTR(pScrni); + + switch (pGeode->Rotate) { + case 1: + pGeode->Rotation = GXRotation1; + pGeode->RBltXlat = GXRBltXlat1; + break; + case 2: + pGeode->Rotation = GXRotation2; + pGeode->RBltXlat = GXRBltXlat2; + break; + case 3: + pGeode->Rotation = GXRotation3; + pGeode->RBltXlat = GXRBltXlat3; + break; + default: + pGeode->Rotation = GXRotation0; + pGeode->RBltXlat = GXRBltXlat0; + break; + } +} + +void +GXShadowFBInit(ScreenPtr pScrn, GeodeRec *pGeode, int bytpp) +{ + RefreshAreaFuncPtr refreshArea; + + switch (bytpp) { + case 2: + switch (pGeode->Rotate) { + case 1: + refreshArea = GXRefreshArea1_Cpu16; + break; + case 2: + refreshArea = GXRefreshArea2_Cpu16; + break; + case 3: + refreshArea = GXRefreshArea3_Cpu16; + break; + default: + refreshArea = GXRefreshArea0_Cpu; + break; + } + break; + case 4: + switch (pGeode->Rotate) { + case 1: + refreshArea = GXRefreshArea1_Cpu32; + break; + case 2: + refreshArea = GXRefreshArea2_Cpu32; + break; + case 3: + refreshArea = GXRefreshArea3_Cpu32; + break; + default: + refreshArea = GXRefreshArea0_Cpu; + break; + } + break; + default: + switch (pGeode->Rotate) { + case 1: + refreshArea = GXRefreshArea1_Cpu8; + break; + case 2: + refreshArea = GXRefreshArea2_Cpu8; + break; + case 3: + refreshArea = GXRefreshArea3_Cpu8; + break; + default: + refreshArea = GXRefreshArea0_Cpu; + break; + } + break; + } + ShadowFBInit(pScrn, refreshArea); +} + +/* End of file */ |