r128_exa.c revision 42a55b46
142a55b46Smrg/* 242a55b46Smrg * Copyright 2006 Joseph Garvin 342a55b46Smrg * Copyright 2012 Connor Behan 442a55b46Smrg * All Rights Reserved. 542a55b46Smrg * 642a55b46Smrg * Permission is hereby granted, free of charge, to any person obtaining a 742a55b46Smrg * copy of this software and associated documentation files (the "Software"), 842a55b46Smrg * to deal in the Software without restriction, including without limitation 942a55b46Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 1042a55b46Smrg * and/or sell copies of the Software, and to permit persons to whom the 1142a55b46Smrg * Software is furnished to do so, subject to the following conditions: 1242a55b46Smrg * 1342a55b46Smrg * The above copyright notice and this permission notice (including the next 1442a55b46Smrg * paragraph) shall be included in all copies or substantial portions of the 1542a55b46Smrg * Software. 1642a55b46Smrg * 1742a55b46Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1842a55b46Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1942a55b46Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 2042a55b46Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 2142a55b46Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 2242a55b46Smrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 2342a55b46Smrg * SOFTWARE. 2442a55b46Smrg * 2542a55b46Smrg * Authors: 2642a55b46Smrg * Joseph Garvin <joseph.h.garvin@gmail.com> 2742a55b46Smrg * Connor Behan <connor.behan@gmail.com> 2842a55b46Smrg * 2942a55b46Smrg */ 3042a55b46Smrg 3142a55b46Smrg#ifdef HAVE_CONFIG_H 3242a55b46Smrg#include "config.h" 3342a55b46Smrg#endif 3442a55b46Smrg 3542a55b46Smrg#include "r128.h" 3642a55b46Smrg#include "exa.h" 3742a55b46Smrg 3842a55b46Smrg#include "r128_reg.h" 3942a55b46Smrg 4042a55b46Smrg#include "xf86.h" 4142a55b46Smrg 4242a55b46Smrgstatic struct { 4342a55b46Smrg int rop; 4442a55b46Smrg int pattern; 4542a55b46Smrg} R128_ROP[] = { 4642a55b46Smrg { R128_ROP3_ZERO, R128_ROP3_ZERO }, /* GXclear */ 4742a55b46Smrg { R128_ROP3_DSa, R128_ROP3_DPa }, /* Gxand */ 4842a55b46Smrg { R128_ROP3_SDna, R128_ROP3_PDna }, /* GXandReverse */ 4942a55b46Smrg { R128_ROP3_S, R128_ROP3_P }, /* GXcopy */ 5042a55b46Smrg { R128_ROP3_DSna, R128_ROP3_DPna }, /* GXandInverted */ 5142a55b46Smrg { R128_ROP3_D, R128_ROP3_D }, /* GXnoop */ 5242a55b46Smrg { R128_ROP3_DSx, R128_ROP3_DPx }, /* GXxor */ 5342a55b46Smrg { R128_ROP3_DSo, R128_ROP3_DPo }, /* GXor */ 5442a55b46Smrg { R128_ROP3_DSon, R128_ROP3_DPon }, /* GXnor */ 5542a55b46Smrg { R128_ROP3_DSxn, R128_ROP3_PDxn }, /* GXequiv */ 5642a55b46Smrg { R128_ROP3_Dn, R128_ROP3_Dn }, /* GXinvert */ 5742a55b46Smrg { R128_ROP3_SDno, R128_ROP3_PDno }, /* GXorReverse */ 5842a55b46Smrg { R128_ROP3_Sn, R128_ROP3_Pn }, /* GXcopyInverted */ 5942a55b46Smrg { R128_ROP3_DSno, R128_ROP3_DPno }, /* GXorInverted */ 6042a55b46Smrg { R128_ROP3_DSan, R128_ROP3_DPan }, /* GXnand */ 6142a55b46Smrg { R128_ROP3_ONE, R128_ROP3_ONE } /* GXset */ 6242a55b46Smrg}; 6342a55b46Smrg 6442a55b46Smrg/* Assumes that depth 15 and 16 can be used as depth 16, which is okay since we 6542a55b46Smrg * require src and dest datatypes to be equal. 6642a55b46Smrg */ 6742a55b46SmrgBool R128GetDatatypeBpp(int bpp, uint32_t *type) 6842a55b46Smrg{ 6942a55b46Smrg switch (bpp) { 7042a55b46Smrg case 8: 7142a55b46Smrg *type = R128_DATATYPE_CI8; 7242a55b46Smrg return TRUE; 7342a55b46Smrg case 16: 7442a55b46Smrg *type = R128_DATATYPE_RGB565; 7542a55b46Smrg return TRUE; 7642a55b46Smrg case 24: 7742a55b46Smrg *type = R128_DATATYPE_RGB888; 7842a55b46Smrg return TRUE; 7942a55b46Smrg case 32: 8042a55b46Smrg *type = R128_DATATYPE_ARGB8888; 8142a55b46Smrg return TRUE; 8242a55b46Smrg default: 8342a55b46Smrg return FALSE; 8442a55b46Smrg } 8542a55b46Smrg} 8642a55b46Smrg 8742a55b46Smrgstatic Bool R128GetOffsetPitch(PixmapPtr pPix, int bpp, uint32_t *pitch_offset, 8842a55b46Smrg unsigned int offset, unsigned int pitch) 8942a55b46Smrg{ 9042a55b46Smrg ScreenPtr pScreen = pPix->drawable.pScreen; 9142a55b46Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 9242a55b46Smrg R128InfoPtr info = R128PTR(pScrn); 9342a55b46Smrg 9442a55b46Smrg if (pitch > 16320 || pitch % info->ExaDriver->pixmapPitchAlign != 0) { 9542a55b46Smrg R128TRACE(("Bad pitch 0x%08x\n", pitch)); 9642a55b46Smrg return FALSE; 9742a55b46Smrg } 9842a55b46Smrg 9942a55b46Smrg if (offset % info->ExaDriver->pixmapOffsetAlign != 0) { 10042a55b46Smrg R128TRACE(("Bad offset 0x%08x\n", offset)); 10142a55b46Smrg return FALSE; 10242a55b46Smrg } 10342a55b46Smrg 10442a55b46Smrg *pitch_offset = ((pitch / bpp) << 21) | (offset >> 5); 10542a55b46Smrg 10642a55b46Smrg return TRUE; 10742a55b46Smrg} 10842a55b46Smrg 10942a55b46SmrgBool R128GetPixmapOffsetPitch(PixmapPtr pPix, uint32_t *pitch_offset) 11042a55b46Smrg{ 11142a55b46Smrg uint32_t pitch, offset; 11242a55b46Smrg int bpp; 11342a55b46Smrg 11442a55b46Smrg bpp = pPix->drawable.bitsPerPixel; 11542a55b46Smrg if (bpp == 24) 11642a55b46Smrg bpp = 8; 11742a55b46Smrg 11842a55b46Smrg offset = exaGetPixmapOffset(pPix); 11942a55b46Smrg pitch = exaGetPixmapPitch(pPix); 12042a55b46Smrg 12142a55b46Smrg return R128GetOffsetPitch(pPix, bpp, pitch_offset, offset, pitch); 12242a55b46Smrg} 12342a55b46Smrg 12442a55b46Smrgstatic void Emit2DState(ScrnInfoPtr pScrn) 12542a55b46Smrg{ 12642a55b46Smrg R128InfoPtr info = R128PTR(pScrn); 12742a55b46Smrg int has_src = info->state_2d.src_pitch_offset; 12842a55b46Smrg unsigned char *R128MMIO = info->MMIO; 12942a55b46Smrg 13042a55b46Smrg R128WaitForFifo(pScrn, (has_src ? 10 : 9)); 13142a55b46Smrg 13242a55b46Smrg OUTREG(R128_DEFAULT_SC_BOTTOM_RIGHT, info->state_2d.default_sc_bottom_right); 13342a55b46Smrg OUTREG(R128_DP_GUI_MASTER_CNTL, info->state_2d.dp_gui_master_cntl); 13442a55b46Smrg OUTREG(R128_DP_BRUSH_FRGD_CLR, info->state_2d.dp_brush_frgd_clr); 13542a55b46Smrg OUTREG(R128_DP_BRUSH_BKGD_CLR, info->state_2d.dp_brush_bkgd_clr); 13642a55b46Smrg OUTREG(R128_DP_SRC_FRGD_CLR, info->state_2d.dp_src_frgd_clr); 13742a55b46Smrg OUTREG(R128_DP_SRC_BKGD_CLR, info->state_2d.dp_src_bkgd_clr); 13842a55b46Smrg OUTREG(R128_DP_WRITE_MASK, info->state_2d.dp_write_mask); 13942a55b46Smrg OUTREG(R128_DP_CNTL, info->state_2d.dp_cntl); 14042a55b46Smrg 14142a55b46Smrg OUTREG(R128_DST_PITCH_OFFSET, info->state_2d.dst_pitch_offset); 14242a55b46Smrg if (has_src) OUTREG(R128_SRC_PITCH_OFFSET, info->state_2d.src_pitch_offset); 14342a55b46Smrg} 14442a55b46Smrg 14542a55b46Smrg#ifdef R128DRI 14642a55b46Smrgstatic void EmitCCE2DState(ScrnInfoPtr pScrn) 14742a55b46Smrg{ 14842a55b46Smrg R128InfoPtr info = R128PTR(pScrn); 14942a55b46Smrg int has_src = info->state_2d.src_pitch_offset; 15042a55b46Smrg RING_LOCALS; 15142a55b46Smrg 15242a55b46Smrg R128CCE_REFRESH( pScrn, info ); 15342a55b46Smrg 15442a55b46Smrg BEGIN_RING( (has_src ? 20 : 18) ); 15542a55b46Smrg 15642a55b46Smrg OUT_RING_REG( R128_DEFAULT_SC_BOTTOM_RIGHT, info->state_2d.default_sc_bottom_right ); 15742a55b46Smrg OUT_RING_REG( R128_DP_GUI_MASTER_CNTL, info->state_2d.dp_gui_master_cntl ); 15842a55b46Smrg OUT_RING_REG( R128_DP_BRUSH_FRGD_CLR, info->state_2d.dp_brush_frgd_clr ); 15942a55b46Smrg OUT_RING_REG( R128_DP_BRUSH_BKGD_CLR, info->state_2d.dp_brush_bkgd_clr ); 16042a55b46Smrg OUT_RING_REG( R128_DP_SRC_FRGD_CLR, info->state_2d.dp_src_frgd_clr ); 16142a55b46Smrg OUT_RING_REG( R128_DP_SRC_BKGD_CLR, info->state_2d.dp_src_bkgd_clr ); 16242a55b46Smrg OUT_RING_REG( R128_DP_WRITE_MASK, info->state_2d.dp_write_mask ); 16342a55b46Smrg OUT_RING_REG( R128_DP_CNTL, info->state_2d.dp_cntl ); 16442a55b46Smrg 16542a55b46Smrg OUT_RING_REG( R128_DST_PITCH_OFFSET, info->state_2d.dst_pitch_offset ); 16642a55b46Smrg if (has_src) OUT_RING_REG( R128_SRC_PITCH_OFFSET, info->state_2d.src_pitch_offset ); 16742a55b46Smrg 16842a55b46Smrg ADVANCE_RING(); 16942a55b46Smrg} 17042a55b46Smrg#endif 17142a55b46Smrg 17242a55b46Smrg/* EXA Callbacks */ 17342a55b46Smrg 17442a55b46Smrgstatic Bool 17542a55b46SmrgR128PrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) 17642a55b46Smrg{ 17742a55b46Smrg ScreenPtr pScreen = pPixmap->drawable.pScreen; 17842a55b46Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 17942a55b46Smrg R128InfoPtr info = R128PTR(pScrn); 18042a55b46Smrg 18142a55b46Smrg int bpp = pPixmap->drawable.bitsPerPixel; 18242a55b46Smrg uint32_t datatype, dst_pitch_offset; 18342a55b46Smrg 18442a55b46Smrg if (!R128GetDatatypeBpp(bpp, &datatype)) { 18542a55b46Smrg R128TRACE(("R128GetDatatypeBpp failed\n")); 18642a55b46Smrg return FALSE; 18742a55b46Smrg } 18842a55b46Smrg if (!R128GetPixmapOffsetPitch(pPixmap, &dst_pitch_offset)) { 18942a55b46Smrg R128TRACE(("R128GetPixmapOffsetPitch failed\n")); 19042a55b46Smrg return FALSE; 19142a55b46Smrg } 19242a55b46Smrg if (info->state_2d.in_use) return FALSE; 19342a55b46Smrg 19442a55b46Smrg info->state_2d.in_use = TRUE; 19542a55b46Smrg info->state_2d.default_sc_bottom_right = (R128_DEFAULT_SC_RIGHT_MAX | R128_DEFAULT_SC_BOTTOM_MAX); 19642a55b46Smrg info->state_2d.dp_brush_bkgd_clr = 0x00000000; 19742a55b46Smrg info->state_2d.dp_src_frgd_clr = 0xffffffff; 19842a55b46Smrg info->state_2d.dp_src_bkgd_clr = 0x00000000; 19942a55b46Smrg info->state_2d.dp_gui_master_cntl = (R128_GMC_DST_PITCH_OFFSET_CNTL | 20042a55b46Smrg R128_GMC_BRUSH_SOLID_COLOR | 20142a55b46Smrg (datatype >> 8) | 20242a55b46Smrg R128_GMC_SRC_DATATYPE_COLOR | 20342a55b46Smrg R128_ROP[alu].pattern | 20442a55b46Smrg R128_GMC_CLR_CMP_CNTL_DIS); 20542a55b46Smrg info->state_2d.dp_brush_frgd_clr = fg; 20642a55b46Smrg info->state_2d.dp_cntl = (R128_DST_X_LEFT_TO_RIGHT | R128_DST_Y_TOP_TO_BOTTOM); 20742a55b46Smrg info->state_2d.dp_write_mask = planemask; 20842a55b46Smrg info->state_2d.dst_pitch_offset = dst_pitch_offset; 20942a55b46Smrg info->state_2d.src_pitch_offset = 0; 21042a55b46Smrg 21142a55b46Smrg#ifdef R128DRI 21242a55b46Smrg if (info->directRenderingEnabled) { 21342a55b46Smrg EmitCCE2DState(pScrn); 21442a55b46Smrg } else 21542a55b46Smrg#endif 21642a55b46Smrg { 21742a55b46Smrg Emit2DState(pScrn); 21842a55b46Smrg } 21942a55b46Smrg return TRUE; 22042a55b46Smrg} 22142a55b46Smrg 22242a55b46Smrgstatic void 22342a55b46SmrgR128Solid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) 22442a55b46Smrg{ 22542a55b46Smrg ScreenPtr pScreen = pPixmap->drawable.pScreen; 22642a55b46Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 22742a55b46Smrg R128InfoPtr info = R128PTR(pScrn); 22842a55b46Smrg unsigned char *R128MMIO = info->MMIO; 22942a55b46Smrg 23042a55b46Smrg R128WaitForFifo(pScrn, 2); 23142a55b46Smrg OUTREG(R128_DST_Y_X, (y1 << 16) | x1); 23242a55b46Smrg OUTREG(R128_DST_WIDTH_HEIGHT, ((x2-x1) << 16) | (y2-y1)); 23342a55b46Smrg} 23442a55b46Smrg 23542a55b46Smrg#define R128DoneSolid R128Done 23642a55b46Smrg 23742a55b46Smrgvoid 23842a55b46SmrgR128DoPrepareCopy(ScrnInfoPtr pScrn, uint32_t src_pitch_offset, 23942a55b46Smrg uint32_t dst_pitch_offset, uint32_t datatype, int alu, Pixel planemask) 24042a55b46Smrg{ 24142a55b46Smrg R128InfoPtr info = R128PTR(pScrn); 24242a55b46Smrg 24342a55b46Smrg info->state_2d.in_use = TRUE; 24442a55b46Smrg info->state_2d.dp_gui_master_cntl = (R128_GMC_DST_PITCH_OFFSET_CNTL | 24542a55b46Smrg R128_GMC_SRC_PITCH_OFFSET_CNTL | 24642a55b46Smrg R128_GMC_BRUSH_NONE | 24742a55b46Smrg (datatype >> 8) | 24842a55b46Smrg R128_GMC_SRC_DATATYPE_COLOR | 24942a55b46Smrg R128_ROP[alu].rop | 25042a55b46Smrg R128_DP_SRC_SOURCE_MEMORY | 25142a55b46Smrg R128_GMC_CLR_CMP_CNTL_DIS); 25242a55b46Smrg info->state_2d.dp_cntl = ((info->xdir >= 0 ? R128_DST_X_LEFT_TO_RIGHT : 0) | 25342a55b46Smrg (info->ydir >= 0 ? R128_DST_Y_TOP_TO_BOTTOM : 0)); 25442a55b46Smrg info->state_2d.dp_brush_frgd_clr = 0xffffffff; 25542a55b46Smrg info->state_2d.dp_brush_bkgd_clr = 0x00000000; 25642a55b46Smrg info->state_2d.dp_src_frgd_clr = 0xffffffff; 25742a55b46Smrg info->state_2d.dp_src_bkgd_clr = 0x00000000; 25842a55b46Smrg info->state_2d.dp_write_mask = planemask; 25942a55b46Smrg info->state_2d.dst_pitch_offset = dst_pitch_offset; 26042a55b46Smrg info->state_2d.src_pitch_offset = src_pitch_offset; 26142a55b46Smrg info->state_2d.default_sc_bottom_right = (R128_DEFAULT_SC_RIGHT_MAX | R128_DEFAULT_SC_BOTTOM_MAX); 26242a55b46Smrg 26342a55b46Smrg#ifdef R128DRI 26442a55b46Smrg if (info->directRenderingEnabled) { 26542a55b46Smrg EmitCCE2DState(pScrn); 26642a55b46Smrg } else 26742a55b46Smrg#endif 26842a55b46Smrg { 26942a55b46Smrg Emit2DState(pScrn); 27042a55b46Smrg } 27142a55b46Smrg} 27242a55b46Smrg 27342a55b46Smrgstatic Bool 27442a55b46SmrgR128PrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, int ydir, int alu, Pixel planemask) 27542a55b46Smrg{ 27642a55b46Smrg ScreenPtr pScreen = pSrcPixmap->drawable.pScreen; 27742a55b46Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 27842a55b46Smrg R128InfoPtr info = R128PTR(pScrn); 27942a55b46Smrg 28042a55b46Smrg int bpp = pDstPixmap->drawable.bitsPerPixel; 28142a55b46Smrg uint32_t datatype, src_pitch_offset, dst_pitch_offset; 28242a55b46Smrg 28342a55b46Smrg if (!R128GetDatatypeBpp(bpp, &datatype)) { 28442a55b46Smrg R128TRACE(("R128GetDatatypeBpp failed\n")); 28542a55b46Smrg return FALSE; 28642a55b46Smrg } 28742a55b46Smrg if (!R128GetPixmapOffsetPitch(pSrcPixmap, &src_pitch_offset)) { 28842a55b46Smrg R128TRACE(("R128GetPixmapOffsetPitch source failed\n")); 28942a55b46Smrg return FALSE; 29042a55b46Smrg } 29142a55b46Smrg if (!R128GetPixmapOffsetPitch(pDstPixmap, &dst_pitch_offset)) { 29242a55b46Smrg R128TRACE(("R128GetPixmapOffsetPitch dest failed\n")); 29342a55b46Smrg return FALSE; 29442a55b46Smrg } 29542a55b46Smrg if (info->state_2d.in_use) return FALSE; 29642a55b46Smrg 29742a55b46Smrg info->xdir = xdir; 29842a55b46Smrg info->ydir = ydir; 29942a55b46Smrg 30042a55b46Smrg R128DoPrepareCopy(pScrn, src_pitch_offset, dst_pitch_offset, datatype, alu, planemask); 30142a55b46Smrg 30242a55b46Smrg return TRUE; 30342a55b46Smrg} 30442a55b46Smrg 30542a55b46Smrgstatic void 30642a55b46SmrgR128Copy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int width, int height) 30742a55b46Smrg{ 30842a55b46Smrg ScreenPtr pScreen = pDstPixmap->drawable.pScreen; 30942a55b46Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 31042a55b46Smrg R128InfoPtr info = R128PTR(pScrn); 31142a55b46Smrg unsigned char *R128MMIO = info->MMIO; 31242a55b46Smrg 31342a55b46Smrg if (info->xdir < 0) srcX += width - 1, dstX += width - 1; 31442a55b46Smrg if (info->ydir < 0) srcY += height - 1, dstY += height - 1; 31542a55b46Smrg 31642a55b46Smrg R128WaitForFifo(pScrn, 3); 31742a55b46Smrg OUTREG(R128_SRC_Y_X, (srcY << 16) | srcX); 31842a55b46Smrg OUTREG(R128_DST_Y_X, (dstY << 16) | dstX); 31942a55b46Smrg OUTREG(R128_DST_HEIGHT_WIDTH, (height << 16) | width); 32042a55b46Smrg} 32142a55b46Smrg 32242a55b46Smrg#define R128DoneCopy R128Done 32342a55b46Smrg 32442a55b46Smrgstatic void 32542a55b46SmrgR128Sync(ScreenPtr pScreen, int marker) 32642a55b46Smrg{ 32742a55b46Smrg R128WaitForIdle(xf86ScreenToScrn(pScreen)); 32842a55b46Smrg} 32942a55b46Smrg 33042a55b46Smrgstatic void 33142a55b46SmrgR128Done(PixmapPtr pPixmap) 33242a55b46Smrg{ 33342a55b46Smrg ScreenPtr pScreen = pPixmap->drawable.pScreen; 33442a55b46Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 33542a55b46Smrg R128InfoPtr info = R128PTR(pScrn); 33642a55b46Smrg 33742a55b46Smrg info->state_2d.in_use = FALSE; 33842a55b46Smrg#if defined(R128DRI) && defined(RENDER) 33942a55b46Smrg if (info->state_2d.src_pix) { 34042a55b46Smrg pScreen->DestroyPixmap(info->state_2d.src_pix); 34142a55b46Smrg info->state_2d.src_pix = NULL; 34242a55b46Smrg } 34342a55b46Smrg if (info->state_2d.msk_pix) { 34442a55b46Smrg pScreen->DestroyPixmap(info->state_2d.msk_pix); 34542a55b46Smrg info->state_2d.msk_pix = NULL; 34642a55b46Smrg } 34742a55b46Smrg#endif 34842a55b46Smrg} 34942a55b46Smrg 35042a55b46Smrg#ifdef R128DRI 35142a55b46Smrg 35242a55b46Smrg#define R128CCEPrepareSolid R128PrepareSolid 35342a55b46Smrg 35442a55b46Smrgstatic void 35542a55b46SmrgR128CCESolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) 35642a55b46Smrg{ 35742a55b46Smrg ScreenPtr pScreen = pPixmap->drawable.pScreen; 35842a55b46Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 35942a55b46Smrg R128InfoPtr info = R128PTR(pScrn); 36042a55b46Smrg RING_LOCALS; 36142a55b46Smrg 36242a55b46Smrg R128CCE_REFRESH( pScrn, info ); 36342a55b46Smrg 36442a55b46Smrg BEGIN_RING( 4 ); 36542a55b46Smrg 36642a55b46Smrg OUT_RING_REG( R128_DST_Y_X, (y1 << 16) | x1 ); 36742a55b46Smrg OUT_RING_REG( R128_DST_WIDTH_HEIGHT, ((x2-x1) << 16) | (y2-y1) ); 36842a55b46Smrg 36942a55b46Smrg ADVANCE_RING(); 37042a55b46Smrg} 37142a55b46Smrg 37242a55b46Smrg#define R128CCEDoneSolid R128Done 37342a55b46Smrg 37442a55b46Smrg#define R128CCEPrepareCopy R128PrepareCopy 37542a55b46Smrg 37642a55b46Smrgstatic void 37742a55b46SmrgR128CCECopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, 37842a55b46Smrg int width, int height) 37942a55b46Smrg{ 38042a55b46Smrg ScreenPtr pScreen = pDstPixmap->drawable.pScreen; 38142a55b46Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 38242a55b46Smrg R128InfoPtr info = R128PTR(pScrn); 38342a55b46Smrg RING_LOCALS; 38442a55b46Smrg 38542a55b46Smrg R128CCE_REFRESH( pScrn, info ); 38642a55b46Smrg 38742a55b46Smrg if (info->xdir < 0) srcX += width - 1, dstX += width - 1; 38842a55b46Smrg if (info->ydir < 0) srcY += height - 1, dstY += height - 1; 38942a55b46Smrg 39042a55b46Smrg BEGIN_RING( 6 ); 39142a55b46Smrg 39242a55b46Smrg OUT_RING_REG( R128_SRC_Y_X, (srcY << 16) | srcX ); 39342a55b46Smrg OUT_RING_REG( R128_DST_Y_X, (dstY << 16) | dstX ); 39442a55b46Smrg OUT_RING_REG( R128_DST_HEIGHT_WIDTH, (height << 16) | width ); 39542a55b46Smrg 39642a55b46Smrg ADVANCE_RING(); 39742a55b46Smrg} 39842a55b46Smrg 39942a55b46Smrg#define R128CCEDoneCopy R128Done 40042a55b46Smrg 40142a55b46Smrgstatic void 40242a55b46SmrgR128CCESync(ScreenPtr pScreen, int marker) 40342a55b46Smrg{ 40442a55b46Smrg R128CCEWaitForIdle(xf86ScreenToScrn(pScreen)); 40542a55b46Smrg} 40642a55b46Smrg 40742a55b46Smrg#ifdef RENDER 40842a55b46Smrg#include "r128_exa_render.c" 40942a55b46Smrg#endif 41042a55b46Smrg 41142a55b46Smrg#endif 41242a55b46Smrg 41342a55b46SmrgBool 41442a55b46SmrgR128EXAInit(ScreenPtr pScreen) 41542a55b46Smrg{ 41642a55b46Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 41742a55b46Smrg R128InfoPtr info = R128PTR(pScrn); 41842a55b46Smrg 41942a55b46Smrg info->ExaDriver->exa_major = EXA_VERSION_MAJOR; 42042a55b46Smrg info->ExaDriver->exa_minor = EXA_VERSION_MINOR; 42142a55b46Smrg 42242a55b46Smrg info->ExaDriver->memoryBase = info->FB + pScrn->fbOffset; 42342a55b46Smrg info->ExaDriver->flags = EXA_OFFSCREEN_PIXMAPS | EXA_OFFSCREEN_ALIGN_POT; 42442a55b46Smrg 42542a55b46Smrg#if EXA_VERSION_MAJOR > 2 || (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 3) 42642a55b46Smrg info->ExaDriver->maxPitchBytes = 16320; 42742a55b46Smrg#endif 42842a55b46Smrg /* Pitch alignment is in sets of 8 pixels, and we need to cover 32bpp, so it's 32 bytes */ 42942a55b46Smrg info->ExaDriver->pixmapPitchAlign = 32; 43042a55b46Smrg info->ExaDriver->pixmapOffsetAlign = 32; 43142a55b46Smrg info->ExaDriver->maxX = 2048; 43242a55b46Smrg info->ExaDriver->maxY = 2048; 43342a55b46Smrg 43442a55b46Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 43542a55b46Smrg "Setting up EXA callbacks\n"); 43642a55b46Smrg 43742a55b46Smrg#ifdef R128DRI 43842a55b46Smrg if (info->directRenderingEnabled) { 43942a55b46Smrg info->ExaDriver->PrepareSolid = R128CCEPrepareSolid; 44042a55b46Smrg info->ExaDriver->Solid = R128CCESolid; 44142a55b46Smrg info->ExaDriver->DoneSolid = R128CCEDoneSolid; 44242a55b46Smrg 44342a55b46Smrg info->ExaDriver->PrepareCopy = R128CCEPrepareCopy; 44442a55b46Smrg info->ExaDriver->Copy = R128CCECopy; 44542a55b46Smrg info->ExaDriver->DoneCopy = R128CCEDoneCopy; 44642a55b46Smrg 44742a55b46Smrg#ifdef RENDER 44842a55b46Smrg if (info->RenderAccel) { 44942a55b46Smrg info->ExaDriver->CheckComposite = R128CCECheckComposite; 45042a55b46Smrg info->ExaDriver->PrepareComposite = R128CCEPrepareComposite; 45142a55b46Smrg info->ExaDriver->Composite = R128CCEComposite; 45242a55b46Smrg info->ExaDriver->DoneComposite = R128CCEDoneComposite; 45342a55b46Smrg } 45442a55b46Smrg#endif 45542a55b46Smrg 45642a55b46Smrg info->ExaDriver->WaitMarker = R128CCESync; 45742a55b46Smrg } else 45842a55b46Smrg#endif 45942a55b46Smrg { 46042a55b46Smrg info->ExaDriver->PrepareSolid = R128PrepareSolid; 46142a55b46Smrg info->ExaDriver->Solid = R128Solid; 46242a55b46Smrg info->ExaDriver->DoneSolid = R128DoneSolid; 46342a55b46Smrg 46442a55b46Smrg info->ExaDriver->PrepareCopy = R128PrepareCopy; 46542a55b46Smrg info->ExaDriver->Copy = R128Copy; 46642a55b46Smrg info->ExaDriver->DoneCopy = R128DoneCopy; 46742a55b46Smrg 46842a55b46Smrg /* The registers used for r128 compositing are CCE specific, just like the 46942a55b46Smrg * registers used for radeon compositing are CP specific. The radeon driver 47042a55b46Smrg * falls back to different registers when there is no DRI. The equivalent 47142a55b46Smrg * registers on the r128 (if they even exist) are not listed in the register 47242a55b46Smrg * file so I can't implement compositing without DRI. 47342a55b46Smrg */ 47442a55b46Smrg 47542a55b46Smrg info->ExaDriver->WaitMarker = R128Sync; 47642a55b46Smrg } 47742a55b46Smrg 47842a55b46Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 47942a55b46Smrg "Initalizing 2D acceleration engine...\n"); 48042a55b46Smrg 48142a55b46Smrg R128EngineInit(pScrn); 48242a55b46Smrg 48342a55b46Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 48442a55b46Smrg "Initializing EXA driver...\n"); 48542a55b46Smrg 48642a55b46Smrg if (!exaDriverInit(pScreen, info->ExaDriver)) { 48742a55b46Smrg free(info->ExaDriver); 48842a55b46Smrg return FALSE; 48942a55b46Smrg } 49042a55b46Smrg 49142a55b46Smrg info->state_2d.composite_setup = FALSE; 49242a55b46Smrg return TRUE; 49342a55b46Smrg} 494