ffb_exa.c revision 89b0bd4c
1/* $NetBSD: ffb_exa.c,v 1.1 2015/08/11 03:57:36 macallan Exp $ */ 2/* 3 * Copyright (c) 2015 Michael Lorenz 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * - Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * - Redistributions in binary form must reproduce the above 13 * copyright notice, this list of conditions and the following 14 * disclaimer in the documentation and/or other materials provided 15 * with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 21 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 * 30 */ 31 32#include <sys/types.h> 33 34/* all driver need this */ 35#include "xf86.h" 36#include "xf86_OSproc.h" 37#include "compiler.h" 38#include "exa.h" 39 40#include "ffb_fifo.h" 41#include "ffb_rcache.h" 42#include "ffb.h" 43#include "ffb_regs.h" 44 45extern void VISmoveImageRL(unsigned char *, unsigned char *, long, long, long, long); 46extern void VISmoveImageLR(unsigned char *, unsigned char *, long, long, long, long); 47 48/*#define FFB_DEBUG*/ 49 50#ifdef FFB_DEBUG 51#define ENTER xf86Msg(X_ERROR, "%s>\n", __func__); 52#define DPRINTF xf86Msg 53#else 54#define ENTER 55#define DPRINTF while (0) xf86Msg 56#endif 57 58static void 59FFBWaitMarker(ScreenPtr pScreen, int Marker) 60{ 61 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 62 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 63 ffb_fbcPtr ffb = pFfb->regs; 64 65 FFBWait(pFfb, ffb); 66} 67 68static Bool 69FFBPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, 70 int xdir, int ydir, int alu, Pixel planemask) 71{ 72 ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 73 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 74 ffb_fbcPtr ffb = pFfb->regs; 75 76 ENTER; 77 pFfb->srcpitch = exaGetPixmapPitch(pSrcPixmap); 78 pFfb->srcoff = exaGetPixmapOffset(pSrcPixmap); 79 pFfb->xdir = xdir; 80 pFfb->ydir = ydir; 81 pFfb->rop = alu; 82 pFfb->planemask = planemask; 83 return TRUE; 84} 85 86static void 87FFBCopy(PixmapPtr pDstPixmap, 88 int srcX, int srcY, int dstX, int dstY, int w, int h) 89{ 90 ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 91 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 92 ffb_fbcPtr ffb = pFfb->regs; 93 unsigned char *src, *dst, *sfb32; 94 int psz_shift = 2; 95 int sdkind; 96 97 ENTER; 98 if ((srcX == dstX) && (srcY != dstY) && (pFfb->rop == GXcopy)) { 99 /* we can use the vscroll command */ 100 FFB_ATTR_VSCROLL_XAA(pFfb, pFfb->planemask); 101 FFBFifo(pFfb, 7); 102 ffb->drawop = FFB_DRAWOP_VSCROLL; 103 FFB_WRITE64(&ffb->by, srcY, srcX); 104 FFB_WRITE64_2(&ffb->dy, dstY, dstX); 105 FFB_WRITE64_3(&ffb->bh, h, w); 106 exaMarkSync(pDstPixmap->drawable.pScreen); 107 return; 108 } 109 FFB_ATTR_SFB_VAR_XAA(pFfb, pFfb->planemask, pFfb->rop); 110 FFBWait(pFfb, ffb); 111 sfb32 = (unsigned char *) pFfb->sfb32; 112 src = sfb32 + (srcY * (2048 << psz_shift)) + (srcX << psz_shift); 113 dst = sfb32 + (dstY * (2048 << psz_shift)) + (dstX << psz_shift); 114 sdkind = (2048 << psz_shift); 115 116 if (pFfb->ydir < 0) { 117 src += ((h - 1) * (2048 << psz_shift)); 118 dst += ((h - 1) * (2048 << psz_shift)); 119 sdkind = -sdkind; 120 } 121 w <<= psz_shift; 122 if (pFfb->xdir < 0) 123 VISmoveImageRL(src, dst, w, h, sdkind, sdkind); 124 else 125 VISmoveImageLR(src, dst, w, h, sdkind, sdkind); 126} 127 128static void 129FFBDoneCopy(PixmapPtr pDstPixmap) 130{ 131} 132 133static Bool 134FFBPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) 135{ 136 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 137 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 138 ffb_fbcPtr ffb = pFfb->regs; 139 unsigned int ppc, ppc_mask, fbc; 140 141 ENTER; 142 FFBWait(pFfb, ffb); 143 pFfb->planemask = planemask; 144 pFfb->rop = alu; 145 146 fbc = pFfb->fbc; 147 if (pFfb->ffb_res == ffb_res_high) 148 fbc |= FFB_FBC_WB_B; 149 ppc = FFB_PPC_ABE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST | FFB_PPC_XS_WID; 150 ppc_mask = FFB_PPC_ABE_MASK | FFB_PPC_APE_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK; 151 152 FFB_ATTR_RAW(pFfb, ppc, ppc_mask, planemask, 153 (FFB_ROP_EDIT_BIT | alu) | (FFB_ROP_NEW << 8), 154 FFB_DRAWOP_RECTANGLE, fg, fbc, pFfb->wid); 155 156 return TRUE; 157} 158 159static void 160FFBSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) 161{ 162 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 163 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 164 ffb_fbcPtr ffb = pFfb->regs; 165 166 ENTER; 167 FFBFifo(pFfb, 4); 168 FFB_WRITE64(&ffb->by, y1, x1); 169 FFB_WRITE64_2(&ffb->bh, y2 - y1, x2 - x1); 170 exaMarkSync(pPixmap->drawable.pScreen); 171} 172 173static Bool 174FFBUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, 175 char *src, int src_pitch) 176{ 177 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 178 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 179 unsigned char *dst, *sfb32; 180 int psz_shift = 2; 181 ffb_fbcPtr ffb = pFfb->regs; 182 183 ENTER; 184 FFB_ATTR_SFB_VAR_XAA(pFfb, 0xffffffff, GXcopy); 185 FFBWait(pFfb, ffb); 186 187 sfb32 = (unsigned char *) pFfb->sfb32; 188 dst = sfb32 + (y * (2048 << psz_shift)) + (x << psz_shift); 189 VISmoveImageLR(src, dst, w << psz_shift, h, 190 src_pitch, (2048 << psz_shift)); 191 return TRUE; 192} 193 194static Bool 195FFBDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, 196 char *dst, int dst_pitch) 197{ 198 ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum]; 199 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 200 unsigned char *src, *sfb32; 201 int psz_shift = 2; 202 ffb_fbcPtr ffb = pFfb->regs; 203 204 ENTER; 205 FFB_ATTR_SFB_VAR_XAA(pFfb, 0xffffffff, GXcopy); 206 FFBWait(pFfb, ffb); 207 208 sfb32 = (unsigned char *) pFfb->sfb32; 209 src = sfb32 + (y * (2048 << psz_shift)) + (x << psz_shift); 210 VISmoveImageLR(src, dst, w << psz_shift, h, 211 (2048 << psz_shift), dst_pitch); 212 return TRUE; 213} 214 215#if 0 216 217Bool 218FFBCheckComposite(int op, PicturePtr pSrcPicture, 219 PicturePtr pMaskPicture, 220 PicturePtr pDstPicture) 221{ 222 return FALSE; 223} 224 225Bool 226FFBPrepareComposite(int op, PicturePtr pSrcPicture, 227 PicturePtr pMaskPicture, 228 PicturePtr pDstPicture, 229 PixmapPtr pSrc, 230 PixmapPtr pMask, 231 PixmapPtr pDst) 232{ 233 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 234 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 235 236 ENTER; 237 return FALSE; 238} 239 240void 241FFBComposite(PixmapPtr pDst, int srcX, int srcY, 242 int maskX, int maskY, 243 int dstX, int dstY, 244 int width, int height) 245{ 246 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 247 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 248 exaMarkSync(pDst->drawable.pScreen); 249} 250 251#endif 252 253static Bool 254FFBPrepareAccess(PixmapPtr pPix, int index) 255{ 256 ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum]; 257 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 258 ffb_fbcPtr ffb = pFfb->regs; 259 260 ENTER; 261 FFB_ATTR_SFB_VAR_XAA(pFfb, 0xffffffff, GXcopy); 262 FFBWait(pFfb, ffb); 263 264 return TRUE; 265} 266 267static void 268FFBFinishAccess(PixmapPtr pPix, int index) 269{ 270} 271 272Bool 273FFBInitEXA(ScreenPtr pScreen) 274{ 275 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 276 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 277 ffb_fbcPtr ffb = pFfb->regs; 278 ExaDriverPtr pExa; 279 280 pFfb->fbc = (FFB_FBC_WB_A | FFB_FBC_WM_COMBINED | FFB_FBC_RB_A | 281 FFB_FBC_WE_FORCEON | 282 FFB_FBC_SB_BOTH | 283 FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF | 284 FFB_FBC_RGBE_MASK | 285 FFB_FBC_XE_ON); 286 pFfb->wid = FFBWidAlloc(pFfb, TrueColor, 0, TRUE); 287 if (pFfb->wid == (unsigned int) -1) 288 return FALSE; 289 290 pFfb->ppc_cache = (FFB_PPC_FW_DISABLE | 291 FFB_PPC_VCE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST | 292 FFB_PPC_XS_WID | FFB_PPC_YS_CONST | FFB_PPC_ZS_CONST | 293 FFB_PPC_DCE_DISABLE | FFB_PPC_ABE_DISABLE | FFB_PPC_TBE_OPAQUE); 294 pFfb->wid_cache = pFfb->wid; 295 pFfb->pmask_cache = ~0; 296 pFfb->rop_cache = (FFB_ROP_NEW | (FFB_ROP_NEW << 8)); 297 pFfb->drawop_cache = FFB_DRAWOP_RECTANGLE; 298 pFfb->fg_cache = pFfb->bg_cache = 0; 299 pFfb->fontw_cache = 32; 300 pFfb->fontinc_cache = (1 << 16) | 0; 301 pFfb->fbc_cache = (FFB_FBC_WB_A | FFB_FBC_WM_COMBINED | FFB_FBC_RB_A | 302 FFB_FBC_WE_FORCEON | 303 FFB_FBC_SB_BOTH | 304 FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF | 305 FFB_FBC_RGBE_OFF | 306 FFB_FBC_XE_ON); 307 308 /* We will now clear the screen: we'll draw a rectangle covering all the 309 * viewscreen, using a 'blackness' ROP. 310 */ 311 FFBFifo(pFfb, 22); 312 ffb->fbc = pFfb->fbc_cache; 313 ffb->ppc = pFfb->ppc_cache; 314 ffb->wid = pFfb->wid_cache; 315 ffb->xpmask = 0xff; 316 ffb->pmask = pFfb->pmask_cache; 317 ffb->rop = pFfb->rop_cache; 318 ffb->drawop = pFfb->drawop_cache; 319 ffb->fg = pFfb->fg_cache; 320 ffb->bg = pFfb->bg_cache; 321 ffb->fontw = pFfb->fontw_cache; 322 ffb->fontinc = pFfb->fontinc_cache; 323 ffb->xclip = FFB_XCLIP_TEST_ALWAYS; 324 ffb->cmp = 0x80808080; 325 ffb->matchab = 0x80808080; 326 ffb->magnab = 0x80808080; 327 ffb->blendc = (FFB_BLENDC_FORCE_ONE | 328 FFB_BLENDC_DF_ONE_M_A | 329 FFB_BLENDC_SF_A); 330 ffb->blendc1 = 0; 331 ffb->blendc2 = 0; 332 FFB_WRITE64(&ffb->by, 0, 0); 333 FFB_WRITE64_2(&ffb->bh, pFfb->psdp->height, pFfb->psdp->width); 334 FFBWait(pFfb, ffb); 335 336 FFB_ATTR_SFB_VAR_XAA(pFfb, 0xffffffff, GXcopy); 337 FFBWait(pFfb, ffb); 338 339 pExa = exaDriverAlloc(); 340 if (!pExa) 341 return FALSE; 342 343 pFfb->pExa = pExa; 344 345 pExa->exa_major = EXA_VERSION_MAJOR; 346 pExa->exa_minor = EXA_VERSION_MINOR; 347 348 349 pExa->memoryBase = (char *)pFfb->sfb32; 350 /* 351 * we don't have usable off-screen memory but EXA craps out if we don't 352 * pretend that we do, so register a ridiculously small amount and 353 * cross fingers 354 */ 355 pExa->memorySize = 8192 * pFfb->psdp->height + 4; 356 pExa->offScreenBase = pExa->memorySize - 4; 357 358 /* we want to use 64bit aligned accesses */ 359 pExa->pixmapOffsetAlign = 8; 360 pExa->pixmapPitchAlign = 8; 361 362 pExa->flags = EXA_OFFSCREEN_PIXMAPS | 363 /*EXA_SUPPORTS_OFFSCREEN_OVERLAPS |*/ 364 EXA_MIXED_PIXMAPS; 365 366 pExa->maxX = 2048; 367 pExa->maxY = 2048; 368 369 pExa->WaitMarker = FFBWaitMarker; 370 371 pExa->PrepareSolid = FFBPrepareSolid; 372 pExa->Solid = FFBSolid; 373 pExa->DoneSolid = FFBDoneCopy; 374 pExa->PrepareCopy = FFBPrepareCopy; 375 pExa->Copy = FFBCopy; 376 pExa->DoneCopy = FFBDoneCopy; 377 pExa->UploadToScreen = FFBUploadToScreen; 378 pExa->DownloadFromScreen = FFBDownloadFromScreen; 379 pExa->PrepareAccess = FFBPrepareAccess; 380 pExa->FinishAccess = FFBFinishAccess; 381#if 0 382 pExa->CheckComposite = CG14CheckComposite; 383 pExa->PrepareComposite = CG14PrepareComposite; 384 pExa->Composite = CG14Composite; 385 pExa->DoneComposite = CG14DoneCopy; 386#endif 387 388 return exaDriverInit(pScreen, pExa); 389} 390