1
0
mirror of synced 2026-03-06 10:43:38 +00:00

Stuff for exa/composite support in X11 (SBusFPGA only for now)

This commit is contained in:
Romain Dolbeau
2022-08-20 18:55:25 +02:00
parent 732a0bfb4b
commit 64e158e496
6 changed files with 455 additions and 21 deletions

View File

@@ -677,6 +677,7 @@ goblin_init_screen(void *cookie, struct vcons_screen *scr,
ri->ri_ops.eraserows = jareth_eraserows;
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_jareth, GOBOFB_ACCEL_REG_SRC_PTR, 0);
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_jareth, GOBOFB_ACCEL_REG_DST_PTR, 0);
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_jareth, GOBOFB_ACCEL_REG_OP, 0x3); // GXcopy by default
device_printf(sc->sc_dev, "Jareth console acceleration enabled\n");
/* uint32_t status = bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_jareth, GOBOFB_ACCEL_REG_STATUS); */
/* uint32_t resv0 = bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_jareth, GOBOFB_ACCEL_REG_RESV0); */
@@ -721,6 +722,7 @@ goblin_reset(struct goblin_softc *sc)
if (sc->sc_has_jareth) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_jareth, GOBOFB_ACCEL_REG_SRC_PTR, 0);
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_jareth, GOBOFB_ACCEL_REG_DST_PTR, 0);
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_jareth, GOBOFB_ACCEL_REG_OP, 0x3); // GXcopy by default
}
}

View File

@@ -63,11 +63,11 @@
#define GOBOFB_ACCEL_REG_STATUS 0x00
#define GOBOFB_ACCEL_REG_CMD 0x04
#define GOBOFB_ACCEL_REG_R5_CMD 0x08
#define GOBOFB_ACCEL_REG_RESV0 0x0C
#define GOBOFB_ACCEL_REG_OP 0x0C
#define GOBOFB_ACCEL_REG_WIDTH 0x10
#define GOBOFB_ACCEL_REG_HEIGHT 0x14
#define GOBOFB_ACCEL_REG_FGCOLOR 0x18
#define GOBOFB_ACCEL_REG_RESV2 0x1C
#define GOBOFB_ACCEL_REG_DEPTH 0x1C
#define GOBOFB_ACCEL_REG_SRC_X 0x20
#define GOBOFB_ACCEL_REG_SRC_Y 0x24
#define GOBOFB_ACCEL_REG_DST_X 0x28
@@ -77,6 +77,11 @@
#define GOBOFB_ACCEL_REG_SRC_PTR 0x38
#define GOBOFB_ACCEL_REG_DST_PTR 0x3c
#define GOBOFB_ACCEL_REG_MSK_X 0x40
#define GOBOFB_ACCEL_REG_MSK_Y 0x44
#define GOBOFB_ACCEL_REG_MSK_STRIDE 0x48
#define GOBOFB_ACCEL_REG_MSK_PTR 0x4c
// status
#define WORK_IN_PROGRESS_BIT 0

View File

@@ -65,6 +65,7 @@ typedef struct {
CloseScreenProcPtr CloseScreen;
OptionInfoPtr Options;
Bool has_accel;
Bool has_xrender;
ExaDriverPtr pExa;
uint32_t last_mask;
@@ -77,6 +78,12 @@ typedef struct {
int copy_off, copy_len;
int copyrev_off, copyrev_len;
Bool source_is_solid, no_source_pixmap;
uint32_t mskoff, mskpitch;
uint32_t srcformat, dstformat, mskformat;
uint32_t fillcolour;
int op;
xf86CursorInfoPtr CursorInfoRec;
unsigned int CursorXY;
int CursorBg, CursorFg;

View File

@@ -35,17 +35,21 @@
/* DGA stuff */
#define DEBUG_GOBLIN 1
// #define DEBUG_GOBLIN 1
#ifdef DEBUG_GOBLIN
//#define ENTER xf86Msg(X_ERROR, "%s>\n", __func__);
#define ENTER
#define DPRINTF xf86Msg
#define RPRINTF xf86Msg
#else
#define ENTER
#define DPRINTF while (0) xf86Msg
#define RPRINTF xf86Msg
#endif
#define arraysize(ary) (sizeof(ary) / sizeof(ary[0]))
static Bool Goblin_OpenFramebuffer(ScrnInfoPtr pScrn, char **, unsigned char **mem,
int *, int *, int *);
static Bool Goblin_SetMode(ScrnInfoPtr, DGAModePtr);
@@ -62,6 +66,14 @@ static Bool GoblinPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xd
static void GoblinCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int w, int h);
static void GoblinSync(ScrnInfoPtr);
static Bool GoblinCheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture);
static Bool GoblinPrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst);
static void GoblinComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int width, int height);
/* internal helper */
static Bool GoblinCheckPicture(PicturePtr pict);
static DGAFunctionRec Goblin_DGAFuncs = {
Goblin_OpenFramebuffer,
NULL,
@@ -206,9 +218,6 @@ GOBLINEXAInit(ScreenPtr pScreen)
pExa->flags = EXA_OFFSCREEN_PIXMAPS;/* | EXA_MIXED_PIXMAPS; */ /* | EXA_SUPPORTS_OFFSCREEN_OVERLAPS; */
/*
* these limits are bogus
* Jareth doesn't deal with coordinates at all, so there is no limit but
* we have to put something here
*/
pExa->maxX = 4096;
pExa->maxY = 4096;
@@ -226,6 +235,13 @@ GOBLINEXAInit(ScreenPtr pScreen)
pExa->UploadToScreen = GoblinUploadToScreen;
pExa->DownloadFromScreen = GoblinDownloadFromScreen;
if (pGoblin->has_xrender) {
pExa->CheckComposite = GoblinCheckComposite;
pExa->PrepareComposite = GoblinPrepareComposite;
pExa->Composite = GoblinComposite;
pExa->DoneComposite = GoblinDone;
}
return exaDriverInit(pScreen, pExa);;
}
@@ -280,7 +296,7 @@ GoblinUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, int
int wBytes = w * cpp;
ENTER;
DPRINTF(X_ERROR, "%s depth %d x %d y %d w %d h %d src %d %p dst %d 0x%08x %p cpp %d wBytes %d\n", __func__, bpp,
DPRINTF(X_INFO, "%s depth %d x %d y %d w %d h %d src %d %p dst %d 0x%08x %p cpp %d wBytes %d\n", __func__, bpp,
x, y, w, h,
src_pitch, src,
dst_pitch, exaGetPixmapOffset(pDst), dst,
@@ -336,12 +352,12 @@ GoblinPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg)
int i;
ENTER;
DPRINTF(X_ERROR, "PrepareSolid bpp: %d, alu %d, pm 0x%08x, Fg 0x%08x\n", pPixmap->drawable.bitsPerPixel, alu, planemask, fg);
DPRINTF(X_INFO, "%s bpp: %d, alu %d, pm 0x%08x, Fg 0x%08x\n", __func__, pPixmap->drawable.bitsPerPixel, alu, planemask, fg);
GoblinWait(pGoblin);
//goblin->jreg->reg_XXXXX = planemask;
pGoblin->jreg->reg_fgcolor = fg;
pGoblin->jreg->reg_fgcolor = __builtin_bswap32(fg); // ???
pGoblin->last_mask = planemask;
pGoblin->last_rop = alu;
@@ -349,11 +365,13 @@ GoblinPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg)
pGoblin->jreg->reg_dst_ptr = 0;
if ((alu == 0x3) && // GXcopy
(planemask == 0xFFFFFFFF)) { // full pattern
(planemask == 0xFFFFFFFF)) { // full patternp
// fill
pGoblin->jreg->reg_op = alu;
pGoblin->jreg->reg_depth = 0; // reset to native
} else {
// fillrop
DPRINTF(X_ERROR, "PrepareSolid unsupported: 0x08x, 0x%08x\n", alu, planemask);
DPRINTF(X_ERROR, "%s unsupported: 0x08x, 0x%08x\n", __func__, alu, planemask);
return FALSE;
}
return TRUE;
@@ -401,7 +419,7 @@ GoblinSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
else
pGoblin->jreg->reg_dst_ptr = 0;
DPRINTF(X_INFO, "Solid {%d} %d %d %d %d [%d %d], %d %d -> %d (%p: %p)\n",
DPRINTF(X_INFO, "%s {%d} %d %d %d %d [%d %d], %d %d -> %d (%p: %p)\n", __func__,
depth,
x1, y1, x2, y2,
w, h, dstpitch, dstoff, start, (void*)start, ptr);
@@ -414,7 +432,6 @@ GoblinSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
static void GoblinDone(PixmapPtr pDstPixmap) {
}
static Bool
GoblinPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap,
int xdir, int ydir, int alu, Pixel planemask)
@@ -440,23 +457,27 @@ GoblinPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap,
if ((alu == 0x3) && // GCcopy
(planemask == 0xFFFFFFFF)) { // full pattern
// fill
pGoblin->jreg->reg_op = alu;
pGoblin->jreg->reg_depth = 0; // reset to native
} else {
// fillrop
DPRINTF(X_ERROR, "PrepareCopy unsupported: 0x08x, 0x%08x\n", alu, planemask);
DPRINTF(X_ERROR, "%s unsupported: 0x08x, 0x%08x\n", __func__, alu, planemask);
return FALSE;
}
} else {
if ((alu == 0x3) && // GCcopy
(planemask == 0xFFFFFFFF)) { // full pattern
// fill
pGoblin->jreg->reg_op = alu;
pGoblin->jreg->reg_depth = 0; // reset to native
} else {
// fillrop
DPRINTF(X_ERROR, "PrepareCopy unsupported: 0x08x, 0x%08x\n", alu, planemask);
DPRINTF(X_ERROR, "%s unsupported: 0x08x, 0x%08x\n", __func__, alu, planemask);
return FALSE;
}
}
DPRINTF(X_ERROR, "PrepareCopy: alu %d, pm 0x%08x, xdir/ydir %d/%d\n", alu, planemask, xdir, ydir);
DPRINTF(X_INFO, "%s: alu %d, pm 0x%08x, xdir/ydir %d/%d\n", __func__, alu, planemask, xdir, ydir);
return TRUE;
}
@@ -509,8 +530,7 @@ GoblinCopy(PixmapPtr pDstPixmap,
else
pGoblin->jreg->reg_dst_ptr = 0;
//DPRINTF(X_ERROR, "Copy %d %d -> %d %d [%d x %d, %d %d] ; %d -> %d \n", srcX, srcY, dstX, dstY, w, h, pGoblin->xdir, pGoblin->ydir, srcstart, dststart);
DPRINTF(X_ERROR, "Copy %d %d -> %d %d [%d x %d, %d %d] ; 0x%08x 0x%08x ; %d %d \n", srcX, srcY, dstX, dstY, w, h, pGoblin->xdir, pGoblin->ydir, pGoblin->srcoff, dstoff, pGoblin->srcpitch, dstpitch);
DPRINTF(X_INFO, "%s %d %d -> %d %d [%d x %d, %d %d] ; 0x%08x 0x%08x ; %d %d \n", __func__, srcX, srcY, dstX, dstY, w, h, pGoblin->xdir, pGoblin->ydir, pGoblin->srcoff, dstoff, pGoblin->srcpitch, dstpitch);
pGoblin->jreg->reg_cmd = 1; // 1<<DO_COPY_BIT
@@ -537,3 +557,393 @@ GoblinCopy(PixmapPtr pDstPixmap,
}
#endif
}
int src_formats[] = {PICT_a8r8g8b8, PICT_x8r8g8b8,
PICT_a8b8g8r8, PICT_x8b8g8r8, PICT_a8};
int tex_formats[] = {PICT_a8r8g8b8, PICT_a8b8g8r8, PICT_a8};
static const char* fmt2name(const int fmt) {
switch (fmt) {
case PICT_a8r8g8b8: return "PICT_a8r8g8b8";
case PICT_x8r8g8b8: return "PICT_x8r8g8b8";
case PICT_a8b8g8r8: return "PICT_a8b8g8r8";
case PICT_x8b8g8r8: return "PICT_x8b8g8r8";
case PICT_a8: return "PICT_a8";
default: return "PICT_Unknown";
}
}
static const char* op2name(const int op) {
switch (op) {
case PictOpClear: return "PictOpClear";
case PictOpSrc: return "PictOpSrc";
case PictOpDst: return "PictOpDst";
case PictOpOver: return "PictOpOver";
case PictOpOverReverse: return "PictOpOverReverse";
case PictOpIn: return "PictOpIn";
case PictOpInReverse: return "PictOpInReverse";
case PictOpOut: return "PictOpOut";
case PictOpOutReverse: return "PictOpOutReverse";
case PictOpAtop: return "PictOpAtop";
case PictOpAtopReverse: return "PictOpAtopReverse";
case PictOpXor: return "PictOpXor";
case PictOpAdd: return "PictOpAdd";
case PictOpSaturate: return "PictOpSaturate";
default: return "PictOpUnknown";
}
}
static Bool GoblinCheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture) {
int i, ok = FALSE;
ENTER;
/*
* Like SX, Goblin is in theory capable of accelerating pretty much all Xrender ops,
* even coordinate transformation and gradients.
* However someone needs to write all that software...
*/
if ((op != PictOpOver) &&
(op != PictOpAdd) &&
/* (op != PictOpSrc) && */
/* (op != PictOpOutReverse) && */
1) {
RPRINTF(X_ERROR, "%s: rejecting %s (%d)\n", __func__, op2name(op), op);
return FALSE;
} else {
RPRINTF(X_INFO, "%s: accepting %s (%d)\n", __func__, op2name(op), op);
}
if (pSrcPicture != NULL) {
i = 0;
while ((i < arraysize(src_formats)) && (!ok)) {
ok = (pSrcPicture->format == src_formats[i]);
i++;
}
if (!ok) {
RPRINTF(X_ERROR, "%s: unsupported src format %s (%x)\n",
__func__, fmt2name(pSrcPicture->format), pSrcPicture->format);
return FALSE;
}
if (!GoblinCheckPicture(pSrcPicture)) {
return FALSE;
}
RPRINTF(X_INFO, "%s: src is %s (%x), %s (%d)\n", __func__, fmt2name(pSrcPicture->format), pSrcPicture->format, op2name(op), op);
// pSrcPicture->pDrawable->width, pSrcPicture->pDrawable->height);
}
if (pDstPicture != NULL) {
i = 0;
ok = FALSE;
while ((i < arraysize(src_formats)) && (!ok)) {
ok = (pDstPicture->format == src_formats[i]);
i++;
}
if (!ok) {
RPRINTF(X_ERROR, "%s: unsupported dst format %x\n",
__func__, pDstPicture->format);
return FALSE;
}
RPRINTF(X_INFO, "%s: dst is %s (%x), %s (%d)\n", __func__, fmt2name(pDstPicture->format), pDstPicture->format, op2name(op), op);
// pDstPicture->pDrawable->width, pDstPicture->pDrawable->height);
}
if (pMaskPicture != NULL) {
if (!GoblinCheckPicture(pMaskPicture)) {
return FALSE;
}
RPRINTF(X_INFO, "%s: mask is %s (%x), %d x %d\n", __func__, fmt2name(pMaskPicture->format), pMaskPicture->format,
pMaskPicture->pDrawable->width,
pMaskPicture->pDrawable->height);
}
return TRUE;
}
static Bool GoblinCheckPicture(PicturePtr pict) {
int w, h;
if (pict->pDrawable) {
w = pict->pDrawable->width;
h = pict->pDrawable->height;
} else {
if (pict->pSourcePict->type != SourcePictTypeSolidFill) {
RPRINTF(X_ERROR, "%s: Gradient pictures not supported\n", __func__);
return FALSE;
}
w = 1;
h = 1;
}
if (w >= 4096 || h >= 4096) {
RPRINTF(X_ERROR, "%s: Picture too large, %d x %d\n", __func__, w, h);
return FALSE;
}
if ((pict->repeat != RepeatNone) &&
((w != 1) || (h != 1))) {
RPRINTF(X_ERROR, "%s: Picture is repeating non-trivial\n", __func__);
return FALSE;
}
if (pict->filter) {
RPRINTF(X_ERROR, "%s: Picture has filter\n", __func__);
return FALSE;
}
if (pict->transform) {
RPRINTF(X_ERROR, "%s: Picture has transform\n", __func__);
return FALSE;
}
return TRUE;
}
static Bool GoblinPrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst) {
ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
GoblinPtr pGoblin = GET_GOBLIN_FROM_SCRN(pScrn);
ENTER;
pGoblin->no_source_pixmap = FALSE;
pGoblin->source_is_solid = FALSE;
if (pSrcPicture->format == PICT_a1) {
xf86Msg(X_ERROR, "src mono, dst %x, op %d\n",
pDstPicture->format, op);
if (pMaskPicture != NULL) {
xf86Msg(X_ERROR, "msk %x\n", pMaskPicture->format);
}
}
if (pSrcPicture->pSourcePict != NULL) {
if (pSrcPicture->pSourcePict->type == SourcePictTypeSolidFill) {
pGoblin->fillcolour =
pSrcPicture->pSourcePict->solidFill.color;
RPRINTF(X_INFO, "%s: solid src %08x\n", __func__, pGoblin->fillcolour);
pGoblin->no_source_pixmap = TRUE;
pGoblin->source_is_solid = TRUE;
}
}
if ((pMaskPicture != NULL) && (pMaskPicture->pSourcePict != NULL)) {
if (pMaskPicture->pSourcePict->type ==
SourcePictTypeSolidFill) {
pGoblin->fillcolour =
pMaskPicture->pSourcePict->solidFill.color;
xf86Msg(X_ERROR, "%s: solid mask %08x\n", __func__, pGoblin->fillcolour);
}
}
if (pMaskPicture != NULL) {
pGoblin->mskoff = exaGetPixmapOffset(pMask);
pGoblin->mskpitch = exaGetPixmapPitch(pMask);
pGoblin->mskformat = pMaskPicture->format;
} else {
pGoblin->mskoff = 0;
pGoblin->mskpitch = 0;
pGoblin->mskformat = 0;
}
if (pSrc != NULL) {
//pGoblin->source_is_solid = ((pSrc->drawable.width == 1) && (pSrc->drawable.height == 1));
pGoblin->source_is_solid = 0;
pGoblin->srcoff = exaGetPixmapOffset(pSrc);
pGoblin->srcpitch = exaGetPixmapPitch(pSrc);
if (pGoblin->source_is_solid) {
pGoblin->fillcolour = *(uint32_t *)(pGoblin->fb + pGoblin->srcoff);
}
}
pGoblin->srcformat = pSrcPicture->format;
pGoblin->dstformat = pDstPicture->format;
if (pGoblin->source_is_solid) {
// init for solid ?
}
pGoblin->op = op;
/* if (op == PictOpSrc) { */
/* CG14PrepareCopy(pSrc, pDst, 1, 1, GXcopy, 0xffffffff); */
/* } */
if ((pGoblin->op == PictOpOver) &&
(pGoblin->source_is_solid) &&
(pGoblin->mskformat == PICT_a8) &&
1) {
RPRINTF(X_INFO, "%s: A %s (%d) %s _ %s [%d %d _] %s\n", __func__, op2name(op), op, fmt2name(pGoblin->srcformat), fmt2name(pGoblin->dstformat),
pGoblin->srcpitch, pGoblin->mskpitch, pGoblin->source_is_solid ? "Solid" : "");
return TRUE;
}
if ((pGoblin->op == PictOpOver) &&
(~pGoblin->source_is_solid) &&
((pGoblin->srcformat == PICT_x8r8g8b8) || (pGoblin->srcformat == PICT_x8b8g8r8)) &&
(pGoblin->mskformat == PICT_a8r8g8b8) &&
1) {
RPRINTF(X_INFO, "%s: B %s (%d) %s _ %s [%d %d _] %s\n", __func__, op2name(op), op, fmt2name(pGoblin->srcformat), fmt2name(pGoblin->dstformat),
pGoblin->srcpitch, pGoblin->mskpitch, pGoblin->source_is_solid ? "Solid" : "");
return TRUE;
}
if ((pGoblin->op == PictOpAdd) &&
(pGoblin->srcformat == PICT_a8) &&
(pGoblin->dstformat == PICT_a8) &&
(pGoblin->mskformat == 0) &&
1) {
RPRINTF(X_INFO, "%s: C %s (%d) %s _ %s [%d %d _] %s\n", __func__, op2name(op), op, fmt2name(pGoblin->srcformat), fmt2name(pGoblin->dstformat),
pGoblin->srcpitch, pGoblin->mskpitch, pGoblin->source_is_solid ? "Solid" : "");
return TRUE;
}
RPRINTF(X_ERROR, "%s: NOT %s (%d) %s _ %s [%d %d _] %s\n", __func__, op2name(op), op, fmt2name(pGoblin->srcformat), fmt2name(pGoblin->dstformat),
pGoblin->srcpitch, pGoblin->mskpitch, pGoblin->source_is_solid ? "Solid" : "");
return FALSE;
}
static void GoblinComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int width, int height) {
ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
GoblinPtr pGoblin = GET_GOBLIN_FROM_SCRN(pScrn);
uint32_t dstoff, dstpitch;
uint32_t dst, msk, src;
int flip = 0;
ENTER;
dstoff = exaGetPixmapOffset(pDst);
dstpitch = exaGetPixmapPitch(pDst);
flip = (PICT_FORMAT_TYPE(pGoblin->srcformat) !=
PICT_FORMAT_TYPE(pGoblin->dstformat));
switch (pGoblin->op) {
case PictOpOver: {
GoblinWait(pGoblin);
pGoblin->jreg->reg_op = (0x80 | PictOpOver | ((flip && ~pGoblin->source_is_solid) ? 0x40 : 0)); // xrender operation
pGoblin->jreg->reg_depth = 0; // or 32 ?
pGoblin->jreg->reg_width = width;
pGoblin->jreg->reg_height = height;
pGoblin->jreg->reg_dst_stride = dstpitch;
pGoblin->jreg->reg_bitblt_dst_x = dstX;
pGoblin->jreg->reg_bitblt_dst_y = dstY;
if (dstoff != 0)
pGoblin->jreg->reg_dst_ptr = (0x8f000000 + dstoff); // fixme: hw'ired @
else
pGoblin->jreg->reg_dst_ptr = 0;
pGoblin->jreg->reg_msk_stride = pGoblin->mskpitch;
pGoblin->jreg->reg_bitblt_msk_x = maskX;
pGoblin->jreg->reg_bitblt_msk_y = maskY;
if (pGoblin->mskoff != 0)
pGoblin->jreg->reg_msk_ptr = (0x8f000000 + pGoblin->mskoff); // fixme: hw'ired @
else
pGoblin->jreg->reg_msk_ptr = 0;
if (pGoblin->source_is_solid) {
pGoblin->jreg->reg_fgcolor = flip ? __builtin_bswap32(pGoblin->fillcolour) : pGoblin->fillcolour;
switch (pGoblin->mskformat) {
case PICT_a8:
RPRINTF(X_INFO, "%s: Starting PictOpOver: %d x %d, flip %d, %d x %d (+0x%08x)-> %d x %d (+0x%08x), fg 0x%08x\n", __func__,
width, height, flip,
maskX, maskY, pGoblin->mskoff,
dstX, dstY, dstoff,
pGoblin->fillcolour
);
pGoblin->jreg->reg_cmd = 8; // 1<<DO_RSMSK8DST32_BIT
break;
default:
RPRINTF(X_ERROR, "%s: A Unsupported mask format %s (%d) for PictOpOver (%d x %d)\n", __func__, fmt2name(pGoblin->mskformat), pGoblin->mskformat, width, height);
break;
}
} else {
pGoblin->jreg->reg_src_stride = pGoblin->srcpitch;
pGoblin->jreg->reg_bitblt_src_x = srcX;
pGoblin->jreg->reg_bitblt_src_y = srcY;
if (pGoblin->srcoff != 0)
pGoblin->jreg->reg_src_ptr = (0x8f000000 + pGoblin->srcoff); // fixme: hw'ired @
else
pGoblin->jreg->reg_src_ptr = 0;
switch (pGoblin->mskformat) {
case PICT_a8r8g8b8:
case PICT_a8b8g8r8:
RPRINTF(X_INFO, "%s: Starting PictOpOver: %d x %d, flip %d, %d x %d (+0x%08x) & %d x %d (+0x%08x) -> %d x %d (+0x%08x)\n", __func__,
width, height, flip,
srcX, srcY, pGoblin->srcoff,
maskX, maskY, pGoblin->mskoff,
dstX, dstY, dstoff
);
if ((width == 1) && (height == 1)) {
RPRINTF(X_INFO, "%s: before ... 0x%08x 0x%08x 0x%08x\n", __func__,
*(unsigned int*)(pGoblin->fb + pGoblin->srcoff),
*(unsigned int*)(pGoblin->fb + pGoblin->mskoff),
*(unsigned int*)(pGoblin->fb + dstoff));
}
if ((pGoblin->srcoff != pGoblin->mskoff) ||
(srcX != maskX) ||
(srcY != maskY)) {
pGoblin->jreg->reg_cmd = 0x10; // 1<<DO_RSRC32MSK32DST32_BIT
} else {
// mask is just src
pGoblin->jreg->reg_cmd = 0x20; // 1<<DO_RSRC32DST32_BIT
}
if ((width == 1) && (height == 1)) {
GoblinWait(pGoblin);
RPRINTF(X_INFO, "%s: after ... 0x%08x 0x%08x 0x%08x\n", __func__,
*(unsigned int*)(pGoblin->fb + pGoblin->srcoff),
*(unsigned int*)(pGoblin->fb + pGoblin->mskoff),
*(unsigned int*)(pGoblin->fb + dstoff));
}
break;
default:
RPRINTF(X_ERROR, "%s: B Unsupported mask format %s (%d) for PictOpOver (%d x %d)\n", __func__, fmt2name(pGoblin->mskformat), pGoblin->mskformat, width, height);
break;
}
}
} break;
case PictOpAdd: {
GoblinWait(pGoblin);
pGoblin->jreg->reg_op = (0x80 | PictOpAdd); // xrender operation
pGoblin->jreg->reg_width = width;
pGoblin->jreg->reg_height = height;
pGoblin->jreg->reg_dst_stride = dstpitch;
pGoblin->jreg->reg_bitblt_dst_x = dstX;
pGoblin->jreg->reg_bitblt_dst_y = dstY;
if (dstoff != 0)
pGoblin->jreg->reg_dst_ptr = (0x8f000000 + dstoff); // fixme: hw'ired @
else
pGoblin->jreg->reg_dst_ptr = 0;
pGoblin->jreg->reg_src_stride = pGoblin->srcpitch;
pGoblin->jreg->reg_bitblt_src_x = srcX;
pGoblin->jreg->reg_bitblt_src_y = srcY;
if (pGoblin->srcoff != 0)
pGoblin->jreg->reg_src_ptr = (0x8f000000 + pGoblin->srcoff); // fixme: hw'ired @
else
pGoblin->jreg->reg_src_ptr = 0;
if ((pGoblin->srcformat == PICT_a8) &&
(pGoblin->dstformat == PICT_a8) &&
(pGoblin->mskformat == 0) &&
1) {
RPRINTF(X_INFO, "%s: Starting PictOpAdd: %d x %d, flip %d, %d x %d (+0x%08x)-> %d x %d (+0x%08x)\n", __func__,
width, height, flip,
srcX, srcY, pGoblin->srcoff,
dstX, dstY, dstoff
);
pGoblin->jreg->reg_depth = 8; // force 8 bits mode in the blitter
pGoblin->jreg->reg_cmd = 1; // 1<<DO_COPY_BIT
} else {
RPRINTF(X_ERROR, "%s: Unsupported fmts %s (%d), %s (%d), %s (%d)\n", __func__, pGoblin->srcformat, pGoblin->srcformat, pGoblin->dstformat, pGoblin->dstformat, pGoblin->mskformat, pGoblin->mskformat);
}
} break;
default:
RPRINTF(X_ERROR, "%s: Unsupported %s (%d)\n", __func__, op2name(pGoblin->op), pGoblin->op);
break;
}
exaMarkSync(pDst->drawable.pScreen);
}

View File

@@ -118,12 +118,14 @@ _X_EXPORT DriverRec GOBLIN = {
typedef enum {
OPTION_NOACCEL,
OPTION_ACCELMETHOD
OPTION_ACCELMETHOD,
OPTION_XRENDER
} GOBLINOpts;
static const OptionInfoRec GOBLINOptions[] = {
{ OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE },
{ OPTION_XRENDER, "XRender", OPTV_BOOLEAN, {0}, FALSE},
{ -1, NULL, OPTV_NONE, {0}, FALSE }
};
@@ -486,6 +488,9 @@ GOBLINPreInit(ScrnInfoPtr pScrn, int flags)
/* Set display resolution */
xf86SetDpi(pScrn, 0, 0);
/* xrender ?*/
pGoblin->has_xrender = xf86ReturnOptValBool(pGoblin->Options, OPTION_XRENDER, FALSE);
return TRUE;
}

View File

@@ -70,11 +70,11 @@ typedef struct goblin_accel_regs {
u_int32_t reg_status; // 0
u_int32_t reg_cmd;
u_int32_t reg_r5_cmd;
u_int32_t resv0;
u_int32_t reg_op;
u_int32_t reg_width; // 4
u_int32_t reg_height;
u_int32_t reg_fgcolor;
u_int32_t resv2;
u_int32_t reg_depth;
u_int32_t reg_bitblt_src_x; // 8
u_int32_t reg_bitblt_src_y;
u_int32_t reg_bitblt_dst_x;
@@ -83,6 +83,11 @@ typedef struct goblin_accel_regs {
u_int32_t reg_dst_stride;
u_int32_t reg_src_ptr; // 14
u_int32_t reg_dst_ptr;
u_int32_t reg_bitblt_msk_x; // 16
u_int32_t reg_bitblt_msk_y;
u_int32_t reg_msk_stride; // 18
u_int32_t reg_msk_ptr; // 19
} GoblinAccel, *GoblinAccelPtr;
#endif /* GOBLIN_REGS_H */