1f29dbc25Smrg/* Copyrightg (c) 2006 Advanced Micro Devices, Inc. 2f29dbc25Smrg * 3f29dbc25Smrg * Permission is hereby granted, free of charge, to any person obtaining a copy 4f29dbc25Smrg * of this software and associated documentation files (the "Software"), to 5f29dbc25Smrg * deal in the Software without restriction, including without limitation the 6f29dbc25Smrg * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7f29dbc25Smrg * sell copies of the Software, and to permit persons to whom the Software is 8f29dbc25Smrg * furnished to do so, subject to the following conditions: 9f29dbc25Smrg * 10f29dbc25Smrg * The above copyright notice and this permission notice shall be included in 11f29dbc25Smrg * all copies or substantial portions of the Software. 12f29dbc25Smrg * 13f29dbc25Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14f29dbc25Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15f29dbc25Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16f29dbc25Smrg * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17f29dbc25Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18f29dbc25Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19f29dbc25Smrg * IN THE SOFTWARE. 20f29dbc25Smrg * 21f29dbc25Smrg * Neither the name of the Advanced Micro Devices, Inc. nor the names of its 22f29dbc25Smrg * contributors may be used to endorse or promote products derived from this 23f29dbc25Smrg * software without specific prior written permission. 24f29dbc25Smrg */ 25f29dbc25Smrg 26f29dbc25Smrg#ifdef HAVE_CONFIG_H 27f29dbc25Smrg#include "config.h" 28f29dbc25Smrg#endif 29f29dbc25Smrg 3000be8644Schristos#include "xorg-server.h" 3100be8644Schristos 32f29dbc25Smrg#include "xf86.h" 33f29dbc25Smrg#include "shadow.h" 34f29dbc25Smrg#include "geode.h" 35f29dbc25Smrg 36f29dbc25Smrgstatic void * 37f29dbc25SmrgGXWindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, 3804007ebaSmrg CARD32 *size, void *closure) 39f29dbc25Smrg{ 4004007ebaSmrg ScrnInfoPtr pScrni = xf86ScreenToScrn(pScreen); 41f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 42f29dbc25Smrg 43f29dbc25Smrg *size = pGeode->displayPitch; 44f29dbc25Smrg 45f29dbc25Smrg return (pGeode->FBBase + pGeode->displayOffset) + 4604007ebaSmrg row * pGeode->displayPitch + offset; 47f29dbc25Smrg} 48f29dbc25Smrg 49f29dbc25Smrgstatic void 50f29dbc25SmrgGXUpdate(ScreenPtr pScreen, shadowBufPtr pBuf) 51f29dbc25Smrg{ 5204007ebaSmrg ScrnInfoPtr pScrni = xf86ScreenToScrn(pScreen); 53f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 54f29dbc25Smrg int rotate = pGeode->rotation; 55f29dbc25Smrg 56f29dbc25Smrg switch (rotate) { 57f29dbc25Smrg case RR_Rotate_90: 58f29dbc25Smrg 5904007ebaSmrg if (pScrni->bitsPerPixel == 8) 6004007ebaSmrg shadowUpdateRotate8_90(pScreen, pBuf); 6104007ebaSmrg else if (pScrni->bitsPerPixel == 16) 6204007ebaSmrg shadowUpdateRotate16_90(pScreen, pBuf); 6304007ebaSmrg else 6404007ebaSmrg shadowUpdateRotate32_90(pScreen, pBuf); 65f29dbc25Smrg 6604007ebaSmrg break; 67f29dbc25Smrg 68f29dbc25Smrg case RR_Rotate_180: 69f29dbc25Smrg 7004007ebaSmrg if (pScrni->bitsPerPixel == 8) 7104007ebaSmrg shadowUpdateRotate8_180(pScreen, pBuf); 7204007ebaSmrg else if (pScrni->bitsPerPixel == 16) 7304007ebaSmrg shadowUpdateRotate16_180(pScreen, pBuf); 7404007ebaSmrg else 7504007ebaSmrg shadowUpdateRotate32_180(pScreen, pBuf); 76f29dbc25Smrg 7704007ebaSmrg break; 78f29dbc25Smrg 79f29dbc25Smrg case RR_Rotate_270: 8004007ebaSmrg if (pScrni->bitsPerPixel == 8) 8104007ebaSmrg shadowUpdateRotate8_270(pScreen, pBuf); 8204007ebaSmrg else if (pScrni->bitsPerPixel == 16) 8304007ebaSmrg shadowUpdateRotate16_270(pScreen, pBuf); 8404007ebaSmrg else 8504007ebaSmrg shadowUpdateRotate32_270(pScreen, pBuf); 8604007ebaSmrg 8704007ebaSmrg break; 88f29dbc25Smrg } 89f29dbc25Smrg} 90f29dbc25Smrg 91f29dbc25SmrgBool 92f29dbc25SmrgGXRotate(ScrnInfoPtr pScrni, DisplayModePtr mode) 93f29dbc25Smrg{ 94f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 95f29dbc25Smrg Rotation curr = pGeode->rotation; 96f29dbc25Smrg unsigned int curdw = pScrni->displayWidth; 97f29dbc25Smrg PixmapPtr pPixmap; 98f29dbc25Smrg BOOL ret; 99f29dbc25Smrg 100f29dbc25Smrg pPixmap = pScrni->pScreen->GetScreenPixmap(pScrni->pScreen); 101f29dbc25Smrg pGeode->rotation = GXGetRotation(pScrni->pScreen); 102f29dbc25Smrg 103f29dbc25Smrg /* Leave if we have nothing to do */ 104f29dbc25Smrg 105f29dbc25Smrg if (pGeode->rotation == curr && pGeode->curMode == mode) { 10604007ebaSmrg return TRUE; 107f29dbc25Smrg } 108f29dbc25Smrg 109f29dbc25Smrg shadowRemove(pScrni->pScreen, NULL); 110f29dbc25Smrg 111f29dbc25Smrg switch (pGeode->rotation) { 112f29dbc25Smrg case RR_Rotate_0: 11304007ebaSmrg ErrorF("Rotate to 0 degrees\n"); 11404007ebaSmrg pScrni->displayWidth = pGeode->displayWidth; 11504007ebaSmrg pGeode->Pitch = pGeode->displayPitch; 11604007ebaSmrg break; 117f29dbc25Smrg 118f29dbc25Smrg case RR_Rotate_90: 11904007ebaSmrg ErrorF("Rotate to 90 degrees\n"); 12004007ebaSmrg pScrni->displayWidth = pScrni->pScreen->width; 12104007ebaSmrg break; 122f29dbc25Smrg 123f29dbc25Smrg case RR_Rotate_180: 12404007ebaSmrg ErrorF("Rotate to 180 degrees\n"); 12504007ebaSmrg pScrni->displayWidth = pGeode->displayWidth; 12604007ebaSmrg break; 127f29dbc25Smrg 128f29dbc25Smrg case RR_Rotate_270: 12904007ebaSmrg ErrorF("Rotate to 270 degrees\n"); 13004007ebaSmrg pScrni->displayWidth = pScrni->pScreen->width; 13104007ebaSmrg break; 132f29dbc25Smrg } 133f29dbc25Smrg 134f29dbc25Smrg if (pGeode->rotation != RR_Rotate_0) { 135f29dbc25Smrg 13604007ebaSmrg ret = 13704007ebaSmrg shadowAdd(pScrni->pScreen, pPixmap, GXUpdate, GXWindowLinear, 13804007ebaSmrg pGeode->rotation, NULL); 139f29dbc25Smrg 14004007ebaSmrg if (!ret) { 14104007ebaSmrg ErrorF("shadowAdd failed\n"); 14204007ebaSmrg goto error; 14304007ebaSmrg } 144f29dbc25Smrg } 145f29dbc25Smrg 146f29dbc25Smrg if (pGeode->rotation == RR_Rotate_0) 14704007ebaSmrg pScrni->fbOffset = pGeode->displayOffset; 148f29dbc25Smrg else 14904007ebaSmrg pScrni->fbOffset = pGeode->shadowOffset; 150f29dbc25Smrg 151f29dbc25Smrg pScrni->pScreen->ModifyPixmapHeader(pPixmap, 15204007ebaSmrg pScrni->pScreen->width, 15304007ebaSmrg pScrni->pScreen->height, 15404007ebaSmrg pScrni->pScreen->rootDepth, 15504007ebaSmrg pScrni->bitsPerPixel, 15604007ebaSmrg PixmapBytePad(pScrni->displayWidth, 15704007ebaSmrg pScrni-> 15804007ebaSmrg pScreen->rootDepth), 15904007ebaSmrg (pointer) (pGeode->FBBase + 16004007ebaSmrg pScrni->fbOffset)); 161f29dbc25Smrg 162f29dbc25Smrg /* Don't use XAA pixmap cache or offscreen pixmaps when rotated */ 16304007ebaSmrg#if XF86XAA 164f29dbc25Smrg if (pGeode->AccelInfoRec) { 16504007ebaSmrg if (pGeode->rotation == RR_Rotate_0) { 16604007ebaSmrg pGeode->AccelInfoRec->Flags = 16704007ebaSmrg LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS | PIXMAP_CACHE; 16804007ebaSmrg pGeode->AccelInfoRec->UsingPixmapCache = TRUE; 16904007ebaSmrg pGeode->AccelInfoRec->maxOffPixWidth = 0; 17004007ebaSmrg pGeode->AccelInfoRec->maxOffPixHeight = 0; 17104007ebaSmrg } 17204007ebaSmrg else { 17304007ebaSmrg pGeode->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER; 17404007ebaSmrg pGeode->AccelInfoRec->UsingPixmapCache = FALSE; 17504007ebaSmrg pGeode->AccelInfoRec->maxOffPixWidth = 1; 17604007ebaSmrg pGeode->AccelInfoRec->maxOffPixHeight = 1; 17704007ebaSmrg } 178f29dbc25Smrg } 17904007ebaSmrg#endif 180f29dbc25Smrg 181f29dbc25Smrg return TRUE; 182f29dbc25Smrg 18304007ebaSmrg error: 184f29dbc25Smrg /* Restore the old rotation */ 185f29dbc25Smrg pScrni->displayWidth = curdw; 186f29dbc25Smrg 187f29dbc25Smrg if (curr & (RR_Rotate_0 | RR_Rotate_180)) { 18804007ebaSmrg pScrni->pScreen->width = pScrni->virtualX; 18904007ebaSmrg pScrni->pScreen->height = pScrni->virtualY; 19004007ebaSmrg } 19104007ebaSmrg else { 19204007ebaSmrg pScrni->pScreen->width = pScrni->virtualY; 19304007ebaSmrg pScrni->pScreen->height = pScrni->virtualX; 194f29dbc25Smrg } 195f29dbc25Smrg 196f29dbc25Smrg pGeode->rotation = curr; 197f29dbc25Smrg return FALSE; 198f29dbc25Smrg} 199