summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Hourihane <alanh@tungstengraphics.com>2008-06-26 22:27:44 +0100
committerAlan Hourihane <alanh@tungstengraphics.com>2008-06-26 22:27:44 +0100
commitacb7da8c7979659bcfdfef7a6ee5b402f6fb366b (patch)
tree14f65449a8a1fd4beccb46c7c0bbedfba477f632
parent169e39c504a0ac52828108a4490fc45198812fd1 (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.c303
-rw-r--r--src/driver.h15
-rw-r--r--src/exa.c614
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;
diff --git a/src/exa.c b/src/exa.c
index 9327cbc..124dc03 100644
--- a/src/exa.c
+++ b/src/exa.c
@@ -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);