diff options
author | Alan Hourihane <alanh@tungstengraphics.com> | 2008-06-26 22:27:44 +0100 |
---|---|---|
committer | Alan Hourihane <alanh@tungstengraphics.com> | 2008-06-26 22:27:44 +0100 |
commit | acb7da8c7979659bcfdfef7a6ee5b402f6fb366b (patch) | |
tree | 14f65449a8a1fd4beccb46c7c0bbedfba477f632 | |
parent | 169e39c504a0ac52828108a4490fc45198812fd1 (diff) |
Add EXA winsys for gallium pipe driver interface.
Plug in the EXA framework into the pipe driver
for surface_copy & surface_fill.
Back pixmaps with drmBO's including the front buffer.
-rw-r--r-- | src/driver.c | 303 | ||||
-rw-r--r-- | src/driver.h | 15 | ||||
-rw-r--r-- | src/exa.c | 614 |
3 files changed, 591 insertions, 341 deletions
diff --git a/src/driver.c b/src/driver.c index 6bf6388..0e6f4c8 100644 --- a/src/driver.c +++ b/src/driver.c @@ -40,7 +40,6 @@ #include "xf86Resources.h" #include "mipointer.h" #include "micmap.h" -#include "shadowfb.h" #include <X11/extensions/randr.h> #include "fb.h" #include "edid.h" @@ -50,7 +49,6 @@ #include "dixstruct.h" #include "xf86xv.h" #include <X11/extensions/Xv.h> -#include "shadow.h" #include <xorg-server.h> #if XSERVER_LIBPCIACCESS #include <pciaccess.h> @@ -120,15 +118,11 @@ static PciChipsets PciDevices[] = { typedef enum { - OPTION_NOACCEL, OPTION_SW_CURSOR, - OPTION_SHADOWFB, } modesettingOpts; static const OptionInfoRec Options[] = { - {OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE}, - {OPTION_SHADOWFB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE}, {-1, NULL, OPTV_NONE, {0}, FALSE} }; @@ -154,12 +148,6 @@ static const char *ddcSymbols[] = { NULL }; -static const char *shadowSymbols[] = { - "shadowInit", - "shadowUpdatePackedWeak", - NULL -}; - static const char *i2cSymbols[] = { "xf86CreateI2CBusRec", "xf86I2CBusInit", @@ -200,7 +188,7 @@ Setup(pointer module, pointer opts, int *errmaj, int *errmin) * Tell the loader about symbols from other modules that this module * might refer to. */ - LoaderRefSymLists(exaSymbols, fbSymbols, shadowSymbols, ddcSymbols, NULL); + LoaderRefSymLists(exaSymbols, fbSymbols, ddcSymbols, NULL); /* * The return value must be non-NULL on success even though there @@ -323,7 +311,6 @@ Probe(DriverPtr drv, int flags) if (numUsed > 0) foundScreen = TRUE; } else { - ErrorF("NUMUSED %d\n", numUsed); for (i = 0; i < numUsed; i++) { ScrnInfoPtr pScrn = NULL; @@ -420,54 +407,21 @@ ProbeDDC(ScrnInfoPtr pScrn, int index) } static Bool -MapMem(ScrnInfoPtr pScrn) -{ - modesettingPtr ms = modesettingPTR(pScrn); - - drmBOMap(ms->fd, - &ms->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &ms->virtual); - - ms->virtual = ms->bo.virtual; - - return TRUE; -} - -static Bool -UnmapMem(ScrnInfoPtr pScrn) -{ - modesettingPtr ms = modesettingPTR(pScrn); - - drmBOUnmap(ms->fd, &ms->bo); - - return TRUE; -} - -static void -LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, - LOCO * colors, VisualPtr pVisual) -{ - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); -} - -static Bool CreateFrontBuffer(ScrnInfoPtr pScrn) { modesettingPtr ms = modesettingPTR(pScrn); ScreenPtr pScreen = pScrn->pScreen; PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); Bool fbAccessDisabled; - CARD8 *fbstart; + int flags; - drmBOCreate(ms->fd, - pScrn->virtualY * pScrn->displayWidth * - pScrn->bitsPerPixel / 8, 0, NULL, - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_SHAREABLE - | DRM_BO_FLAG_CACHED_MAPPED - | DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_MAPPABLE | - /*DRM_BO_FLAG_MEM_VRAM |*/ DRM_BO_FLAG_MEM_TT, - 0, &ms->bo); - - MapMem(pScrn); + ms->noEvict = TRUE; + pScreen->ModifyPixmapHeader(rootPixmap, + pScrn->virtualX, pScrn->virtualY, + pScrn->depth, pScrn->bitsPerPixel, + pScrn->displayWidth * pScrn->bitsPerPixel / 8, + NULL); + ms->noEvict = FALSE; drmModeAddFB(ms->fd, pScrn->virtualX, @@ -475,50 +429,12 @@ CreateFrontBuffer(ScrnInfoPtr pScrn) pScrn->depth, pScrn->bitsPerPixel, pScrn->displayWidth * pScrn->bitsPerPixel / 8, - ms->bo.handle, &ms->fb_id); - - if (ms->shadowFB) { - if ((ms->shadowMem = - shadowAlloc(pScrn->displayWidth, pScrn->virtualY, - pScrn->bitsPerPixel)) == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Allocation of shadow memory failed\n"); - return FALSE; - } - fbstart = ms->shadowMem; - } else { - fbstart = ms->bo.virtual; - } - - /* - * If we are in a fb disabled state, the virtual address of the root - * pixmap should always be NULL, and it will be overwritten later - * if we try to set it to something. - * - * Therefore, set it to NULL, and modify the backup copy instead. - */ - - fbAccessDisabled = (rootPixmap->devPrivate.ptr == NULL); - - pScreen->ModifyPixmapHeader(rootPixmap, - pScrn->virtualX, pScrn->virtualY, - pScrn->depth, pScrn->bitsPerPixel, - pScrn->displayWidth * pScrn->bitsPerPixel / 8, - fbstart); - - if (fbAccessDisabled) { - pScrn->pixmapPrivate.ptr = fbstart; - rootPixmap->devPrivate.ptr = NULL; - } + driGetPixmapHandle(rootPixmap, &flags), &ms->fb_id); pScrn->frameX0 = 0; pScrn->frameY0 = 0; AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); - UnmapMem(pScrn); - - ms->front = TRUE; - return TRUE; } @@ -538,22 +454,12 @@ crtc_resize(ScrnInfoPtr pScrn, int width, int height) pScrn->virtualX = width; pScrn->virtualY = height; - pScrn->displayWidth = (pScrn->virtualX + 63) & ~63; - if (ms->shadowMem) { - xfree(ms->shadowMem); - ms->shadowMem = NULL; - } + /* HW dependent - FIXME */ + pScrn->displayWidth = pScrn->virtualX; drmModeRmFB(ms->fd, ms->fb_id); - /* move old buffer out of the way */ - drmBOSetStatus(ms->fd, &ms->bo, 0, 0, 0, 0, 0); - - /* unreference it */ - drmBOUnreference(ms->fd, &ms->bo); - ms->front = FALSE; - /* now create new frontbuffer */ return CreateFrontBuffer(pScrn); } @@ -571,7 +477,6 @@ PreInit(ScrnInfoPtr pScrn, int flags) rgb defaultWeight = { 0, 0, 0 }; EntityInfoPtr pEnt; EntPtr msEnt = NULL; - int flags24; char *BusID; int i; char *s; @@ -645,13 +550,12 @@ PreInit(ScrnInfoPtr pScrn, int flags) pScrn->progClock = TRUE; pScrn->rgbBits = 8; - flags24 = Support32bppFb | PreferConvert24to32 | SupportConvert24to32; - - if (!xf86SetDepthBpp(pScrn, 0, 0, 0, flags24)) + if (!xf86SetDepthBpp + (pScrn, 0, 0, 0, + PreferConvert24to32 | SupportConvert24to32 | Support32bppFb)) return FALSE; switch (pScrn->depth) { - case 8: case 15: case 16: case 24: @@ -684,23 +588,10 @@ PreInit(ScrnInfoPtr pScrn, int flags) max_height = 8192; xf86CrtcSetSizeRange(pScrn, 320, 200, max_width, max_height); - if (xf86ReturnOptValBool(ms->Options, OPTION_NOACCEL, FALSE)) { - ms->noAccel = TRUE; - } - if (xf86ReturnOptValBool(ms->Options, OPTION_SW_CURSOR, FALSE)) { ms->SWCursor = TRUE; } - if (xf86ReturnOptValBool(ms->Options, OPTION_SHADOWFB, FALSE)) { - if (!xf86LoadSubModule(pScrn, "shadow")) - return FALSE; - - xf86LoaderReqSymLists(shadowSymbols, NULL); - - ms->shadowFB = TRUE; - } - SaveHWState(pScrn); crtc_init(pScrn); @@ -767,42 +658,37 @@ RestoreHWState(ScrnInfoPtr pScrn) return TRUE; } -static void * -WindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, - CARD32 * size, void *closure) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - modesettingPtr ms = modesettingPTR(pScrn); - - if (!pScrn->vtSema) - return NULL; - - *size = pScrn->displayWidth * pScrn->bitsPerPixel / 8; - - return ((CARD8 *) ms->bo.virtual + row * (*size) + offset); -} - static Bool CreateScreenResources(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; modesettingPtr ms = modesettingPTR(pScrn); - PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); + PixmapPtr rootPixmap; Bool ret; + int flags; + + ms->noEvict = TRUE; pScreen->CreateScreenResources = ms->createScreenResources; ret = pScreen->CreateScreenResources(pScreen); pScreen->CreateScreenResources = CreateScreenResources; - if (ms->shadowFB) - shadowAdd(pScreen, rootPixmap, - ms->update, WindowLinear, 0, 0); + rootPixmap = pScreen->GetScreenPixmap(pScreen); - if (!pScreen->ModifyPixmapHeader(pScreen->GetScreenPixmap(pScreen), - -1, -1, -1, -1, -1, - ms->shadowFB ? (pointer)ms->shadowMem : (pointer)ms->bo.virtual)) + if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, NULL)) FatalError("Couldn't adjust screen pixmap\n"); + ms->noEvict = FALSE; + + drmModeAddFB(ms->fd, + pScrn->virtualX, + pScrn->virtualY, + pScrn->depth, + pScrn->bitsPerPixel, + pScrn->displayWidth * pScrn->bitsPerPixel / 8, + driGetPixmapHandle(rootPixmap, &flags), &ms->fb_id); + + AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); return ret; } @@ -816,33 +702,33 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) unsigned long sys_mem; int c; MessageType from; - CARD8 *fbstart; /* deal with server regeneration */ if (ms->fd < 0) { - char *BusID; + char *BusID; - BusID = xalloc(64); - sprintf(BusID, "PCI:%d:%d:%d", + BusID = xalloc(64); + sprintf(BusID, "PCI:%d:%d:%d", #if XSERVER_LIBPCIACCESS - ((ms->PciInfo->domain << 8) | ms->PciInfo->bus), - ms->PciInfo->dev, ms->PciInfo->func + ((ms->PciInfo->domain << 8) | ms->PciInfo->bus), + ms->PciInfo->dev, ms->PciInfo->func #else - ((pciConfigPtr) ms->PciInfo->thisCard)->busnum, - ((pciConfigPtr) ms->PciInfo->thisCard)->devnum, - ((pciConfigPtr) ms->PciInfo->thisCard)->funcnum + ((pciConfigPtr) ms->PciInfo->thisCard)->busnum, + ((pciConfigPtr) ms->PciInfo->thisCard)->devnum, + ((pciConfigPtr) ms->PciInfo->thisCard)->funcnum #endif - ); + ); - ms->fd = drmOpen(NULL, BusID); + ms->fd = drmOpen(NULL, BusID); - if (ms->fd < 0) + if (ms->fd < 0) return FALSE; } pScrn->pScreen = pScreen; - pScrn->displayWidth = (pScrn->virtualX + 63) & ~63; + /* HW dependent - FIXME */ + pScrn->displayWidth = pScrn->virtualX; miClearVisualTypes(); @@ -857,39 +743,7 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pScrn->memPhysBase = 0; pScrn->fbOffset = 0; - drmBOCreate(ms->fd, - pScrn->virtualY * pScrn->displayWidth * - pScrn->bitsPerPixel / 8, 0, NULL, - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_SHAREABLE - | DRM_BO_FLAG_CACHED_MAPPED - | DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_MAPPABLE | - /*DRM_BO_FLAG_MEM_VRAM |*/ DRM_BO_FLAG_MEM_TT, - 0, &ms->bo); - - MapMem(pScrn); - - drmModeAddFB(ms->fd, - pScrn->virtualX, - pScrn->virtualY, - pScrn->depth, - pScrn->bitsPerPixel, - pScrn->displayWidth * pScrn->bitsPerPixel / 8, - ms->bo.handle, &ms->fb_id); - - if (ms->shadowFB) { - if ((ms->shadowMem = - shadowAlloc(pScrn->displayWidth, pScrn->virtualY, - pScrn->bitsPerPixel)) == NULL) { - xf86DrvMsg(scrnIndex, X_ERROR, - "Allocation of shadow memory failed\n"); - return FALSE; - } - fbstart = ms->shadowMem; - } else { - fbstart = ms->bo.virtual; - } - - if (!fbScreenInit(pScreen, fbstart, + if (!fbScreenInit(pScreen, NULL, pScrn->virtualX, pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth, pScrn->bitsPerPixel)) @@ -911,26 +765,13 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } fbPictureInit(pScreen, NULL, 0); - if (ms->shadowFB) { - ms->update = shadowUpdatePackedWeak(); - if (!shadowSetup(pScreen)) { - xf86DrvMsg(scrnIndex, X_ERROR, - "Shadow framebuffer initialization failed.\n"); - return FALSE; - } - } ms->createScreenResources = pScreen->CreateScreenResources; pScreen->CreateScreenResources = CreateScreenResources; xf86SetBlackWhitePixels(pScreen); -#if 0 - glucoseScreenInit(pScreen, 0); -#endif -#if 1 - ms->pExa = ExaInit(pScrn); -#endif + ms->exa = ExaInit(pScrn); miInitializeBackingStore(pScreen); xf86SetBackingStore(pScreen); @@ -939,9 +780,9 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) /* Need to extend HWcursor support to handle mask interleave */ if (!ms->SWCursor) - xf86_cursors_init (pScreen, 64, 64, - HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 | - HARDWARE_CURSOR_ARGB); + xf86_cursors_init(pScreen, 64, 64, + HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 | + HARDWARE_CURSOR_ARGB); /* Must force it before EnterVT, so we are in control of VT and * later memory should be bound when allocating, e.g rotate_mem */ @@ -957,20 +798,8 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (!miCreateDefColormap(pScreen)) return FALSE; -#if 0 - if (!xf86HandleColormaps(pScreen, 256, 8, LoadPalette, NULL, - CMAP_RELOAD_ON_MODE_SWITCH | - CMAP_PALETTED_TRUECOLOR)) { - return FALSE; - } -#endif - xf86DPMSInit(pScreen, xf86DPMSSet, 0); -#if 0 - glucoseInitVideo(pScreen); -#endif - if (serverGeneration == 1) xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); @@ -978,11 +807,7 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) driScreenInit(pScreen); #endif - UnmapMem(pScrn); - - ms->front = TRUE; - - return EnterVT(scrnIndex, 0); + return EnterVT(scrnIndex, 1); } static void @@ -1018,7 +843,7 @@ LeaveVT(int scrnIndex, int flags) for (o = 0; o < config->num_crtc; o++) { xf86CrtcPtr crtc = config->crtc[o]; - cursor_destroy(crtc); + cursor_destroy(crtc); if (crtc->rotatedPixmap || crtc->rotatedData) { crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap, @@ -1030,12 +855,6 @@ LeaveVT(int scrnIndex, int flags) drmModeRmFB(ms->fd, ms->fb_id); - /* move old buffer out of the way */ - drmBOSetStatus(ms->fd, &ms->bo, 0, 0, 0, 0, 0); - - drmBOUnreference(ms->fd, &ms->bo); - ms->front = FALSE; - RestoreHWState(pScrn); #if 0 @@ -1078,14 +897,12 @@ EnterVT(int scrnIndex, int flags) SaveHWState(pScrn); } - if (!ms->front) + if (!flags) /* signals startup as we'll do this in CreateScreenResources */ CreateFrontBuffer(pScrn); if (!xf86SetDesiredModes(pScrn)) return FALSE; - AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); - return TRUE; } @@ -1104,25 +921,19 @@ CloseScreen(int scrnIndex, ScreenPtr pScreen) modesettingPtr ms = modesettingPTR(pScrn); if (pScrn->vtSema) { - LeaveVT(scrnIndex, 0); + LeaveVT(scrnIndex, 0); #if 0 - drmMMUnlock(ms->fd, DRM_BO_MEM_VRAM, 1); - drmMMUnlock(ms->fd, DRM_BO_MEM_TT, 1); + drmMMUnlock(ms->fd, DRM_BO_MEM_VRAM, 1); + drmMMUnlock(ms->fd, DRM_BO_MEM_TT, 1); #endif } - #ifdef DRI2 driCloseScreen(pScreen); #endif pScreen->CreateScreenResources = ms->createScreenResources; - if (ms->shadowMem) { - xfree(ms->shadowMem); - ms->shadowMem = NULL; - } - - if (ms->pExa) + if (ms->exa) ExaClose(pScrn); drmClose(ms->fd); diff --git a/src/driver.h b/src/driver.h index 7ac6466..5b31188 100644 --- a/src/driver.h +++ b/src/driver.h @@ -32,7 +32,6 @@ #include <xf86drm.h> #include <xf86drmMode.h> #include <xf86mm.h> -#include "shadow.h" #include "exa.h" #define DRV_ERROR(msg) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, msg); @@ -49,14 +48,9 @@ typedef struct _modesettingRec { int fd; unsigned int fb_id; - void *virtual; - drmBO bo; - Bool front; EntPtr entityPrivate; - void (*PointerMoved) (int, int, int); - int Chipset; EntityInfoPtr pEnt; #if XSERVER_LIBPCIACCESS @@ -75,15 +69,12 @@ typedef struct _modesettingRec unsigned int SaveGeneration; - /* shadowfb */ - CARD8 *shadowMem; - Bool shadowFB; CreateScreenResourcesProcPtr createScreenResources; - ShadowUpdateProc update; /* exa */ - ExaDriverPtr pExa; - drmBO exa_bo; + void *exa; + void *driver; + Bool noEvict; /* dri2 */ drm_context_t context; @@ -31,19 +31,329 @@ #include "config.h" #endif +/* FIXME ! */ +#define DRI_DRIVER_PATH "/ISO/X.Org/modular/i386/lib/dri" + #include "xf86.h" #include "xf86_OSproc.h" - #include "driver.h" +#include <dlfcn.h> + +#include "pipe/p_winsys.h" +#include "pipe/p_format.h" +#include "pipe/p_context.h" +#include "pipe/p_util.h" +#include "pipe/p_state.h" +#include "pipe/p_inlines.h" + +/* EXA winsys */ +struct exa_context +{ +}; + +struct exa_winsys +{ + struct pipe_winsys base; + modesettingPtr ms; +}; -struct PixmapPriv { +struct exa_buffer +{ + struct pipe_buffer base; drmBO bo; - #if 0 + boolean userBuffer; /** Is this a user-space buffer? */ + //void *data; + //void *mapped; +}; + +struct exa_surface +{ + struct pipe_surface surface; +}; + +struct exa_entity +{ + ExaDriverPtr pExa; + struct exa_context *c; + struct pipe_winsys *ws; + struct pipe_context *ctx; + struct pipe_screen *scrn; +}; + +static INLINE struct exa_winsys * +exa_get_winsys(struct pipe_winsys *ws) +{ + return (struct exa_winsys *)ws; +} + +static INLINE struct exa_surface * +exa_get_surface(struct pipe_surface *ps) +{ + return (struct exa_surface *)ps; +} + +static INLINE struct exa_buffer * +exa_get_buffer(struct pipe_buffer *buf) +{ + return (struct exa_buffer *)buf; +} + +static void * +exa_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf, + unsigned flags) +{ + struct exa_buffer *exa_buf = exa_get_buffer(buf); + struct exa_winsys *exa_winsys = exa_get_winsys(pws); + void *virtual; + + drmBOMap(exa_winsys->ms->fd, + &exa_buf->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &virtual); + + return virtual; +} + +static void +exa_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf) +{ + struct exa_buffer *exa_buf = exa_get_buffer(buf); + struct exa_winsys *exa_winsys = exa_get_winsys(pws); + + drmBOUnmap(exa_winsys->ms->fd, &exa_buf->bo); +} + +static void +exa_buffer_destroy(struct pipe_winsys *pws, struct pipe_buffer *buf) +{ + struct exa_winsys *exa_winsys = exa_get_winsys(pws); + struct exa_buffer *exa_buf = exa_get_buffer(buf); + + drmBOUnreference(exa_winsys->ms->fd, &exa_buf->bo); + + free(exa_buf); +} + +static void +exa_flush_frontbuffer(struct pipe_winsys *pws, + struct pipe_surface *surf, void *context_private) +{ + struct exa_buffer *exa_buf = exa_get_buffer(surf->buffer); + + ErrorF("WANT TO FLUSH\n"); +} + +static const char * +exa_get_name(struct pipe_winsys *pws) +{ + return "EXA"; +} + +static struct pipe_buffer * +exa_buffer_create(struct pipe_winsys *pws, + unsigned alignment, unsigned usage, unsigned size) +{ + struct exa_buffer *buffer = xcalloc(1, sizeof(struct exa_buffer)); + struct exa_winsys *exa_winsys = exa_get_winsys(pws); + unsigned int flags = 0; + + buffer->base.refcount = 1; + buffer->base.alignment = alignment; + buffer->base.usage = usage; + buffer->base.size = size; + + if (exa_winsys->ms->noEvict) { + flags = DRM_BO_FLAG_NO_EVICT; + ErrorF("DISPLAY TARGET\n"); + } + + ErrorF("SIZE %d %d\n", size, alignment); + if (!buffer->bo.handle) { + // buffer->data = align_malloc(size, alignment); + drmBOCreate(exa_winsys->ms->fd, size, 4096, NULL, + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_SHAREABLE | DRM_BO_FLAG_MEM_TT | + DRM_BO_FLAG_MAPPABLE | DRM_BO_FLAG_CACHED_MAPPED | flags, + 0, &buffer->bo); + } + + return &buffer->base; +} + +static struct pipe_buffer * +exa_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes) +{ + struct exa_buffer *buffer = xcalloc(1, sizeof(struct exa_buffer)); + + buffer->base.refcount = 1; + buffer->base.size = bytes; + buffer->userBuffer = TRUE; + //buffer->data = ptr; + ErrorF("USERBUFFER\n"); + + return &buffer->base; +} + +/** + * Round n up to next multiple. + */ +static INLINE unsigned +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + +static int +exa_surface_alloc_storage(struct pipe_winsys *winsys, + struct pipe_surface *surf, + unsigned width, unsigned height, + enum pipe_format format, + unsigned flags, unsigned tex_usage) +{ + const unsigned alignment = 64; + + surf->width = width; + surf->height = height; + surf->format = format; + surf->cpp = pf_get_size(format); + surf->pitch = round_up(width, alignment / surf->cpp); + + assert(!surf->buffer); + surf->buffer = winsys->buffer_create(winsys, alignment, + PIPE_BUFFER_USAGE_PIXEL, + surf->pitch * surf->cpp * height); + if (!surf->buffer) + return -1; + + return 0; +} + +/** + * Called via winsys->surface_alloc() to create new surfaces. + */ +static struct pipe_surface * +exa_surface_alloc(struct pipe_winsys *ws) +{ + struct exa_surface *wms = xcalloc(1, sizeof(struct exa_surface)); + + assert(ws); + + wms->surface.refcount = 1; + wms->surface.winsys = ws; + + return &wms->surface; +} + +static void +exa_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) +{ + struct pipe_surface *surf = *s; + + surf->refcount--; + if (surf->refcount == 0) { + if (surf->buffer) + pipe_buffer_reference(winsys, &surf->buffer, NULL); + free(surf); + } + *s = NULL; +} + +/* + * Fence functions - basically nothing to do, as we don't create any actual + * fence objects. + */ +static void +exa_fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence) +{ +} + +static int +exa_fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + +static int +exa_fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + +struct pipe_winsys * +exa_get_pipe_winsys(modesettingPtr ms) +{ + static struct exa_winsys *ws = NULL; + + if (!ws) { + ws = xcalloc(1, sizeof(struct exa_winsys)); + + /* Fill in this struct with callbacks that pipe will need to + * communicate with the window system, buffer manager, etc. + */ + ws->base.buffer_create = exa_buffer_create; + ws->base.user_buffer_create = exa_user_buffer_create; + ws->base.buffer_map = exa_buffer_map; + ws->base.buffer_unmap = exa_buffer_unmap; + ws->base.buffer_destroy = exa_buffer_destroy; + + ws->base.surface_alloc = exa_surface_alloc; + ws->base.surface_alloc_storage = exa_surface_alloc_storage; + ws->base.surface_release = exa_surface_release; + + ws->base.fence_reference = exa_fence_reference; + ws->base.fence_signalled = exa_fence_signalled; + ws->base.fence_finish = exa_fence_finish; + + ws->base.flush_frontbuffer = exa_flush_frontbuffer; + ws->base.get_name = exa_get_name; + + ws->ms = ms; + } + + return &ws->base; +} + +/* EXA functions */ + +struct PixmapPriv +{ + drmBO bo; +#if 0 dri_fence *fence; - #endif +#endif int flags; + + struct pipe_texture *tex; + unsigned int color; + struct pipe_surface *src_surf; /* for copies */ }; +static enum pipe_format +exa_get_pipe_format(int depth) +{ + switch (depth) { + case 32: + case 24: + return PIPE_FORMAT_A8R8G8B8_UNORM; + case 16: + return PIPE_FORMAT_R5G6B5_UNORM; + case 15: + return PIPE_FORMAT_A1R5G5B5_UNORM; + case 8: + case 4: + case 1: + return PIPE_FORMAT_A8R8G8B8_UNORM; /* bad bad bad */ + default: + assert(0); + return 0; + } +} + +/* + * EXA functions + */ + static void ExaWaitMarker(ScreenPtr pScreen, int marker) { @@ -62,6 +372,7 @@ ExaPrepareAccess(PixmapPtr pPix, int index) ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; modesettingPtr ms = modesettingPTR(pScrn); PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); + struct exa_entity *exa = ms->exa; struct PixmapPriv *priv; int ret; @@ -70,21 +381,20 @@ ExaPrepareAccess(PixmapPtr pPix, int index) if (!priv) return FALSE; - if (priv->bo.handle) { - void *virtual; - - ret = drmBOMap(ms->fd, - &priv->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &virtual); - if (ret) { - driUnlock(pScreen); - FatalError("Failed to map pixmap: %s\n", strerror(-ret)); - return; - } - - pPix->devPrivate.ptr = priv->bo.virtual; + if (!priv->tex) + return FALSE; + { + struct pipe_surface *surf = + exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE); + pPix->devPrivate.ptr = + exa->scrn->surface_map(exa->scrn, surf, + PIPE_BUFFER_USAGE_CPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE); + exa->scrn->tex_surface_release(exa->scrn, &surf); } - return TRUE; } @@ -96,6 +406,7 @@ ExaFinishAccess(PixmapPtr pPix, int index) modesettingPtr ms = modesettingPTR(pScrn); PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); struct PixmapPriv *priv; + struct exa_entity *exa = ms->exa; int ret; priv = exaGetPixmapDriverPrivate(pPix); @@ -103,14 +414,15 @@ ExaFinishAccess(PixmapPtr pPix, int index) if (!priv) return; - if (priv->bo.handle) { - ret = drmBOUnmap(ms->fd, &priv->bo); - if (ret) { - driUnlock(pScreen); - FatalError("Failed to unmap pixmap: %s\n", strerror(-ret)); - return; - } - + if (!priv->tex) + return; + { + struct pipe_surface *surf = + exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE); + exa->scrn->surface_unmap(exa->scrn, surf); + exa->scrn->tex_surface_release(exa->scrn, &surf); pPix->devPrivate.ptr = NULL; } } @@ -119,6 +431,16 @@ static void ExaDone(PixmapPtr pPixmap) { ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap); + struct exa_entity *exa = ms->exa; + + if (!priv) + return; + + if (priv->src_surf) + exa->scrn->tex_surface_release(exa->scrn, &priv->src_surf); + priv->src_surf = NULL; } static void @@ -131,23 +453,46 @@ static Bool ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg) { ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap); + struct exa_entity *exa = ms->exa; - ErrorF("SOLID\n"); + if (pPixmap->drawable.depth < 15) + return FALSE; if (!EXA_PM_IS_SOLID(&pPixmap->drawable, planeMask)) return FALSE; - /* can't do depth 4 */ - if (pPixmap->drawable.depth == 4) + if (!priv->tex) return FALSE; - return FALSE; + if (alu != GXcopy) + return FALSE; + + if (!exa->ctx || !exa->ctx->surface_fill) + return FALSE; + + priv->color = fg; + + return TRUE; } static void -ExaSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) +ExaSolid(PixmapPtr pPixmap, int x0, int y0, int x1, int y1) { ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + struct exa_entity *exa = ms->exa; + struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap); + struct pipe_surface *surf = + exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0, + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_GPU_WRITE); + + exa->ctx->surface_fill(exa->ctx, surf, x0, y0, x1 - x0, y1 - y0, + priv->color); + + exa->scrn->tex_surface_release(exa->scrn, &surf); } static Bool @@ -155,13 +500,31 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, int ydir, int alu, Pixel planeMask) { ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + struct exa_entity *exa = ms->exa; + struct pipe_surface *src_surf; + struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pDstPixmap); + + if (alu != GXcopy) + return FALSE; + + if (pSrcPixmap->drawable.depth < 15 || pDstPixmap->drawable.depth < 15) + return FALSE; + + if (!EXA_PM_IS_SOLID(&pSrcPixmap->drawable, planeMask)) + return FALSE; - ErrorF("COPY\n"); + if (!priv->tex) + return FALSE; - /* can't do depth 4 */ - if (pSrcPixmap->drawable.depth == 4 || pDstPixmap->drawable.depth == 4) + if (!exa->ctx || !exa->ctx->surface_copy) return FALSE; + priv->src_surf = + exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0, + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_GPU_WRITE); + return FALSE; } @@ -170,6 +533,17 @@ ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int width, int height) { ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + struct exa_entity *exa = ms->exa; + struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pDstPixmap); + struct pipe_surface *surf = + exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0, + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_GPU_WRITE); + + exa->ctx->surface_copy(exa->ctx, 0, surf, dstX, dstY, priv->src_surf, + srcX, srcY, width, height); + exa->scrn->tex_surface_release(exa->scrn, &surf); } static Bool @@ -225,37 +599,29 @@ ExaCreatePixmap(ScreenPtr pScreen, int size, int align) priv = xcalloc(1, sizeof(struct PixmapPriv)); if (!priv) - return NULL; - - if (size == 0) - return priv; - - drmBOCreate(ms->fd, size, 4096, NULL, - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_SHAREABLE - | DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MAPPABLE | - DRM_BO_FLAG_CACHED_MAPPED, - 0, &priv->bo); + return NULL; return priv; } -static void +static void ExaDestroyPixmap(ScreenPtr pScreen, void *dPriv) { struct PixmapPriv *priv = (struct PixmapPriv *)dPriv; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; modesettingPtr ms = modesettingPTR(pScrn); + struct exa_entity *exa = ms->exa; if (!priv) - return; + return; - if (priv->bo.handle) - drmBOUnreference(ms->fd, &priv->bo); + if (priv->tex) + exa->scrn->texture_release(exa->scrn, &priv->tex); xfree(priv); } -static Bool +static Bool ExaPixmapIsOffscreen(PixmapPtr pPixmap) { struct PixmapPriv *priv; @@ -265,10 +631,10 @@ ExaPixmapIsOffscreen(PixmapPtr pPixmap) priv = exaGetPixmapDriverPrivate(pPixmap); if (!priv) - return FALSE; + return FALSE; - if (priv->bo.handle) - return TRUE; + if (priv->tex) + return TRUE; return FALSE; } @@ -281,87 +647,146 @@ driGetPixmapHandle(PixmapPtr pPixmap, unsigned int *flags) PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; modesettingPtr ms = modesettingPTR(pScrn); + struct exa_entity *exa = ms->exa; + struct exa_buffer *exa_buf; + struct pipe_surface *surf; struct PixmapPriv *priv; *flags = 0; - if (rootPixmap == pPixmap) - return ms->bo.handle; - - if (!ms->pExa) - return 0; + if (!ms->exa) { + FatalError("NO MS->EXA\n"); + return 0; + } priv = exaGetPixmapDriverPrivate(pPixmap); - if (!priv) - return 0; + if (!priv) { + FatalError("NO PIXMAP PRIVATE\n"); + return 0; + } + + surf = + exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE); + exa_buf = exa_get_buffer(surf->buffer); + exa->scrn->tex_surface_release(exa->scrn, &surf); - if (priv->bo.handle) - return priv->bo.handle; + if (exa_buf->bo.handle) + return exa_buf->bo.handle; return 0; } -static Bool +static Bool ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth, int bitsPerPixel, int devKind, pointer pPixData) { - ScreenPtr pScreen = pPixmap->drawable.pScreen; + ScreenPtr pScreen = pPixmap->drawable.pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap); modesettingPtr ms = modesettingPTR(pScrn); PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); + struct exa_entity *exa = ms->exa; - if (rootPixmap == pPixmap) { + /*if (rootPixmap == pPixmap) */ { miModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, devKind, NULL); + } - return TRUE; + if (!priv) + return FALSE; + + if (depth <= 0) + depth = pPixmap->drawable.depth; + + if (bitsPerPixel <= 0) + bitsPerPixel = pPixmap->drawable.bitsPerPixel; + + if (width <= 0) + width = pPixmap->drawable.width; + + if (height <= 0) + height = pPixmap->drawable.height; + + if (width <= 0 || height <= 0 || depth <= 0) + return FALSE; + + /* Deal with screen resize */ + if (priv->tex) { + struct pipe_surface *surf = + exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE); + + ErrorF("RESIZE %d %d to %d %d\n", surf->width, surf->height, width, + height); + if (surf->width != width || surf->height != height) { + exa->scrn->texture_release(exa->scrn, &priv->tex); + priv->tex = NULL; + } + exa->scrn->tex_surface_release(exa->scrn, &surf); } - return FALSE; -} + if (!priv->tex) { + struct pipe_texture template; + + memset(&template, 0, sizeof(template)); + template.target = PIPE_TEXTURE_2D; + template.compressed = 0; + template.format = exa_get_pipe_format(depth); + template.cpp = pf_get_size(template.format); + template.width[0] = width; + template.height[0] = height; + template.depth[0] = 1; + template.last_level = 0; + template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; + priv->tex = exa->scrn->texture_create(exa->scrn, &template); + } + + if (rootPixmap == pPixmap) + return TRUE; + return TRUE; +} void ExaClose(ScrnInfoPtr pScrn) { modesettingPtr ms = modesettingPTR(pScrn); + struct exa_entity *exa = ms->exa; exaDriverFini(pScrn->pScreen); -#if 0 - drmBOUnreference(ms->fd, &ms->exa_bo); -#endif + dlclose(ms->driver); } -ExaDriverPtr +void * ExaInit(ScrnInfoPtr pScrn) { modesettingPtr ms = modesettingPTR(pScrn); - ExaDriverPtr pExa; + struct exa_entity *exa; + ExaDriverPtr pExa = exa->pExa; + + exa = xcalloc(1, sizeof(struct exa_entity)); + if (!exa) + return NULL; pExa = exaDriverAlloc(); if (!pExa) { goto out_err; } -#if 0 - /* Create a 256KB offscreen area */ - drmBOCreate(ms->fd, 256 * 1024, 0, NULL, - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_MEM_TT, - DRM_BO_HINT_DONT_FENCE, &ms->exa_bo); -#endif - memset(pExa, 0, sizeof(*pExa)); pExa->exa_major = 2; pExa->exa_minor = 4; - pExa->memoryBase = 0; /* ms->exa_bo.virtual; */ - pExa->memorySize = 0; /* ms->exa_bo.size; */ + pExa->memoryBase = 0; + pExa->memorySize = 0; pExa->offScreenBase = 0; - pExa->pixmapOffsetAlign = 8; - pExa->pixmapPitchAlign = 32 * 4; + pExa->pixmapOffsetAlign = 0; + pExa->pixmapPitchAlign = 1; pExa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS; pExa->maxX = 8191; /* FIXME */ pExa->maxY = 8191; /* FIXME */ @@ -389,7 +814,30 @@ ExaInit(ScrnInfoPtr pScrn) goto out_err; } - return pExa; + { + char filename[128]; + char dri_driver_path[] = DRI_DRIVER_PATH; + + snprintf(filename, sizeof filename, + "%s/%s_dri.so", dri_driver_path, "i915"); + + ms->driver = dlopen(filename, RTLD_NOW | RTLD_DEEPBIND | RTLD_GLOBAL); + + exa->c = xcalloc(1, sizeof(struct exa_context)); + + exa->ws = exa_get_pipe_winsys(ms); + + exa->scrn = softpipe_create_screen(exa->ws); + + exa->ctx = softpipe_create(exa->scrn, exa->ws, NULL); + + if (!exa->ctx) + ErrorF("BAD CTX\n"); + + exa->ctx->priv = exa->c; + } + + return (void *)exa; out_err: ExaClose(pScrn); |