ffb_exa.c revision f1295e53
1/* $NetBSD: ffb_exa.c,v 1.3 2016/08/19 19:16:01 mrg 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#include "ffb_fifo.h" 35#include "ffb_rcache.h" 36#include "ffb.h" 37#include "ffb_regs.h" 38 39/* all driver need this */ 40#include "xf86.h" 41#include "xf86_OSproc.h" 42#include "compiler.h" 43#include "exa.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 58#define arraysize(ary) (sizeof(ary) / sizeof(ary[0])) 59 60int src_formats[] = {PICT_a8r8g8b8, PICT_x8r8g8b8, 61 PICT_a8b8g8r8, PICT_x8b8g8r8, PICT_a8}; 62int tex_formats[] = {PICT_a8r8g8b8, PICT_a8b8g8r8, PICT_a8}; 63 64static void 65FFBWaitMarker(ScreenPtr pScreen, int Marker) 66{ 67 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 68 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 69 ffb_fbcPtr ffb = pFfb->regs; 70 71 FFBWait(pFfb, ffb); 72} 73 74static Bool 75FFBPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, 76 int xdir, int ydir, int alu, Pixel planemask) 77{ 78 ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 79 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 80 ffb_fbcPtr ffb = pFfb->regs; 81 82 ENTER; 83 pFfb->srcpitch = exaGetPixmapPitch(pSrcPixmap); 84 pFfb->srcoff = exaGetPixmapOffset(pSrcPixmap); 85 pFfb->xdir = xdir; 86 pFfb->ydir = ydir; 87 pFfb->rop = alu; 88 pFfb->planemask = planemask; 89 return TRUE; 90} 91 92static void 93FFBCopy(PixmapPtr pDstPixmap, 94 int srcX, int srcY, int dstX, int dstY, int w, int h) 95{ 96 ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 97 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 98 ffb_fbcPtr ffb = pFfb->regs; 99 unsigned char *src, *dst, *sfb32; 100 int psz_shift = 2; 101 int sdkind; 102 103 ENTER; 104 if ((srcX == dstX) && (srcY != dstY) && (pFfb->rop == GXcopy)) { 105 /* we can use the vscroll command */ 106 FFB_ATTR_VSCROLL_XAA(pFfb, pFfb->planemask); 107 FFBFifo(pFfb, 7); 108 ffb->drawop = FFB_DRAWOP_VSCROLL; 109 FFB_WRITE64(&ffb->by, srcY, srcX); 110 FFB_WRITE64_2(&ffb->dy, dstY, dstX); 111 FFB_WRITE64_3(&ffb->bh, h, w); 112 exaMarkSync(pDstPixmap->drawable.pScreen); 113 return; 114 } 115 FFB_ATTR_SFB_VAR_XAA(pFfb, pFfb->planemask, pFfb->rop); 116 if (pFfb->use_blkread_prefetch) { 117 FFBFifo(pFfb, 1); 118 if (pFfb->xdir < 0) 119 ffb->mer = FFB_MER_EDRA; 120 else 121 ffb->mer = FFB_MER_EIRA; 122 } 123 FFBWait(pFfb, ffb); 124 sfb32 = (unsigned char *) pFfb->sfb32; 125 src = sfb32 + (srcY * (2048 << psz_shift)) + (srcX << psz_shift); 126 dst = sfb32 + (dstY * (2048 << psz_shift)) + (dstX << psz_shift); 127 sdkind = (2048 << psz_shift); 128 129 if (pFfb->ydir < 0) { 130 src += ((h - 1) * (2048 << psz_shift)); 131 dst += ((h - 1) * (2048 << psz_shift)); 132 sdkind = -sdkind; 133 } 134 w <<= psz_shift; 135 if (pFfb->xdir < 0) 136 VISmoveImageRL(src, dst, w, h, sdkind, sdkind); 137 else 138 VISmoveImageLR(src, dst, w, h, sdkind, sdkind); 139 if (pFfb->use_blkread_prefetch) { 140 FFBFifo(pFfb, 1); 141 ffb->mer = FFB_MER_DRA; 142 } 143} 144 145static void 146FFBDoneCopy(PixmapPtr pDstPixmap) 147{ 148} 149 150static Bool 151FFBPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) 152{ 153 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 154 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 155 ffb_fbcPtr ffb = pFfb->regs; 156 unsigned int ppc, ppc_mask, fbc; 157 158 ENTER; 159 FFBWait(pFfb, ffb); 160 pFfb->planemask = planemask; 161 pFfb->rop = alu; 162 163 fbc = pFfb->fbc; 164 if (pFfb->ffb_res == ffb_res_high) 165 fbc |= FFB_FBC_WB_B; 166 ppc = FFB_PPC_ABE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST | FFB_PPC_XS_WID; 167 ppc_mask = FFB_PPC_ABE_MASK | FFB_PPC_APE_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK; 168 169 FFB_ATTR_RAW(pFfb, ppc, ppc_mask, planemask, 170 (FFB_ROP_EDIT_BIT | alu) | (FFB_ROP_NEW << 8), 171 FFB_DRAWOP_RECTANGLE, fg, fbc, pFfb->wid); 172 173 return TRUE; 174} 175 176static void 177FFBSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) 178{ 179 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 180 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 181 ffb_fbcPtr ffb = pFfb->regs; 182 183 ENTER; 184 FFBFifo(pFfb, 4); 185 FFB_WRITE64(&ffb->by, y1, x1); 186 FFB_WRITE64_2(&ffb->bh, y2 - y1, x2 - x1); 187 exaMarkSync(pPixmap->drawable.pScreen); 188} 189 190static Bool 191FFBUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, 192 char *src, int src_pitch) 193{ 194 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 195 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 196 unsigned char *dst, *sfb32; 197 int psz_shift = 2; 198 ffb_fbcPtr ffb = pFfb->regs; 199 200 ENTER; 201 FFB_ATTR_SFB_VAR_XAA(pFfb, 0xffffffff, GXcopy); 202 FFBWait(pFfb, ffb); 203 204 sfb32 = (unsigned char *) pFfb->sfb32; 205 dst = sfb32 + (y * (2048 << psz_shift)) + (x << psz_shift); 206 VISmoveImageLR(src, dst, w << psz_shift, h, 207 src_pitch, (2048 << psz_shift)); 208 return TRUE; 209} 210 211static Bool 212FFBDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, 213 char *dst, int dst_pitch) 214{ 215 ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum]; 216 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 217 unsigned char *src, *sfb32; 218 int psz_shift = 2; 219 ffb_fbcPtr ffb = pFfb->regs; 220 221 ENTER; 222 FFB_ATTR_SFB_VAR_XAA(pFfb, 0xffffffff, GXcopy); 223 if (pFfb->use_blkread_prefetch) { 224 FFBFifo(pFfb, 1); 225 ffb->mer = FFB_MER_EIRA; 226 } 227 FFBWait(pFfb, ffb); 228 229 sfb32 = (unsigned char *) pFfb->sfb32; 230 src = sfb32 + (y * (2048 << psz_shift)) + (x << psz_shift); 231 VISmoveImageLR(src, dst, w << psz_shift, h, 232 (2048 << psz_shift), dst_pitch); 233 if (pFfb->use_blkread_prefetch) { 234 FFBFifo(pFfb, 1); 235 ffb->mer = FFB_MER_DRA; 236 } 237 return TRUE; 238} 239 240static Bool 241FFBCheckComposite(int op, PicturePtr pSrcPicture, 242 PicturePtr pMaskPicture, 243 PicturePtr pDstPicture) 244{ 245 int i, ok = FALSE; 246 247 ENTER; 248 249 i = 0; 250 while ((i < arraysize(src_formats)) && (!ok)) { 251 ok = (pSrcPicture->format == src_formats[i]); 252 i++; 253 } 254 255 if (!ok) { 256 xf86Msg(X_ERROR, "%s: unsupported src format %x\n", 257 __func__, pSrcPicture->format); 258 return FALSE; 259 } 260 261 DPRINTF(X_ERROR, "src is %x, %d: %d %d\n", pSrcPicture->format, op, 262 pSrcPicture->pDrawable->width, pSrcPicture->pDrawable->height); 263 264 if (pMaskPicture != NULL) { 265 DPRINTF(X_ERROR, "mask is %x %d %d\n", pMaskPicture->format, 266 pMaskPicture->pDrawable->width, 267 pMaskPicture->pDrawable->height); 268 } 269 return TRUE; 270} 271 272static Bool 273FFBPrepareComposite(int op, PicturePtr pSrcPicture, 274 PicturePtr pMaskPicture, 275 PicturePtr pDstPicture, 276 PixmapPtr pSrc, 277 PixmapPtr pMask, 278 PixmapPtr pDst) 279{ 280 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 281 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 282 283 ENTER; 284 285 pFfb->no_source_pixmap = FALSE; 286 pFfb->source_is_solid = FALSE; 287 288 if (pSrcPicture->format == PICT_a1) { 289 xf86Msg(X_ERROR, "src mono, dst %x, op %d\n", 290 pDstPicture->format, op); 291 if (pMaskPicture != NULL) { 292 xf86Msg(X_ERROR, "msk %x\n", pMaskPicture->format); 293 } 294 } 295 if (pSrcPicture->pSourcePict != NULL) { 296 if (pSrcPicture->pSourcePict->type == SourcePictTypeSolidFill) { 297 pFfb->fillcolour = 298 pSrcPicture->pSourcePict->solidFill.color; 299 DPRINTF(X_ERROR, "%s: solid src %08x\n", 300 __func__, pFfb->fillcolour); 301 pFfb->no_source_pixmap = TRUE; 302 pFfb->source_is_solid = TRUE; 303 } 304 } 305 if ((pMaskPicture != NULL) && (pMaskPicture->pSourcePict != NULL)) { 306 if (pMaskPicture->pSourcePict->type == 307 SourcePictTypeSolidFill) { 308 pFfb->fillcolour = 309 pMaskPicture->pSourcePict->solidFill.color; 310 xf86Msg(X_ERROR, "%s: solid mask %08x\n", 311 __func__, pFfb->fillcolour); 312 } 313 } 314 if (pMaskPicture != NULL) { 315 pFfb->mskoff = exaGetPixmapOffset(pMask); 316 pFfb->mskpitch = exaGetPixmapPitch(pMask); 317 pFfb->mskformat = pMaskPicture->format; 318 } else { 319 pFfb->mskoff = 0; 320 pFfb->mskpitch = 0; 321 pFfb->mskformat = 0; 322 } 323 if (pSrc != NULL) { 324 pFfb->source_is_solid = 325 ((pSrc->drawable.width == 1) && (pSrc->drawable.height == 1)); 326 pFfb->srcoff = exaGetPixmapOffset(pSrc); 327 pFfb->srcpitch = exaGetPixmapPitch(pSrc); 328 if (pFfb->source_is_solid) { 329 pFfb->fillcolour = *(uint32_t *)(pFfb->fb + pFfb->srcoff); 330 } 331 } 332 pFfb->srcformat = pSrcPicture->format; 333 pFfb->dstformat = pDstPicture->format; 334 335 if (pFfb->source_is_solid) { 336 uint32_t temp; 337 338 /* swap solid source as needed */ 339 switch (pFfb->srcformat) { 340 case PICT_a8r8g8b8: 341 case PICT_x8r8g8b8: 342 temp = (pFfb->fillcolour & 0x000000ff) << 16; 343 temp |= (pFfb->fillcolour & 0x00ff0000) >> 16; 344 temp |= (pFfb->fillcolour & 0xff00ff00); 345 pFfb->fillcolour = temp; 346 break; 347 } 348 } 349 pFfb->op = op; 350 return TRUE; 351} 352 353static void 354FFBComposite(PixmapPtr pDst, int srcX, int srcY, 355 int maskX, int maskY, 356 int dstX, int dstY, 357 int width, int height) 358{ 359 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 360 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 361 exaMarkSync(pDst->drawable.pScreen); 362} 363 364static Bool 365FFBPrepareAccess(PixmapPtr pPix, int index) 366{ 367 ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum]; 368 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 369 ffb_fbcPtr ffb = pFfb->regs; 370 371 ENTER; 372 FFB_ATTR_SFB_VAR_XAA(pFfb, 0xffffffff, GXcopy); 373 FFBWait(pFfb, ffb); 374 375 return TRUE; 376} 377 378static void 379FFBFinishAccess(PixmapPtr pPix, int index) 380{ 381} 382 383Bool 384FFBInitEXA(ScreenPtr pScreen) 385{ 386 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 387 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 388 ffb_fbcPtr ffb = pFfb->regs; 389 ExaDriverPtr pExa; 390 391 pFfb->fbc = (FFB_FBC_WB_A | FFB_FBC_WM_COMBINED | FFB_FBC_RB_A | 392 FFB_FBC_WE_FORCEON | 393 FFB_FBC_SB_BOTH | 394 FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF | 395 FFB_FBC_RGBE_MASK | 396 FFB_FBC_XE_ON); 397 pFfb->wid = FFBWidAlloc(pFfb, TrueColor, 0, TRUE); 398 if (pFfb->wid == (unsigned int) -1) 399 return FALSE; 400 401 pFfb->ppc_cache = (FFB_PPC_FW_DISABLE | 402 FFB_PPC_VCE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST | 403 FFB_PPC_XS_WID | FFB_PPC_YS_CONST | FFB_PPC_ZS_CONST | 404 FFB_PPC_DCE_DISABLE | FFB_PPC_ABE_DISABLE | FFB_PPC_TBE_OPAQUE); 405 pFfb->wid_cache = pFfb->wid; 406 pFfb->pmask_cache = ~0; 407 pFfb->rop_cache = (FFB_ROP_NEW | (FFB_ROP_NEW << 8)); 408 pFfb->drawop_cache = FFB_DRAWOP_RECTANGLE; 409 pFfb->fg_cache = pFfb->bg_cache = 0; 410 pFfb->fontw_cache = 32; 411 pFfb->fontinc_cache = (1 << 16) | 0; 412 pFfb->fbc_cache = (FFB_FBC_WB_A | FFB_FBC_WM_COMBINED | FFB_FBC_RB_A | 413 FFB_FBC_WE_FORCEON | 414 FFB_FBC_SB_BOTH | 415 FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF | 416 FFB_FBC_RGBE_OFF | 417 FFB_FBC_XE_ON); 418 419 /* We will now clear the screen: we'll draw a rectangle covering all the 420 * viewscreen, using a 'blackness' ROP. 421 */ 422 FFBFifo(pFfb, 22); 423 ffb->fbc = pFfb->fbc_cache; 424 ffb->ppc = pFfb->ppc_cache; 425 ffb->wid = pFfb->wid_cache; 426 ffb->xpmask = 0xff; 427 ffb->pmask = pFfb->pmask_cache; 428 ffb->rop = pFfb->rop_cache; 429 ffb->drawop = pFfb->drawop_cache; 430 ffb->fg = pFfb->fg_cache; 431 ffb->bg = pFfb->bg_cache; 432 ffb->fontw = pFfb->fontw_cache; 433 ffb->fontinc = pFfb->fontinc_cache; 434 ffb->xclip = FFB_XCLIP_TEST_ALWAYS; 435 ffb->cmp = 0x80808080; 436 ffb->matchab = 0x80808080; 437 ffb->magnab = 0x80808080; 438 ffb->blendc = (FFB_BLENDC_FORCE_ONE | 439 FFB_BLENDC_DF_ONE_M_A | 440 FFB_BLENDC_SF_A); 441 ffb->blendc1 = 0; 442 ffb->blendc2 = 0; 443 FFB_WRITE64(&ffb->by, 0, 0); 444 FFB_WRITE64_2(&ffb->bh, pFfb->psdp->height, pFfb->psdp->width); 445 FFBWait(pFfb, ffb); 446 447 FFB_ATTR_SFB_VAR_XAA(pFfb, 0xffffffff, GXcopy); 448 FFBWait(pFfb, ffb); 449 450 FFB_HardwareSetup(pFfb); 451 pExa = exaDriverAlloc(); 452 if (!pExa) 453 return FALSE; 454 455 pFfb->pExa = pExa; 456 457 pExa->exa_major = EXA_VERSION_MAJOR; 458 pExa->exa_minor = EXA_VERSION_MINOR; 459 460 461 pExa->memoryBase = (char *)pFfb->sfb32; 462 /* 463 * we don't have usable off-screen memory but EXA craps out if we don't 464 * pretend that we do, so register a ridiculously small amount and 465 * cross fingers 466 */ 467 pExa->memorySize = 8192 * pFfb->psdp->height + 4; 468 pExa->offScreenBase = pExa->memorySize - 4; 469 470 /* we want to use 64bit aligned accesses */ 471 pExa->pixmapOffsetAlign = 8; 472 pExa->pixmapPitchAlign = 8; 473 474 pExa->flags = EXA_OFFSCREEN_PIXMAPS | 475 /*EXA_SUPPORTS_OFFSCREEN_OVERLAPS |*/ 476 EXA_MIXED_PIXMAPS; 477 478 pExa->maxX = 2048; 479 pExa->maxY = 2048; 480 481 pExa->WaitMarker = FFBWaitMarker; 482 483 pExa->PrepareSolid = FFBPrepareSolid; 484 pExa->Solid = FFBSolid; 485 pExa->DoneSolid = FFBDoneCopy; 486 487 pExa->PrepareCopy = FFBPrepareCopy; 488 pExa->Copy = FFBCopy; 489 pExa->DoneCopy = FFBDoneCopy; 490 491 pExa->UploadToScreen = FFBUploadToScreen; 492 pExa->DownloadFromScreen = FFBDownloadFromScreen; 493 494 pExa->PrepareAccess = FFBPrepareAccess; 495 pExa->FinishAccess = FFBFinishAccess; 496 497if(0) { 498 pExa->CheckComposite = FFBCheckComposite; 499 pExa->PrepareComposite = FFBPrepareComposite; 500 pExa->Composite = FFBComposite; 501 pExa->DoneComposite = FFBDoneCopy; 502} 503 return exaDriverInit(pScreen, pExa); 504} 505