cg14_accel.c revision 4bd47ccf
14bd47ccfSmacallan/* $NetBSD: cg14_accel.c,v 1.10 2017/01/13 20:58:40 macallan Exp $ */ 24261fa58Smacallan/* 34261fa58Smacallan * Copyright (c) 2013 Michael Lorenz 44261fa58Smacallan * All rights reserved. 54261fa58Smacallan * 64261fa58Smacallan * Redistribution and use in source and binary forms, with or without 74261fa58Smacallan * modification, are permitted provided that the following conditions 84261fa58Smacallan * are met: 94261fa58Smacallan * 104261fa58Smacallan * - Redistributions of source code must retain the above copyright 114261fa58Smacallan * notice, this list of conditions and the following disclaimer. 124261fa58Smacallan * - Redistributions in binary form must reproduce the above 134261fa58Smacallan * copyright notice, this list of conditions and the following 144261fa58Smacallan * disclaimer in the documentation and/or other materials provided 154261fa58Smacallan * with the distribution. 164261fa58Smacallan * 174261fa58Smacallan * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 184261fa58Smacallan * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 194261fa58Smacallan * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 204261fa58Smacallan * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 214261fa58Smacallan * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 224261fa58Smacallan * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 234261fa58Smacallan * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 244261fa58Smacallan * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 254261fa58Smacallan * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 264261fa58Smacallan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 274261fa58Smacallan * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 284261fa58Smacallan * POSSIBILITY OF SUCH DAMAGE. 294261fa58Smacallan * 304261fa58Smacallan */ 31c88c16f8Smacallan 32c88c16f8Smacallan#ifdef HAVE_CONFIG_H 33c88c16f8Smacallan#include "config.h" 34c88c16f8Smacallan#endif 35c88c16f8Smacallan 364261fa58Smacallan#include <sys/types.h> 374261fa58Smacallan 384261fa58Smacallan/* all driver need this */ 394261fa58Smacallan#include "xf86.h" 404261fa58Smacallan#include "xf86_OSproc.h" 414261fa58Smacallan#include "compiler.h" 424261fa58Smacallan 434261fa58Smacallan#include "cg14.h" 444261fa58Smacallan#include <sparc/sxreg.h> 454261fa58Smacallan 464261fa58Smacallan/*#define SX_DEBUG*/ 474261fa58Smacallan 484261fa58Smacallan#ifdef SX_DEBUG 494261fa58Smacallan#define ENTER xf86Msg(X_ERROR, "%s>\n", __func__); 504261fa58Smacallan#define DPRINTF xf86Msg 514261fa58Smacallan#else 524261fa58Smacallan#define ENTER 534261fa58Smacallan#define DPRINTF while (0) xf86Msg 544261fa58Smacallan#endif 554261fa58Smacallan 564261fa58Smacallan#define arraysize(ary) (sizeof(ary) / sizeof(ary[0])) 574261fa58Smacallan 584261fa58Smacallan/* 0xcc is SX's GXcopy equivalent */ 594261fa58Smacallanuint32_t sx_rop[] = { 0x00, 0x88, 0x44, 0xcc, 0x22, 0xaa, 0x66, 0xee, 604261fa58Smacallan 0x11, 0x99, 0x55, 0xdd, 0x33, 0xbb, 0x77, 0xff}; 614261fa58Smacallan 624261fa58Smacallanint src_formats[] = {PICT_a8r8g8b8, PICT_x8r8g8b8, 634261fa58Smacallan PICT_a8b8g8r8, PICT_x8b8g8r8, PICT_a8}; 644261fa58Smacallanint tex_formats[] = {PICT_a8r8g8b8, PICT_a8b8g8r8, PICT_a8}; 654261fa58Smacallan 664261fa58Smacallanstatic inline void 674261fa58SmacallanCG14Wait(Cg14Ptr p) 684261fa58Smacallan{ 694261fa58Smacallan /* we just wait until the instruction queue is empty */ 704261fa58Smacallan while ((read_sx_reg(p, SX_CONTROL_STATUS) & SX_MT) != 0) {}; 714261fa58Smacallan} 724261fa58Smacallan 734261fa58Smacallanstatic void 744261fa58SmacallanCG14WaitMarker(ScreenPtr pScreen, int Marker) 754261fa58Smacallan{ 764261fa58Smacallan ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 774261fa58Smacallan Cg14Ptr p = GET_CG14_FROM_SCRN(pScrn); 784261fa58Smacallan 794261fa58Smacallan CG14Wait(p); 804261fa58Smacallan} 814261fa58Smacallan 824261fa58Smacallanstatic Bool 834261fa58SmacallanCG14PrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, 844261fa58Smacallan int xdir, int ydir, int alu, Pixel planemask) 854261fa58Smacallan{ 864261fa58Smacallan ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 874261fa58Smacallan Cg14Ptr p = GET_CG14_FROM_SCRN(pScrn); 884261fa58Smacallan 894261fa58Smacallan ENTER; 904261fa58Smacallan DPRINTF(X_ERROR, "bits per pixel: %d\n", 914261fa58Smacallan pSrcPixmap->drawable.bitsPerPixel); 924261fa58Smacallan 934261fa58Smacallan if (planemask != p->last_mask) { 944261fa58Smacallan CG14Wait(p); 954261fa58Smacallan write_sx_reg(p, SX_PLANEMASK, planemask); 964261fa58Smacallan p->last_mask = planemask; 974261fa58Smacallan } 984261fa58Smacallan alu = sx_rop[alu]; 994261fa58Smacallan if (alu != p->last_rop) { 1004261fa58Smacallan CG14Wait(p); 1014261fa58Smacallan write_sx_reg(p, SX_ROP_CONTROL, alu); 1024261fa58Smacallan p->last_rop = alu; 1034261fa58Smacallan } 1044261fa58Smacallan p->srcpitch = exaGetPixmapPitch(pSrcPixmap); 1054261fa58Smacallan p->srcoff = exaGetPixmapOffset(pSrcPixmap); 1064261fa58Smacallan p->xdir = xdir; 1074261fa58Smacallan p->ydir = ydir; 1084261fa58Smacallan return TRUE; 1094261fa58Smacallan} 1104261fa58Smacallan 1114261fa58Smacallanstatic void 1124261fa58SmacallanCG14Copy(PixmapPtr pDstPixmap, 1134261fa58Smacallan int srcX, int srcY, int dstX, int dstY, int w, int h) 1144261fa58Smacallan{ 1154261fa58Smacallan ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 1164261fa58Smacallan Cg14Ptr p = GET_CG14_FROM_SCRN(pScrn); 1174261fa58Smacallan int dstpitch, dstoff, srcpitch, srcoff; 1184261fa58Smacallan int srcstart, dststart, xinc, srcinc, dstinc; 1194261fa58Smacallan int line, count, s, d, num; 1204261fa58Smacallan 1214261fa58Smacallan ENTER; 1224261fa58Smacallan dstpitch = exaGetPixmapPitch(pDstPixmap); 1234261fa58Smacallan dstoff = exaGetPixmapOffset(pDstPixmap); 1244261fa58Smacallan srcpitch = p->srcpitch; 1254261fa58Smacallan srcoff = p->srcoff; 1264261fa58Smacallan /* 1274261fa58Smacallan * should clear the WO bit in SX_CONTROL_STATUS, then check if SX 1284261fa58Smacallan * actually wrote anything and only sync if it did 1294261fa58Smacallan */ 1304261fa58Smacallan srcstart = (srcX << 2) + (srcpitch * srcY) + srcoff; 1314261fa58Smacallan dststart = (dstX << 2) + (dstpitch * dstY) + dstoff; 1324261fa58Smacallan 1334261fa58Smacallan /* 1344261fa58Smacallan * we always copy up to 32 pixels at a time so direction doesn't 1354261fa58Smacallan * matter if w<=32 1364261fa58Smacallan */ 1374261fa58Smacallan if (w > 32) { 1384261fa58Smacallan if (p->xdir < 0) { 1394261fa58Smacallan srcstart += (w - 32) << 2; 1404261fa58Smacallan dststart += (w - 32) << 2; 1414261fa58Smacallan xinc = -128; 1424261fa58Smacallan } else 1434261fa58Smacallan xinc = 128; 1444261fa58Smacallan } else 1454261fa58Smacallan xinc = 128; 1464261fa58Smacallan if (p->ydir < 0) { 1474261fa58Smacallan srcstart += (h - 1) * srcpitch; 1484261fa58Smacallan dststart += (h - 1) * dstpitch; 1494261fa58Smacallan srcinc = -srcpitch; 1504261fa58Smacallan dstinc = -dstpitch; 1514261fa58Smacallan } else { 1524261fa58Smacallan srcinc = srcpitch; 1534261fa58Smacallan dstinc = dstpitch; 1544261fa58Smacallan } 1554261fa58Smacallan if (p->last_rop == 0xcc) { 1564261fa58Smacallan /* plain old copy */ 1574261fa58Smacallan if ( xinc > 0) { 1584261fa58Smacallan /* going left to right */ 1594261fa58Smacallan for (line = 0; line < h; line++) { 1604261fa58Smacallan count = 0; 1614261fa58Smacallan s = srcstart; 1624261fa58Smacallan d = dststart; 1634261fa58Smacallan while ( count < w) { 1644261fa58Smacallan num = min(32, w - count); 1654261fa58Smacallan write_sx_io(p, s, 1664261fa58Smacallan SX_LD(10, num - 1, s & 7)); 1674261fa58Smacallan write_sx_io(p, d, 1684261fa58Smacallan SX_STM(10, num - 1, d & 7)); 1694261fa58Smacallan s += xinc; 1704261fa58Smacallan d += xinc; 1714261fa58Smacallan count += 32; 1724261fa58Smacallan } 1734261fa58Smacallan srcstart += srcinc; 1744261fa58Smacallan dststart += dstinc; 1754261fa58Smacallan } 1764261fa58Smacallan } else { 1774261fa58Smacallan /* going right to left */ 1784261fa58Smacallan int i, chunks = (w >> 5); 1794261fa58Smacallan for (line = 0; line < h; line++) { 1804261fa58Smacallan s = srcstart; 1814261fa58Smacallan d = dststart; 1824261fa58Smacallan count = w; 1834261fa58Smacallan for (i = 0; i < chunks; i++) { 1844261fa58Smacallan write_sx_io(p, s, 1854261fa58Smacallan SX_LD(10, 31, s & 7)); 1864261fa58Smacallan write_sx_io(p, d, 1874261fa58Smacallan SX_STM(10, 31, d & 7)); 1884261fa58Smacallan s -= 128; 1894261fa58Smacallan d -= 128; 1904261fa58Smacallan count -= 32; 1914261fa58Smacallan } 1924261fa58Smacallan /* leftovers, if any */ 1934261fa58Smacallan if (count > 0) { 1944261fa58Smacallan s += (32 - count) << 2; 1954261fa58Smacallan d += (32 - count) << 2; 1964261fa58Smacallan write_sx_io(p, s, 1974261fa58Smacallan SX_LD(10, count - 1, s & 7)); 1984261fa58Smacallan write_sx_io(p, d, 1994261fa58Smacallan SX_STM(10, count - 1, d & 7)); 2004261fa58Smacallan } 2014261fa58Smacallan srcstart += srcinc; 2024261fa58Smacallan dststart += dstinc; 2034261fa58Smacallan } 2044261fa58Smacallan } 2054261fa58Smacallan } else { 2064261fa58Smacallan /* ROPs needed */ 2074261fa58Smacallan if ( xinc > 0) { 2084261fa58Smacallan /* going left to right */ 2094261fa58Smacallan for (line = 0; line < h; line++) { 2104261fa58Smacallan count = 0; 2114261fa58Smacallan s = srcstart; 2124261fa58Smacallan d = dststart; 2134261fa58Smacallan while ( count < w) { 2144261fa58Smacallan num = min(32, w - count); 2154261fa58Smacallan write_sx_io(p, s, 2164261fa58Smacallan SX_LD(10, num - 1, s & 7)); 2174261fa58Smacallan write_sx_io(p, d, 2184261fa58Smacallan SX_LD(42, num - 1, d & 7)); 2194261fa58Smacallan if (num > 16) { 2204261fa58Smacallan write_sx_reg(p, SX_INSTRUCTIONS, 2214261fa58Smacallan SX_ROP(10, 42, 74, 15)); 2224261fa58Smacallan write_sx_reg(p, SX_INSTRUCTIONS, 2234261fa58Smacallan SX_ROP(26, 58, 90, num - 17)); 2244261fa58Smacallan } else { 2254261fa58Smacallan write_sx_reg(p, SX_INSTRUCTIONS, 2264261fa58Smacallan SX_ROP(10, 42, 74, num - 1)); 2274261fa58Smacallan } 2284261fa58Smacallan write_sx_io(p, d, 2294261fa58Smacallan SX_STM(74, num - 1, d & 7)); 2304261fa58Smacallan s += xinc; 2314261fa58Smacallan d += xinc; 2324261fa58Smacallan count += 32; 2334261fa58Smacallan } 2344261fa58Smacallan srcstart += srcinc; 2354261fa58Smacallan dststart += dstinc; 2364261fa58Smacallan } 2374261fa58Smacallan } else { 2384261fa58Smacallan /* going right to left */ 2394261fa58Smacallan int i, chunks = (w >> 5); 2404261fa58Smacallan for (line = 0; line < h; line++) { 2414261fa58Smacallan s = srcstart; 2424261fa58Smacallan d = dststart; 2434261fa58Smacallan count = w; 2444261fa58Smacallan for (i = 0; i < chunks; i++) { 2454261fa58Smacallan write_sx_io(p, s, SX_LD(10, 31, s & 7)); 2464261fa58Smacallan write_sx_io(p, d, SX_LD(42, 31, d & 7)); 2474261fa58Smacallan write_sx_reg(p, SX_INSTRUCTIONS, 2484261fa58Smacallan SX_ROP(10, 42, 74, 15)); 2494261fa58Smacallan write_sx_reg(p, SX_INSTRUCTIONS, 2504261fa58Smacallan SX_ROP(26, 58, 90, 15)); 2514261fa58Smacallan write_sx_io(p, d, 2524261fa58Smacallan SX_STM(74, 31, d & 7)); 2534261fa58Smacallan s -= 128; 2544261fa58Smacallan d -= 128; 2554261fa58Smacallan count -= 32; 2564261fa58Smacallan } 2574261fa58Smacallan /* leftovers, if any */ 2584261fa58Smacallan if (count > 0) { 2594261fa58Smacallan s += (32 - count) << 2; 2604261fa58Smacallan d += (32 - count) << 2; 2614261fa58Smacallan write_sx_io(p, s, 2624261fa58Smacallan SX_LD(10, count - 1, s & 7)); 2634261fa58Smacallan write_sx_io(p, d, 2644261fa58Smacallan SX_LD(42, count - 1, d & 7)); 2654261fa58Smacallan if (count > 16) { 2664261fa58Smacallan write_sx_reg(p, SX_INSTRUCTIONS, 2674261fa58Smacallan SX_ROP(10, 42, 74, 15)); 2684261fa58Smacallan write_sx_reg(p, SX_INSTRUCTIONS, 2694261fa58Smacallan SX_ROP(26, 58, 90, count - 17)); 2704261fa58Smacallan } else { 2714261fa58Smacallan write_sx_reg(p, SX_INSTRUCTIONS, 2724261fa58Smacallan SX_ROP(10, 42, 74, count - 1)); 2734261fa58Smacallan } 2744261fa58Smacallan 2754261fa58Smacallan write_sx_io(p, d, 2764261fa58Smacallan SX_STM(74, count - 1, d & 7)); 2774261fa58Smacallan } 2784261fa58Smacallan srcstart += srcinc; 2794261fa58Smacallan dststart += dstinc; 2804261fa58Smacallan } 2814261fa58Smacallan } 2824261fa58Smacallan } 2834261fa58Smacallan exaMarkSync(pDstPixmap->drawable.pScreen); 2844261fa58Smacallan} 2854261fa58Smacallan 2864261fa58Smacallanstatic void 2874261fa58SmacallanCG14DoneCopy(PixmapPtr pDstPixmap) 2884261fa58Smacallan{ 2894261fa58Smacallan} 2904261fa58Smacallan 2914261fa58Smacallanstatic Bool 2924261fa58SmacallanCG14PrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) 2934261fa58Smacallan{ 2944261fa58Smacallan ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 2954261fa58Smacallan Cg14Ptr p = GET_CG14_FROM_SCRN(pScrn); 2964261fa58Smacallan 2974261fa58Smacallan ENTER; 2986bdc2ffdSmacallan DPRINTF(X_ERROR, "bits per pixel: %d\n", 2996bdc2ffdSmacallan pPixmap->drawable.bitsPerPixel); 3004261fa58Smacallan write_sx_reg(p, SX_QUEUED(8), fg); 3014261fa58Smacallan write_sx_reg(p, SX_QUEUED(9), fg); 3024261fa58Smacallan if (planemask != p->last_mask) { 3034261fa58Smacallan CG14Wait(p); 3044261fa58Smacallan write_sx_reg(p, SX_PLANEMASK, planemask); 3054261fa58Smacallan p->last_mask = planemask; 3064261fa58Smacallan } 3074261fa58Smacallan alu = sx_rop[alu]; 3084261fa58Smacallan if (alu != p->last_rop) { 3094261fa58Smacallan CG14Wait(p); 3104261fa58Smacallan write_sx_reg(p, SX_ROP_CONTROL, alu); 3114261fa58Smacallan p->last_rop = alu; 3124261fa58Smacallan } 3134261fa58Smacallan DPRINTF(X_ERROR, "%s: %x\n", __func__, alu); 3144261fa58Smacallan return TRUE; 3154261fa58Smacallan} 3164261fa58Smacallan 3174261fa58Smacallanstatic void 3184261fa58SmacallanCG14Solid32(Cg14Ptr p, uint32_t start, uint32_t pitch, int w, int h) 3194261fa58Smacallan{ 3204261fa58Smacallan int line, x, num; 3214261fa58Smacallan uint32_t ptr; 3224261fa58Smacallan 3234261fa58Smacallan ENTER; 3244261fa58Smacallan if (p->last_rop == 0xcc) { 3254261fa58Smacallan /* simple fill */ 3264261fa58Smacallan for (line = 0; line < h; line++) { 3274261fa58Smacallan x = 0; 3284261fa58Smacallan while (x < w) { 3294261fa58Smacallan ptr = start + (x << 2); 3304261fa58Smacallan num = min(32, w - x); 3314261fa58Smacallan write_sx_io(p, ptr, 3324261fa58Smacallan SX_STS(8, num - 1, ptr & 7)); 3334261fa58Smacallan x += 32; 3344261fa58Smacallan } 3354261fa58Smacallan start += pitch; 3364261fa58Smacallan } 3374261fa58Smacallan } else if (p->last_rop == 0xaa) { 3384261fa58Smacallan /* nothing to do here */ 3394261fa58Smacallan return; 3404261fa58Smacallan } else { 3414261fa58Smacallan /* alright, let's do actual ROP stuff */ 3424261fa58Smacallan 3434261fa58Smacallan /* first repeat the fill colour into 16 registers */ 3444261fa58Smacallan write_sx_reg(p, SX_INSTRUCTIONS, 3454261fa58Smacallan SX_SELECT_S(8, 8, 10, 15)); 3464261fa58Smacallan 3474261fa58Smacallan for (line = 0; line < h; line++) { 3484261fa58Smacallan x = 0; 3494261fa58Smacallan while (x < w) { 3504261fa58Smacallan ptr = start + (x << 2); 3514261fa58Smacallan num = min(32, w - x); 3524261fa58Smacallan /* now suck fb data into registers */ 3534261fa58Smacallan write_sx_io(p, ptr, 3544261fa58Smacallan SX_LD(42, num - 1, ptr & 7)); 3554261fa58Smacallan /* 3564261fa58Smacallan * ROP them with the fill data we left in 10 3574261fa58Smacallan * non-memory ops can only have counts up to 16 3584261fa58Smacallan */ 3594261fa58Smacallan if (num <= 16) { 3604261fa58Smacallan write_sx_reg(p, SX_INSTRUCTIONS, 3614261fa58Smacallan SX_ROP(10, 42, 74, num - 1)); 3624261fa58Smacallan } else { 3634261fa58Smacallan write_sx_reg(p, SX_INSTRUCTIONS, 3644261fa58Smacallan SX_ROP(10, 42, 74, 15)); 3654261fa58Smacallan write_sx_reg(p, SX_INSTRUCTIONS, 3664261fa58Smacallan SX_ROP(10, 58, 90, num - 17)); 3674261fa58Smacallan } 3684261fa58Smacallan /* and write the result back into memory */ 3694261fa58Smacallan write_sx_io(p, ptr, 3704261fa58Smacallan SX_ST(74, num - 1, ptr & 7)); 3714261fa58Smacallan x += 32; 3724261fa58Smacallan } 3734261fa58Smacallan start += pitch; 3744261fa58Smacallan } 3754261fa58Smacallan } 3764261fa58Smacallan} 3774261fa58Smacallan 3784261fa58Smacallanstatic void 3794261fa58SmacallanCG14Solid8(Cg14Ptr p, uint32_t start, uint32_t pitch, int w, int h) 3804261fa58Smacallan{ 3814261fa58Smacallan int line, x, num, off; 3824261fa58Smacallan uint32_t ptr; 3834261fa58Smacallan 3844261fa58Smacallan ENTER; 3854261fa58Smacallan off = start & 7; 3864261fa58Smacallan start &= ~7; 3874261fa58Smacallan 3884261fa58Smacallan if (p->last_rop == 0xcc) { 3894261fa58Smacallan /* simple fill */ 3904261fa58Smacallan for (line = 0; line < h; line++) { 3914261fa58Smacallan x = 0; 3924261fa58Smacallan while (x < w) { 3934261fa58Smacallan ptr = start + x; 3944261fa58Smacallan num = min(32, w - x); 3954261fa58Smacallan write_sx_io(p, ptr, 3964261fa58Smacallan SX_STBS(8, num - 1, off)); 3974261fa58Smacallan x += 32; 3984261fa58Smacallan } 3994261fa58Smacallan start += pitch; 4004261fa58Smacallan } 4014261fa58Smacallan } else if (p->last_rop == 0xaa) { 4024261fa58Smacallan /* nothing to do here */ 4034261fa58Smacallan return; 4044261fa58Smacallan } else { 4054261fa58Smacallan /* alright, let's do actual ROP stuff */ 4064261fa58Smacallan 4074261fa58Smacallan /* first repeat the fill colour into 16 registers */ 4084261fa58Smacallan write_sx_reg(p, SX_INSTRUCTIONS, 4094261fa58Smacallan SX_SELECT_S(8, 8, 10, 15)); 4104261fa58Smacallan 4114261fa58Smacallan for (line = 0; line < h; line++) { 4124261fa58Smacallan x = 0; 4134261fa58Smacallan while (x < w) { 4144261fa58Smacallan ptr = start + x; 4154261fa58Smacallan num = min(32, w - x); 4164261fa58Smacallan /* now suck fb data into registers */ 4174261fa58Smacallan write_sx_io(p, ptr, 4184261fa58Smacallan SX_LDB(42, num - 1, off)); 4194261fa58Smacallan /* 4204261fa58Smacallan * ROP them with the fill data we left in 10 4214261fa58Smacallan * non-memory ops can only have counts up to 16 4224261fa58Smacallan */ 4234261fa58Smacallan if (num <= 16) { 4244261fa58Smacallan write_sx_reg(p, SX_INSTRUCTIONS, 4254261fa58Smacallan SX_ROP(10, 42, 74, num - 1)); 4264261fa58Smacallan } else { 4274261fa58Smacallan write_sx_reg(p, SX_INSTRUCTIONS, 4284261fa58Smacallan SX_ROP(10, 42, 74, 15)); 4294261fa58Smacallan write_sx_reg(p, SX_INSTRUCTIONS, 4304261fa58Smacallan SX_ROP(10, 58, 90, num - 17)); 4314261fa58Smacallan } 4324261fa58Smacallan /* and write the result back into memory */ 4334261fa58Smacallan write_sx_io(p, ptr, 4344261fa58Smacallan SX_STB(74, num - 1, off)); 4354261fa58Smacallan x += 32; 4364261fa58Smacallan } 4374261fa58Smacallan start += pitch; 4384261fa58Smacallan } 4394261fa58Smacallan } 4404261fa58Smacallan} 4414261fa58Smacallan 4424261fa58Smacallanstatic void 4434261fa58SmacallanCG14Solid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) 4444261fa58Smacallan{ 4454261fa58Smacallan ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 4464261fa58Smacallan Cg14Ptr p = GET_CG14_FROM_SCRN(pScrn); 4474261fa58Smacallan int w = x2 - x1, h = y2 - y1, dstoff, dstpitch; 4484261fa58Smacallan int start, depth; 4494261fa58Smacallan 4504261fa58Smacallan ENTER; 4514261fa58Smacallan dstpitch = exaGetPixmapPitch(pPixmap); 4524261fa58Smacallan dstoff = exaGetPixmapOffset(pPixmap); 4534261fa58Smacallan 4544261fa58Smacallan depth = pPixmap->drawable.bitsPerPixel; 4554261fa58Smacallan switch (depth) { 4564261fa58Smacallan case 32: 4574261fa58Smacallan start = dstoff + (y1 * dstpitch) + (x1 << 2); 4584261fa58Smacallan CG14Solid32(p, start, dstpitch, w, h); 4594261fa58Smacallan break; 4604261fa58Smacallan case 8: 4614261fa58Smacallan start = dstoff + (y1 * dstpitch) + x1; 4624261fa58Smacallan CG14Solid8(p, start, dstpitch, w, h); 4634261fa58Smacallan break; 4644261fa58Smacallan } 4654261fa58Smacallan 4664261fa58Smacallan DPRINTF(X_ERROR, "Solid %d %d %d %d, %d %d -> %d\n", x1, y1, x2, y2, 4674261fa58Smacallan dstpitch, dstoff, start); 4684261fa58Smacallan DPRINTF(X_ERROR, "%x %x %x\n", p->last_rop, 4694261fa58Smacallan read_sx_reg(p, SX_QUEUED(8)), read_sx_reg(p, SX_QUEUED(9))); 4704261fa58Smacallan exaMarkSync(pPixmap->drawable.pScreen); 4714261fa58Smacallan} 4724261fa58Smacallan 4734261fa58Smacallan/* 4744261fa58Smacallan * Memcpy-based UTS. 4754261fa58Smacallan */ 4764261fa58Smacallanstatic Bool 4774261fa58SmacallanCG14UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, 4784261fa58Smacallan char *src, int src_pitch) 4794261fa58Smacallan{ 4804261fa58Smacallan ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 4814261fa58Smacallan Cg14Ptr p = GET_CG14_FROM_SCRN(pScrn); 4824261fa58Smacallan char *dst = p->fb + exaGetPixmapOffset(pDst); 4834261fa58Smacallan int dst_pitch = exaGetPixmapPitch(pDst); 4844261fa58Smacallan 4854261fa58Smacallan int bpp = pDst->drawable.bitsPerPixel; 4864261fa58Smacallan int cpp = (bpp + 7) >> 3; 4874261fa58Smacallan int wBytes = w * cpp; 4884261fa58Smacallan 4894261fa58Smacallan ENTER; 4904261fa58Smacallan dst += (x * cpp) + (y * dst_pitch); 4914261fa58Smacallan 4924261fa58Smacallan CG14Wait(p); 4934261fa58Smacallan 4944261fa58Smacallan while (h--) { 4954261fa58Smacallan memcpy(dst, src, wBytes); 4964261fa58Smacallan src += src_pitch; 4974261fa58Smacallan dst += dst_pitch; 4984261fa58Smacallan } 4994261fa58Smacallan __asm("stbar;"); 5004261fa58Smacallan return TRUE; 5014261fa58Smacallan} 5024261fa58Smacallan 5034261fa58Smacallan/* 5044261fa58Smacallan * Memcpy-based DFS. 5054261fa58Smacallan */ 5064261fa58Smacallanstatic Bool 5074261fa58SmacallanCG14DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, 5084261fa58Smacallan char *dst, int dst_pitch) 5094261fa58Smacallan{ 5104261fa58Smacallan ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum]; 5114261fa58Smacallan Cg14Ptr p = GET_CG14_FROM_SCRN(pScrn); 5124261fa58Smacallan char *src = p->fb + exaGetPixmapOffset(pSrc); 5134261fa58Smacallan int src_pitch = exaGetPixmapPitch(pSrc); 5144261fa58Smacallan 5154261fa58Smacallan ENTER; 5164261fa58Smacallan int bpp = pSrc->drawable.bitsPerPixel; 5174261fa58Smacallan int cpp = (bpp + 7) >> 3; 5184261fa58Smacallan int wBytes = w * cpp; 5194261fa58Smacallan 5204261fa58Smacallan src += (x * cpp) + (y * src_pitch); 5214261fa58Smacallan 5224261fa58Smacallan CG14Wait(p); 5234261fa58Smacallan 5244261fa58Smacallan while (h--) { 5254261fa58Smacallan memcpy(dst, src, wBytes); 5264261fa58Smacallan src += src_pitch; 5274261fa58Smacallan dst += dst_pitch; 5284261fa58Smacallan } 5294261fa58Smacallan 5304261fa58Smacallan return TRUE; 5314261fa58Smacallan} 5324261fa58Smacallan 5334261fa58SmacallanBool 5344261fa58SmacallanCG14CheckComposite(int op, PicturePtr pSrcPicture, 5354261fa58Smacallan PicturePtr pMaskPicture, 5364261fa58Smacallan PicturePtr pDstPicture) 5374261fa58Smacallan{ 5384261fa58Smacallan int i, ok = FALSE; 5394261fa58Smacallan 5404261fa58Smacallan ENTER; 5414261fa58Smacallan 5424261fa58Smacallan /* 5434261fa58Smacallan * SX is in theory capable of accelerating pretty much all Xrender ops, 5444261fa58Smacallan * even coordinate transformation and gradients. Support will be added 5454261fa58Smacallan * over time and likely have to spill over into its own source file. 5464261fa58Smacallan */ 5474261fa58Smacallan 548a3a2ba44Smacallan if ((op != PictOpOver) && (op != PictOpAdd) && (op != PictOpSrc)) { 549fe97f391Smacallan DPRINTF(X_ERROR, "%s: rejecting %d\n", __func__, op); 5504261fa58Smacallan return FALSE; 5514261fa58Smacallan } 5524261fa58Smacallan 5534bd47ccfSmacallan if (pSrcPicture != NULL) { 5544bd47ccfSmacallan i = 0; 5554bd47ccfSmacallan while ((i < arraysize(src_formats)) && (!ok)) { 5564bd47ccfSmacallan ok = (pSrcPicture->format == src_formats[i]); 5574bd47ccfSmacallan i++; 5584bd47ccfSmacallan } 5594bd47ccfSmacallan 5604bd47ccfSmacallan if (!ok) { 5614bd47ccfSmacallan DPRINTF(X_ERROR, "%s: unsupported src format %x\n", 5624bd47ccfSmacallan __func__, pSrcPicture->format); 5634bd47ccfSmacallan return FALSE; 5644bd47ccfSmacallan } 5654bd47ccfSmacallan DPRINTF(X_ERROR, "src is %x, %d\n", pSrcPicture->format, op); 5664261fa58Smacallan } 5674261fa58Smacallan 5684bd47ccfSmacallan if (pDstPicture != NULL) { 5694bd47ccfSmacallan i = 0; 5704bd47ccfSmacallan ok = FALSE; 5714bd47ccfSmacallan while ((i < arraysize(src_formats)) && (!ok)) { 5724bd47ccfSmacallan ok = (pDstPicture->format == src_formats[i]); 5734bd47ccfSmacallan i++; 5744bd47ccfSmacallan } 5754bd47ccfSmacallan 5764bd47ccfSmacallan if (!ok) { 5774bd47ccfSmacallan DPRINTF(X_ERROR, "%s: unsupported dst format %x\n", 5784bd47ccfSmacallan __func__, pDstPicture->format); 5794bd47ccfSmacallan return FALSE; 5804bd47ccfSmacallan } 5814bd47ccfSmacallan DPRINTF(X_ERROR, "dst is %x, %d\n", pDstPicture->format, op); 5824bd47ccfSmacallan } 5834261fa58Smacallan 5844261fa58Smacallan if (pMaskPicture != NULL) { 5854261fa58Smacallan DPRINTF(X_ERROR, "mask is %x %d %d\n", pMaskPicture->format, 5864261fa58Smacallan pMaskPicture->pDrawable->width, 5874261fa58Smacallan pMaskPicture->pDrawable->height); 5884261fa58Smacallan } 5894261fa58Smacallan return TRUE; 5904261fa58Smacallan} 5914261fa58Smacallan 5924261fa58SmacallanBool 5934261fa58SmacallanCG14PrepareComposite(int op, PicturePtr pSrcPicture, 5944261fa58Smacallan PicturePtr pMaskPicture, 5954261fa58Smacallan PicturePtr pDstPicture, 5964261fa58Smacallan PixmapPtr pSrc, 5974261fa58Smacallan PixmapPtr pMask, 5984261fa58Smacallan PixmapPtr pDst) 5994261fa58Smacallan{ 6004261fa58Smacallan ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 6014261fa58Smacallan Cg14Ptr p = GET_CG14_FROM_SCRN(pScrn); 6024261fa58Smacallan 6034261fa58Smacallan ENTER; 6044261fa58Smacallan 605f7cb851fSmacallan p->no_source_pixmap = FALSE; 606f7cb851fSmacallan p->source_is_solid = FALSE; 607f7cb851fSmacallan 608a3a2ba44Smacallan if (pSrcPicture->format == PICT_a1) { 6096bdc2ffdSmacallan xf86Msg(X_ERROR, "src mono, dst %x, op %d\n", 6106bdc2ffdSmacallan pDstPicture->format, op); 611a3a2ba44Smacallan if (pMaskPicture != NULL) { 612a3a2ba44Smacallan xf86Msg(X_ERROR, "msk %x\n", pMaskPicture->format); 613a3a2ba44Smacallan } 614f7cb851fSmacallan } 6154261fa58Smacallan if (pSrcPicture->pSourcePict != NULL) { 6164261fa58Smacallan if (pSrcPicture->pSourcePict->type == SourcePictTypeSolidFill) { 6174261fa58Smacallan p->fillcolour = 6184261fa58Smacallan pSrcPicture->pSourcePict->solidFill.color; 619f7cb851fSmacallan DPRINTF(X_ERROR, "%s: solid src %08x\n", 6204261fa58Smacallan __func__, p->fillcolour); 621f7cb851fSmacallan p->no_source_pixmap = TRUE; 622f7cb851fSmacallan p->source_is_solid = TRUE; 6234261fa58Smacallan } 6244261fa58Smacallan } 6254261fa58Smacallan if ((pMaskPicture != NULL) && (pMaskPicture->pSourcePict != NULL)) { 6264261fa58Smacallan if (pMaskPicture->pSourcePict->type == 6274261fa58Smacallan SourcePictTypeSolidFill) { 6284261fa58Smacallan p->fillcolour = 6294261fa58Smacallan pMaskPicture->pSourcePict->solidFill.color; 630a3a2ba44Smacallan xf86Msg(X_ERROR, "%s: solid mask %08x\n", 6314261fa58Smacallan __func__, p->fillcolour); 6324261fa58Smacallan } 6334261fa58Smacallan } 6344261fa58Smacallan if (pMaskPicture != NULL) { 635239808baSmacallan p->mskoff = exaGetPixmapOffset(pMask); 6364261fa58Smacallan p->mskpitch = exaGetPixmapPitch(pMask); 6374261fa58Smacallan p->mskformat = pMaskPicture->format; 638a3a2ba44Smacallan } else { 639239808baSmacallan p->mskoff = 0; 640a3a2ba44Smacallan p->mskpitch = 0; 641a3a2ba44Smacallan p->mskformat = 0; 6424261fa58Smacallan } 643f7cb851fSmacallan if (pSrc != NULL) { 644f7cb851fSmacallan p->source_is_solid = 645f7cb851fSmacallan ((pSrc->drawable.width == 1) && (pSrc->drawable.height == 1)); 646f7cb851fSmacallan p->srcoff = exaGetPixmapOffset(pSrc); 647f7cb851fSmacallan p->srcpitch = exaGetPixmapPitch(pSrc); 648f7cb851fSmacallan if (p->source_is_solid) { 649f7cb851fSmacallan p->fillcolour = *(uint32_t *)(p->fb + p->srcoff); 650f7cb851fSmacallan } 651f7cb851fSmacallan } 6524261fa58Smacallan p->srcformat = pSrcPicture->format; 6534261fa58Smacallan p->dstformat = pDstPicture->format; 654f7cb851fSmacallan 655f7cb851fSmacallan if (p->source_is_solid) { 656f7cb851fSmacallan uint32_t temp; 657f7cb851fSmacallan 658f7cb851fSmacallan /* stuff source colour into SX registers, swap as needed */ 659f7cb851fSmacallan temp = p->fillcolour; 660f7cb851fSmacallan switch (p->srcformat) { 661f7cb851fSmacallan case PICT_a8r8g8b8: 662f7cb851fSmacallan case PICT_x8r8g8b8: 663f7cb851fSmacallan write_sx_reg(p, SX_QUEUED(9), temp & 0xff); 664f7cb851fSmacallan temp = temp >> 8; 665f7cb851fSmacallan write_sx_reg(p, SX_QUEUED(10), temp & 0xff); 666f7cb851fSmacallan temp = temp >> 8; 667f7cb851fSmacallan write_sx_reg(p, SX_QUEUED(11), temp & 0xff); 668f7cb851fSmacallan break; 669f7cb851fSmacallan case PICT_a8b8g8r8: 670f7cb851fSmacallan case PICT_x8b8g8r8: 671f7cb851fSmacallan write_sx_reg(p, SX_QUEUED(11), temp & 0xff); 672f7cb851fSmacallan temp = temp >> 8; 673f7cb851fSmacallan write_sx_reg(p, SX_QUEUED(10), temp & 0xff); 674f7cb851fSmacallan temp = temp >> 8; 675f7cb851fSmacallan write_sx_reg(p, SX_QUEUED(9), temp & 0xff); 676f7cb851fSmacallan break; 677f7cb851fSmacallan } 678f7cb851fSmacallan write_sx_reg(p, SX_QUEUED(8), 0xff); 679f7cb851fSmacallan } 6804261fa58Smacallan p->op = op; 681a3a2ba44Smacallan if (op == PictOpSrc) { 682a3a2ba44Smacallan CG14PrepareCopy(pSrc, pDst, 1, 1, GXcopy, 0xffffffff); 683a3a2ba44Smacallan } 6844261fa58Smacallan#ifdef SX_DEBUG 6854261fa58Smacallan DPRINTF(X_ERROR, "%x %x -> %x\n", p->srcoff, p->mskoff, 6864261fa58Smacallan *(uint32_t *)(p->fb + p->srcoff)); 6874261fa58Smacallan#endif 6884261fa58Smacallan return TRUE; 6894261fa58Smacallan} 6904261fa58Smacallan 6914261fa58Smacallanvoid 6924261fa58SmacallanCG14Composite(PixmapPtr pDst, int srcX, int srcY, 6934261fa58Smacallan int maskX, int maskY, 6944261fa58Smacallan int dstX, int dstY, 6954261fa58Smacallan int width, int height) 6964261fa58Smacallan{ 6974261fa58Smacallan ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 6984261fa58Smacallan Cg14Ptr p = GET_CG14_FROM_SCRN(pScrn); 6994261fa58Smacallan uint32_t dstoff, dstpitch; 7004261fa58Smacallan uint32_t dst, msk, src; 7014261fa58Smacallan 7024261fa58Smacallan ENTER; 7034261fa58Smacallan dstoff = exaGetPixmapOffset(pDst); 7044261fa58Smacallan dstpitch = exaGetPixmapPitch(pDst); 7054261fa58Smacallan 7064261fa58Smacallan switch (p->op) { 7074261fa58Smacallan case PictOpOver: 7084261fa58Smacallan dst = dstoff + (dstY * dstpitch) + (dstX << 2); 7094261fa58Smacallan DPRINTF(X_ERROR, "Over %08x %08x, %d %d\n", 7104261fa58Smacallan p->mskformat, p->dstformat, srcX, srcY); 711a3a2ba44Smacallan if (p->source_is_solid) { 712a3a2ba44Smacallan switch (p->mskformat) { 713a3a2ba44Smacallan case PICT_a8: 714a3a2ba44Smacallan msk = p->mskoff + 715a3a2ba44Smacallan (maskY * p->mskpitch) + 716a3a2ba44Smacallan maskX; 717a3a2ba44Smacallan CG14Comp_Over8Solid(p, 718a3a2ba44Smacallan msk, p->mskpitch, 719a3a2ba44Smacallan dst, dstpitch, 720a3a2ba44Smacallan width, height); 721a3a2ba44Smacallan break; 722a3a2ba44Smacallan case PICT_a8r8g8b8: 723a3a2ba44Smacallan case PICT_a8b8g8r8: 724a3a2ba44Smacallan msk = p->mskoff + 725a3a2ba44Smacallan (maskY * p->mskpitch) + 726a3a2ba44Smacallan (maskX << 2); 727a3a2ba44Smacallan CG14Comp_Over32Solid(p, 728a3a2ba44Smacallan msk, p->mskpitch, 729a3a2ba44Smacallan dst, dstpitch, 730a3a2ba44Smacallan width, height); 731a3a2ba44Smacallan break; 732a3a2ba44Smacallan default: 733a3a2ba44Smacallan xf86Msg(X_ERROR, 7346bdc2ffdSmacallan "unsupported mask format\n"); 735a3a2ba44Smacallan } 736a3a2ba44Smacallan } else { 7376bdc2ffdSmacallan DPRINTF(X_ERROR, "non-solid over with msk %x\n", 7386bdc2ffdSmacallan p->mskformat); 739a3a2ba44Smacallan switch (p->srcformat) { 740a3a2ba44Smacallan case PICT_a8r8g8b8: 741a3a2ba44Smacallan case PICT_a8b8g8r8: 742a3a2ba44Smacallan src = p->srcoff + 743a3a2ba44Smacallan (srcY * p->srcpitch) + 744a3a2ba44Smacallan (srcX << 2); 745a3a2ba44Smacallan dst = dstoff + 746a3a2ba44Smacallan (dstY * dstpitch) + 747a3a2ba44Smacallan (dstX << 2); 748a3a2ba44Smacallan if (p->mskformat == PICT_a8) { 749a3a2ba44Smacallan msk = p->mskoff + 750a3a2ba44Smacallan (maskY * p->mskpitch) + 751a3a2ba44Smacallan maskX; 752a3a2ba44Smacallan CG14Comp_Over32Mask(p, 753a3a2ba44Smacallan src, p->srcpitch, 754a3a2ba44Smacallan msk, p->mskpitch, 755a3a2ba44Smacallan dst, dstpitch, 756a3a2ba44Smacallan width, height); 757a3a2ba44Smacallan } else { 758a3a2ba44Smacallan CG14Comp_Over32(p, 759a3a2ba44Smacallan src, p->srcpitch, 760a3a2ba44Smacallan dst, dstpitch, 761a3a2ba44Smacallan width, height); 762a3a2ba44Smacallan } 763a3a2ba44Smacallan break; 764a3a2ba44Smacallan case PICT_x8r8g8b8: 765a3a2ba44Smacallan case PICT_x8b8g8r8: 7666bdc2ffdSmacallan src = p->srcoff + 7676bdc2ffdSmacallan (srcY * p->srcpitch) + 7686bdc2ffdSmacallan (srcX << 2); 7696bdc2ffdSmacallan dst = dstoff + 7706bdc2ffdSmacallan (dstY * dstpitch) + 7716bdc2ffdSmacallan (dstX << 2); 7726bdc2ffdSmacallan if (p->mskformat == PICT_a8) { 7736bdc2ffdSmacallan msk = p->mskoff + 7746bdc2ffdSmacallan (maskY * p->mskpitch) + 7756bdc2ffdSmacallan maskX; 7766bdc2ffdSmacallan CG14Comp_Over32Mask_noalpha(p, 7776bdc2ffdSmacallan src, p->srcpitch, 7786bdc2ffdSmacallan msk, p->mskpitch, 779fa158432Smacallan dst, dstpitch, 780fa158432Smacallan width, height); 781fa158432Smacallan } else if ((p->mskformat == PICT_a8r8g8b8) || 782fa158432Smacallan (p->mskformat == PICT_a8b8g8r8)) { 783fa158432Smacallan msk = p->mskoff + 784fa158432Smacallan (maskY * p->mskpitch) + 785fa158432Smacallan (maskX << 2); 786fa158432Smacallan CG14Comp_Over32Mask32_noalpha(p, 787fa158432Smacallan src, p->srcpitch, 788fa158432Smacallan msk, p->mskpitch, 7896bdc2ffdSmacallan dst, dstpitch, 7906bdc2ffdSmacallan width, height); 7916bdc2ffdSmacallan } else { 7926bdc2ffdSmacallan xf86Msg(X_ERROR, "no src alpha, mask is %x\n", p->mskformat); 7936bdc2ffdSmacallan } 794a3a2ba44Smacallan break; 795a3a2ba44Smacallan default: 796a3a2ba44Smacallan xf86Msg(X_ERROR, "%s: format %x in non-solid Over op\n", 797a3a2ba44Smacallan __func__, p->srcformat); 798a3a2ba44Smacallan } 799a3a2ba44Smacallan } 8004261fa58Smacallan break; 8014261fa58Smacallan case PictOpAdd: 8024261fa58Smacallan DPRINTF(X_ERROR, "Add %08x %08x\n", 8034261fa58Smacallan p->srcformat, p->dstformat); 8044261fa58Smacallan switch (p->srcformat) { 8054261fa58Smacallan case PICT_a8: 8064261fa58Smacallan src = p->srcoff + 8074261fa58Smacallan (srcY * p->srcpitch) + srcX; 8084261fa58Smacallan dst = dstoff + (dstY * dstpitch) + dstX; 8094261fa58Smacallan CG14Comp_Add8(p, src, p->srcpitch, 8104261fa58Smacallan dst, dstpitch, width, height); 8114261fa58Smacallan break; 8124261fa58Smacallan case PICT_a8r8g8b8: 8134261fa58Smacallan case PICT_x8r8g8b8: 8144261fa58Smacallan src = p->srcoff + 8154261fa58Smacallan (srcY * p->srcpitch) + (srcX << 2); 8164261fa58Smacallan dst = dstoff + (dstY * dstpitch) + 8174261fa58Smacallan (dstX << 2); 8184261fa58Smacallan CG14Comp_Add32(p, src, p->srcpitch, 8194261fa58Smacallan dst, dstpitch, width, height); 8204261fa58Smacallan break; 8214261fa58Smacallan default: 8224261fa58Smacallan xf86Msg(X_ERROR, 8234261fa58Smacallan "unsupported src format\n"); 8244261fa58Smacallan } 8254261fa58Smacallan break; 826a3a2ba44Smacallan case PictOpSrc: 827a3a2ba44Smacallan DPRINTF(X_ERROR, "Src %08x %08x\n", 828a3a2ba44Smacallan p->srcformat, p->dstformat); 829239808baSmacallan if (p->mskformat != 0) 830239808baSmacallan xf86Msg(X_ERROR, "Src mask %08x\n", p->mskformat); 831a3a2ba44Smacallan CG14Copy(pDst, srcX, srcY, dstX, dstY, width, height); 832a3a2ba44Smacallan break; 8334261fa58Smacallan default: 8344261fa58Smacallan xf86Msg(X_ERROR, "unsupported op %d\n", p->op); 8354261fa58Smacallan } 8364261fa58Smacallan exaMarkSync(pDst->drawable.pScreen); 8374261fa58Smacallan} 8384261fa58Smacallan 8394261fa58Smacallan 8404261fa58Smacallan 8414261fa58SmacallanBool 8424261fa58SmacallanCG14InitAccel(ScreenPtr pScreen) 8434261fa58Smacallan{ 8444261fa58Smacallan ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 8454261fa58Smacallan Cg14Ptr p = GET_CG14_FROM_SCRN(pScrn); 8464261fa58Smacallan ExaDriverPtr pExa; 8474261fa58Smacallan 8484261fa58Smacallan pExa = exaDriverAlloc(); 8494261fa58Smacallan if (!pExa) 8504261fa58Smacallan return FALSE; 8514261fa58Smacallan 8524261fa58Smacallan p->pExa = pExa; 8534261fa58Smacallan 8544261fa58Smacallan pExa->exa_major = EXA_VERSION_MAJOR; 8554261fa58Smacallan pExa->exa_minor = EXA_VERSION_MINOR; 8564261fa58Smacallan 8574261fa58Smacallan pExa->memoryBase = p->fb; 8584261fa58Smacallan pExa->memorySize = p->memsize; 8594261fa58Smacallan pExa->offScreenBase = p->width * p->height * 4; 8604261fa58Smacallan 8614261fa58Smacallan /* 8624261fa58Smacallan * SX memory instructions are written to 64bit aligned addresses with 8634261fa58Smacallan * a 3 bit displacement. Make sure the displacement remains constant 8644261fa58Smacallan * within one column 8654261fa58Smacallan */ 8664261fa58Smacallan 8674261fa58Smacallan pExa->pixmapOffsetAlign = 8; 8684261fa58Smacallan pExa->pixmapPitchAlign = 8; 8694261fa58Smacallan 870fe97f391Smacallan pExa->flags = EXA_OFFSCREEN_PIXMAPS 871fe97f391Smacallan /* | EXA_SUPPORTS_OFFSCREEN_OVERLAPS |*/ 872fe97f391Smacallan | EXA_MIXED_PIXMAPS; 8734261fa58Smacallan 8744261fa58Smacallan /* 8754261fa58Smacallan * these limits are bogus 8764261fa58Smacallan * SX doesn't deal with coordinates at all, so there is no limit but 8774261fa58Smacallan * we have to put something here 8784261fa58Smacallan */ 8794261fa58Smacallan pExa->maxX = 4096; 8804261fa58Smacallan pExa->maxY = 4096; 8814261fa58Smacallan 8824261fa58Smacallan pExa->WaitMarker = CG14WaitMarker; 8834261fa58Smacallan 8844261fa58Smacallan pExa->PrepareSolid = CG14PrepareSolid; 8854261fa58Smacallan pExa->Solid = CG14Solid; 8864261fa58Smacallan pExa->DoneSolid = CG14DoneCopy; 8874261fa58Smacallan pExa->PrepareCopy = CG14PrepareCopy; 8884261fa58Smacallan pExa->Copy = CG14Copy; 8894261fa58Smacallan pExa->DoneCopy = CG14DoneCopy; 8904261fa58Smacallan if (p->use_xrender) { 8914261fa58Smacallan pExa->CheckComposite = CG14CheckComposite; 8924261fa58Smacallan pExa->PrepareComposite = CG14PrepareComposite; 8934261fa58Smacallan pExa->Composite = CG14Composite; 8944261fa58Smacallan pExa->DoneComposite = CG14DoneCopy; 8954261fa58Smacallan } 8964261fa58Smacallan 8974261fa58Smacallan /* EXA hits more optimized paths when it does not have to fallback 8984261fa58Smacallan * because of missing UTS/DFS, hook memcpy-based UTS/DFS. 8994261fa58Smacallan */ 9004261fa58Smacallan pExa->UploadToScreen = CG14UploadToScreen; 9014261fa58Smacallan pExa->DownloadFromScreen = CG14DownloadFromScreen; 9024261fa58Smacallan 9034261fa58Smacallan /* do some hardware init */ 9044261fa58Smacallan write_sx_reg(p, SX_PLANEMASK, 0xffffffff); 9054261fa58Smacallan p->last_mask = 0xffffffff; 9064261fa58Smacallan write_sx_reg(p, SX_ROP_CONTROL, 0xcc); 9074261fa58Smacallan p->last_rop = 0xcc; 9084261fa58Smacallan return exaDriverInit(pScreen, pExa); 9094261fa58Smacallan} 910