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.
This commit is contained in:
Alan Hourihane 2008-06-26 22:27:44 +01:00
parent 0e1aa03708
commit ccd0c76472
3 changed files with 596 additions and 346 deletions

View File

@ -40,7 +40,6 @@
#include "xf86Resources.h" #include "xf86Resources.h"
#include "mipointer.h" #include "mipointer.h"
#include "micmap.h" #include "micmap.h"
#include "shadowfb.h"
#include <X11/extensions/randr.h> #include <X11/extensions/randr.h>
#include "fb.h" #include "fb.h"
#include "edid.h" #include "edid.h"
@ -50,7 +49,6 @@
#include "dixstruct.h" #include "dixstruct.h"
#include "xf86xv.h" #include "xf86xv.h"
#include <X11/extensions/Xv.h> #include <X11/extensions/Xv.h>
#include "shadow.h"
#include <xorg-server.h> #include <xorg-server.h>
#if XSERVER_LIBPCIACCESS #if XSERVER_LIBPCIACCESS
#include <pciaccess.h> #include <pciaccess.h>
@ -120,15 +118,11 @@ static PciChipsets PciDevices[] = {
typedef enum typedef enum
{ {
OPTION_NOACCEL,
OPTION_SW_CURSOR, OPTION_SW_CURSOR,
OPTION_SHADOWFB,
} modesettingOpts; } modesettingOpts;
static const OptionInfoRec Options[] = { static const OptionInfoRec Options[] = {
{OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_SW_CURSOR, "SWcursor", 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} {-1, NULL, OPTV_NONE, {0}, FALSE}
}; };
@ -154,12 +148,6 @@ static const char *ddcSymbols[] = {
NULL NULL
}; };
static const char *shadowSymbols[] = {
"shadowInit",
"shadowUpdatePackedWeak",
NULL
};
static const char *i2cSymbols[] = { static const char *i2cSymbols[] = {
"xf86CreateI2CBusRec", "xf86CreateI2CBusRec",
"xf86I2CBusInit", "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 * Tell the loader about symbols from other modules that this module
* might refer to. * 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 * The return value must be non-NULL on success even though there
@ -323,7 +311,6 @@ Probe(DriverPtr drv, int flags)
if (numUsed > 0) if (numUsed > 0)
foundScreen = TRUE; foundScreen = TRUE;
} else { } else {
ErrorF("NUMUSED %d\n", numUsed);
for (i = 0; i < numUsed; i++) { for (i = 0; i < numUsed; i++) {
ScrnInfoPtr pScrn = NULL; ScrnInfoPtr pScrn = NULL;
@ -419,36 +406,6 @@ ProbeDDC(ScrnInfoPtr pScrn, int index)
ConfiguredMonitor = NULL; ConfiguredMonitor = NULL;
} }
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 static Bool
CreateFrontBuffer(ScrnInfoPtr pScrn) CreateFrontBuffer(ScrnInfoPtr pScrn)
{ {
@ -456,18 +413,15 @@ CreateFrontBuffer(ScrnInfoPtr pScrn)
ScreenPtr pScreen = pScrn->pScreen; ScreenPtr pScreen = pScrn->pScreen;
PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
Bool fbAccessDisabled; Bool fbAccessDisabled;
CARD8 *fbstart; int flags;
drmBOCreate(ms->fd, ms->noEvict = TRUE;
pScrn->virtualY * pScrn->displayWidth * pScreen->ModifyPixmapHeader(rootPixmap,
pScrn->bitsPerPixel / 8, 0, NULL, pScrn->virtualX, pScrn->virtualY,
DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_SHAREABLE pScrn->depth, pScrn->bitsPerPixel,
| DRM_BO_FLAG_CACHED_MAPPED pScrn->displayWidth * pScrn->bitsPerPixel / 8,
| DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_MAPPABLE | NULL);
/*DRM_BO_FLAG_MEM_VRAM |*/ DRM_BO_FLAG_MEM_TT, ms->noEvict = FALSE;
0, &ms->bo);
MapMem(pScrn);
drmModeAddFB(ms->fd, drmModeAddFB(ms->fd,
pScrn->virtualX, pScrn->virtualX,
@ -475,50 +429,12 @@ CreateFrontBuffer(ScrnInfoPtr pScrn)
pScrn->depth, pScrn->depth,
pScrn->bitsPerPixel, pScrn->bitsPerPixel,
pScrn->displayWidth * pScrn->bitsPerPixel / 8, pScrn->displayWidth * pScrn->bitsPerPixel / 8,
ms->bo.handle, &ms->fb_id); driGetPixmapHandle(rootPixmap, &flags), &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;
}
pScrn->frameX0 = 0; pScrn->frameX0 = 0;
pScrn->frameY0 = 0; pScrn->frameY0 = 0;
AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
UnmapMem(pScrn);
ms->front = TRUE;
return TRUE; return TRUE;
} }
@ -538,22 +454,12 @@ crtc_resize(ScrnInfoPtr pScrn, int width, int height)
pScrn->virtualX = width; pScrn->virtualX = width;
pScrn->virtualY = height; pScrn->virtualY = height;
pScrn->displayWidth = (pScrn->virtualX + 63) & ~63;
if (ms->shadowMem) { /* HW dependent - FIXME */
xfree(ms->shadowMem); pScrn->displayWidth = pScrn->virtualX;
ms->shadowMem = NULL;
}
drmModeRmFB(ms->fd, ms->fb_id); 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 */ /* now create new frontbuffer */
return CreateFrontBuffer(pScrn); return CreateFrontBuffer(pScrn);
} }
@ -571,7 +477,6 @@ PreInit(ScrnInfoPtr pScrn, int flags)
rgb defaultWeight = { 0, 0, 0 }; rgb defaultWeight = { 0, 0, 0 };
EntityInfoPtr pEnt; EntityInfoPtr pEnt;
EntPtr msEnt = NULL; EntPtr msEnt = NULL;
int flags24;
char *BusID; char *BusID;
int i; int i;
char *s; char *s;
@ -645,13 +550,12 @@ PreInit(ScrnInfoPtr pScrn, int flags)
pScrn->progClock = TRUE; pScrn->progClock = TRUE;
pScrn->rgbBits = 8; pScrn->rgbBits = 8;
flags24 = Support32bppFb | PreferConvert24to32 | SupportConvert24to32; if (!xf86SetDepthBpp
(pScrn, 0, 0, 0,
if (!xf86SetDepthBpp(pScrn, 0, 0, 0, flags24)) PreferConvert24to32 | SupportConvert24to32 | Support32bppFb))
return FALSE; return FALSE;
switch (pScrn->depth) { switch (pScrn->depth) {
case 8:
case 15: case 15:
case 16: case 16:
case 24: case 24:
@ -684,23 +588,10 @@ PreInit(ScrnInfoPtr pScrn, int flags)
max_height = 8192; max_height = 8192;
xf86CrtcSetSizeRange(pScrn, 320, 200, max_width, max_height); 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)) { if (xf86ReturnOptValBool(ms->Options, OPTION_SW_CURSOR, FALSE)) {
ms->SWCursor = TRUE; ms->SWCursor = TRUE;
} }
if (xf86ReturnOptValBool(ms->Options, OPTION_SHADOWFB, FALSE)) {
if (!xf86LoadSubModule(pScrn, "shadow"))
return FALSE;
xf86LoaderReqSymLists(shadowSymbols, NULL);
ms->shadowFB = TRUE;
}
SaveHWState(pScrn); SaveHWState(pScrn);
crtc_init(pScrn); crtc_init(pScrn);
@ -767,42 +658,37 @@ RestoreHWState(ScrnInfoPtr pScrn)
return TRUE; 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 static Bool
CreateScreenResources(ScreenPtr pScreen) CreateScreenResources(ScreenPtr pScreen)
{ {
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn); modesettingPtr ms = modesettingPTR(pScrn);
PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); PixmapPtr rootPixmap;
Bool ret; Bool ret;
int flags;
ms->noEvict = TRUE;
pScreen->CreateScreenResources = ms->createScreenResources; pScreen->CreateScreenResources = ms->createScreenResources;
ret = pScreen->CreateScreenResources(pScreen); ret = pScreen->CreateScreenResources(pScreen);
pScreen->CreateScreenResources = CreateScreenResources; pScreen->CreateScreenResources = CreateScreenResources;
if (ms->shadowFB) rootPixmap = pScreen->GetScreenPixmap(pScreen);
shadowAdd(pScreen, rootPixmap,
ms->update, WindowLinear, 0, 0);
if (!pScreen->ModifyPixmapHeader(pScreen->GetScreenPixmap(pScreen), if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, NULL))
-1, -1, -1, -1, -1,
ms->shadowFB ? (pointer)ms->shadowMem : (pointer)ms->bo.virtual))
FatalError("Couldn't adjust screen pixmap\n"); 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; return ret;
} }
@ -816,33 +702,33 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
unsigned long sys_mem; unsigned long sys_mem;
int c; int c;
MessageType from; MessageType from;
CARD8 *fbstart;
/* deal with server regeneration */ /* deal with server regeneration */
if (ms->fd < 0) { if (ms->fd < 0) {
char *BusID; char *BusID;
BusID = xalloc(64); BusID = xalloc(64);
sprintf(BusID, "PCI:%d:%d:%d", sprintf(BusID, "PCI:%d:%d:%d",
#if XSERVER_LIBPCIACCESS #if XSERVER_LIBPCIACCESS
((ms->PciInfo->domain << 8) | ms->PciInfo->bus), ((ms->PciInfo->domain << 8) | ms->PciInfo->bus),
ms->PciInfo->dev, ms->PciInfo->func ms->PciInfo->dev, ms->PciInfo->func
#else #else
((pciConfigPtr) ms->PciInfo->thisCard)->busnum, ((pciConfigPtr) ms->PciInfo->thisCard)->busnum,
((pciConfigPtr) ms->PciInfo->thisCard)->devnum, ((pciConfigPtr) ms->PciInfo->thisCard)->devnum,
((pciConfigPtr) ms->PciInfo->thisCard)->funcnum ((pciConfigPtr) ms->PciInfo->thisCard)->funcnum
#endif #endif
); );
ms->fd = drmOpen(NULL, BusID); ms->fd = drmOpen(NULL, BusID);
if (ms->fd < 0) if (ms->fd < 0)
return FALSE; return FALSE;
} }
pScrn->pScreen = pScreen; pScrn->pScreen = pScreen;
pScrn->displayWidth = (pScrn->virtualX + 63) & ~63; /* HW dependent - FIXME */
pScrn->displayWidth = pScrn->virtualX;
miClearVisualTypes(); miClearVisualTypes();
@ -857,39 +743,7 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pScrn->memPhysBase = 0; pScrn->memPhysBase = 0;
pScrn->fbOffset = 0; pScrn->fbOffset = 0;
drmBOCreate(ms->fd, if (!fbScreenInit(pScreen, NULL,
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,
pScrn->virtualX, pScrn->virtualY, pScrn->virtualX, pScrn->virtualY,
pScrn->xDpi, pScrn->yDpi, pScrn->xDpi, pScrn->yDpi,
pScrn->displayWidth, pScrn->bitsPerPixel)) pScrn->displayWidth, pScrn->bitsPerPixel))
@ -911,26 +765,13 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
} }
fbPictureInit(pScreen, NULL, 0); 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; ms->createScreenResources = pScreen->CreateScreenResources;
pScreen->CreateScreenResources = CreateScreenResources; pScreen->CreateScreenResources = CreateScreenResources;
xf86SetBlackWhitePixels(pScreen); xf86SetBlackWhitePixels(pScreen);
#if 0 ms->exa = ExaInit(pScrn);
glucoseScreenInit(pScreen, 0);
#endif
#if 1
ms->pExa = ExaInit(pScrn);
#endif
miInitializeBackingStore(pScreen); miInitializeBackingStore(pScreen);
xf86SetBackingStore(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 */ /* Need to extend HWcursor support to handle mask interleave */
if (!ms->SWCursor) if (!ms->SWCursor)
xf86_cursors_init (pScreen, 64, 64, xf86_cursors_init(pScreen, 64, 64,
HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 | HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 |
HARDWARE_CURSOR_ARGB); HARDWARE_CURSOR_ARGB);
/* Must force it before EnterVT, so we are in control of VT and /* Must force it before EnterVT, so we are in control of VT and
* later memory should be bound when allocating, e.g rotate_mem */ * 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)) if (!miCreateDefColormap(pScreen))
return FALSE; 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); xf86DPMSInit(pScreen, xf86DPMSSet, 0);
#if 0
glucoseInitVideo(pScreen);
#endif
if (serverGeneration == 1) if (serverGeneration == 1)
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
@ -978,11 +807,7 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
driScreenInit(pScreen); driScreenInit(pScreen);
#endif #endif
UnmapMem(pScrn); return EnterVT(scrnIndex, 1);
ms->front = TRUE;
return EnterVT(scrnIndex, 0);
} }
static void static void
@ -1018,7 +843,7 @@ LeaveVT(int scrnIndex, int flags)
for (o = 0; o < config->num_crtc; o++) { for (o = 0; o < config->num_crtc; o++) {
xf86CrtcPtr crtc = config->crtc[o]; xf86CrtcPtr crtc = config->crtc[o];
cursor_destroy(crtc); cursor_destroy(crtc);
if (crtc->rotatedPixmap || crtc->rotatedData) { if (crtc->rotatedPixmap || crtc->rotatedData) {
crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap, crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap,
@ -1030,12 +855,6 @@ LeaveVT(int scrnIndex, int flags)
drmModeRmFB(ms->fd, ms->fb_id); 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); RestoreHWState(pScrn);
#if 0 #if 0
@ -1078,14 +897,12 @@ EnterVT(int scrnIndex, int flags)
SaveHWState(pScrn); SaveHWState(pScrn);
} }
if (!ms->front) if (!flags) /* signals startup as we'll do this in CreateScreenResources */
CreateFrontBuffer(pScrn); CreateFrontBuffer(pScrn);
if (!xf86SetDesiredModes(pScrn)) if (!xf86SetDesiredModes(pScrn))
return FALSE; return FALSE;
AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
return TRUE; return TRUE;
} }
@ -1104,25 +921,19 @@ CloseScreen(int scrnIndex, ScreenPtr pScreen)
modesettingPtr ms = modesettingPTR(pScrn); modesettingPtr ms = modesettingPTR(pScrn);
if (pScrn->vtSema) { if (pScrn->vtSema) {
LeaveVT(scrnIndex, 0); LeaveVT(scrnIndex, 0);
#if 0 #if 0
drmMMUnlock(ms->fd, DRM_BO_MEM_VRAM, 1); drmMMUnlock(ms->fd, DRM_BO_MEM_VRAM, 1);
drmMMUnlock(ms->fd, DRM_BO_MEM_TT, 1); drmMMUnlock(ms->fd, DRM_BO_MEM_TT, 1);
#endif #endif
} }
#ifdef DRI2 #ifdef DRI2
driCloseScreen(pScreen); driCloseScreen(pScreen);
#endif #endif
pScreen->CreateScreenResources = ms->createScreenResources; pScreen->CreateScreenResources = ms->createScreenResources;
if (ms->shadowMem) { if (ms->exa)
xfree(ms->shadowMem);
ms->shadowMem = NULL;
}
if (ms->pExa)
ExaClose(pScrn); ExaClose(pScrn);
drmClose(ms->fd); drmClose(ms->fd);

View File

@ -32,7 +32,6 @@
#include <xf86drm.h> #include <xf86drm.h>
#include <xf86drmMode.h> #include <xf86drmMode.h>
#include <xf86mm.h> #include <xf86mm.h>
#include "shadow.h"
#include "exa.h" #include "exa.h"
#define DRV_ERROR(msg) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, msg); #define DRV_ERROR(msg) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, msg);
@ -49,14 +48,9 @@ typedef struct _modesettingRec
{ {
int fd; int fd;
unsigned int fb_id; unsigned int fb_id;
void *virtual;
drmBO bo;
Bool front;
EntPtr entityPrivate; EntPtr entityPrivate;
void (*PointerMoved) (int, int, int);
int Chipset; int Chipset;
EntityInfoPtr pEnt; EntityInfoPtr pEnt;
#if XSERVER_LIBPCIACCESS #if XSERVER_LIBPCIACCESS
@ -75,15 +69,12 @@ typedef struct _modesettingRec
unsigned int SaveGeneration; unsigned int SaveGeneration;
/* shadowfb */
CARD8 *shadowMem;
Bool shadowFB;
CreateScreenResourcesProcPtr createScreenResources; CreateScreenResourcesProcPtr createScreenResources;
ShadowUpdateProc update;
/* exa */ /* exa */
ExaDriverPtr pExa; void *exa;
drmBO exa_bo; void *driver;
Bool noEvict;
/* dri2 */ /* dri2 */
drm_context_t context; drm_context_t context;

View File

@ -31,19 +31,329 @@
#include "config.h" #include "config.h"
#endif #endif
/* FIXME ! */
#define DRI_DRIVER_PATH "/ISO/X.Org/modular/i386/lib/dri"
#include "xf86.h" #include "xf86.h"
#include "xf86_OSproc.h" #include "xf86_OSproc.h"
#include "driver.h" #include "driver.h"
#include <dlfcn.h>
struct PixmapPriv { #include "pipe/p_winsys.h"
drmBO bo; #include "pipe/p_format.h"
#if 0 #include "pipe/p_context.h"
dri_fence *fence; #include "pipe/p_util.h"
#endif #include "pipe/p_state.h"
int flags; #include "pipe/p_inlines.h"
/* EXA winsys */
struct exa_context
{
}; };
struct exa_winsys
{
struct pipe_winsys base;
modesettingPtr ms;
};
struct exa_buffer
{
struct pipe_buffer base;
drmBO bo;
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
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 static void
ExaWaitMarker(ScreenPtr pScreen, int marker) ExaWaitMarker(ScreenPtr pScreen, int marker)
{ {
@ -62,6 +372,7 @@ ExaPrepareAccess(PixmapPtr pPix, int index)
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn); modesettingPtr ms = modesettingPTR(pScrn);
PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
struct exa_entity *exa = ms->exa;
struct PixmapPriv *priv; struct PixmapPriv *priv;
int ret; int ret;
@ -70,21 +381,20 @@ ExaPrepareAccess(PixmapPtr pPix, int index)
if (!priv) if (!priv)
return FALSE; return FALSE;
if (priv->bo.handle) { if (!priv->tex)
void *virtual; return FALSE;
{
ret = drmBOMap(ms->fd, struct pipe_surface *surf =
&priv->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &virtual); exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0,
if (ret) { PIPE_BUFFER_USAGE_CPU_READ |
driUnlock(pScreen); PIPE_BUFFER_USAGE_CPU_WRITE);
FatalError("Failed to map pixmap: %s\n", strerror(-ret)); pPix->devPrivate.ptr =
return; exa->scrn->surface_map(exa->scrn, surf,
} PIPE_BUFFER_USAGE_CPU_READ |
PIPE_BUFFER_USAGE_CPU_WRITE);
pPix->devPrivate.ptr = priv->bo.virtual; exa->scrn->tex_surface_release(exa->scrn, &surf);
} }
return TRUE; return TRUE;
} }
@ -96,6 +406,7 @@ ExaFinishAccess(PixmapPtr pPix, int index)
modesettingPtr ms = modesettingPTR(pScrn); modesettingPtr ms = modesettingPTR(pScrn);
PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
struct PixmapPriv *priv; struct PixmapPriv *priv;
struct exa_entity *exa = ms->exa;
int ret; int ret;
priv = exaGetPixmapDriverPrivate(pPix); priv = exaGetPixmapDriverPrivate(pPix);
@ -103,14 +414,15 @@ ExaFinishAccess(PixmapPtr pPix, int index)
if (!priv) if (!priv)
return; return;
if (priv->bo.handle) { if (!priv->tex)
ret = drmBOUnmap(ms->fd, &priv->bo); return;
if (ret) { {
driUnlock(pScreen); struct pipe_surface *surf =
FatalError("Failed to unmap pixmap: %s\n", strerror(-ret)); exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0,
return; 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; pPix->devPrivate.ptr = NULL;
} }
} }
@ -119,6 +431,16 @@ static void
ExaDone(PixmapPtr pPixmap) ExaDone(PixmapPtr pPixmap)
{ {
ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 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 static void
@ -131,23 +453,46 @@ static Bool
ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg) ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
{ {
ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 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)) if (!EXA_PM_IS_SOLID(&pPixmap->drawable, planeMask))
return FALSE; return FALSE;
/* can't do depth 4 */ if (!priv->tex)
if (pPixmap->drawable.depth == 4)
return FALSE; 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 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]; 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 static Bool
@ -155,13 +500,31 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
int ydir, int alu, Pixel planeMask) int ydir, int alu, Pixel planeMask)
{ {
ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 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);
ErrorF("COPY\n"); if (alu != GXcopy)
/* can't do depth 4 */
if (pSrcPixmap->drawable.depth == 4 || pDstPixmap->drawable.depth == 4)
return FALSE; return FALSE;
if (pSrcPixmap->drawable.depth < 15 || pDstPixmap->drawable.depth < 15)
return FALSE;
if (!EXA_PM_IS_SOLID(&pSrcPixmap->drawable, planeMask))
return FALSE;
if (!priv->tex)
return FALSE;
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; return FALSE;
} }
@ -170,6 +533,17 @@ ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY,
int width, int height) int width, int height)
{ {
ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 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 static Bool
@ -225,37 +599,29 @@ ExaCreatePixmap(ScreenPtr pScreen, int size, int align)
priv = xcalloc(1, sizeof(struct PixmapPriv)); priv = xcalloc(1, sizeof(struct PixmapPriv));
if (!priv) if (!priv)
return NULL; 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 priv; return priv;
} }
static void static void
ExaDestroyPixmap(ScreenPtr pScreen, void *dPriv) ExaDestroyPixmap(ScreenPtr pScreen, void *dPriv)
{ {
struct PixmapPriv *priv = (struct PixmapPriv *)dPriv; struct PixmapPriv *priv = (struct PixmapPriv *)dPriv;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn); modesettingPtr ms = modesettingPTR(pScrn);
struct exa_entity *exa = ms->exa;
if (!priv) if (!priv)
return; return;
if (priv->bo.handle) if (priv->tex)
drmBOUnreference(ms->fd, &priv->bo); exa->scrn->texture_release(exa->scrn, &priv->tex);
xfree(priv); xfree(priv);
} }
static Bool static Bool
ExaPixmapIsOffscreen(PixmapPtr pPixmap) ExaPixmapIsOffscreen(PixmapPtr pPixmap)
{ {
struct PixmapPriv *priv; struct PixmapPriv *priv;
@ -265,10 +631,10 @@ ExaPixmapIsOffscreen(PixmapPtr pPixmap)
priv = exaGetPixmapDriverPrivate(pPixmap); priv = exaGetPixmapDriverPrivate(pPixmap);
if (!priv) if (!priv)
return FALSE; return FALSE;
if (priv->bo.handle) if (priv->tex)
return TRUE; return TRUE;
return FALSE; return FALSE;
} }
@ -281,87 +647,146 @@ driGetPixmapHandle(PixmapPtr pPixmap, unsigned int *flags)
PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn); modesettingPtr ms = modesettingPTR(pScrn);
struct exa_entity *exa = ms->exa;
struct exa_buffer *exa_buf;
struct pipe_surface *surf;
struct PixmapPriv *priv; struct PixmapPriv *priv;
*flags = 0; *flags = 0;
if (rootPixmap == pPixmap) if (!ms->exa) {
return ms->bo.handle; FatalError("NO MS->EXA\n");
return 0;
if (!ms->pExa) }
return 0;
priv = exaGetPixmapDriverPrivate(pPixmap); priv = exaGetPixmapDriverPrivate(pPixmap);
if (!priv) if (!priv) {
return 0; FatalError("NO PIXMAP PRIVATE\n");
return 0;
}
if (priv->bo.handle) surf =
return priv->bo.handle; 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 (exa_buf->bo.handle)
return exa_buf->bo.handle;
return 0; return 0;
} }
static Bool static Bool
ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
int depth, int bitsPerPixel, int devKind, int depth, int bitsPerPixel, int devKind,
pointer pPixData) pointer pPixData)
{ {
ScreenPtr pScreen = pPixmap->drawable.pScreen; ScreenPtr pScreen = pPixmap->drawable.pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap); struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap);
modesettingPtr ms = modesettingPTR(pScrn); modesettingPtr ms = modesettingPTR(pScrn);
PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
struct exa_entity *exa = ms->exa;
if (rootPixmap == pPixmap) { /*if (rootPixmap == pPixmap) */ {
miModifyPixmapHeader(pPixmap, width, height, depth, miModifyPixmapHeader(pPixmap, width, height, depth,
bitsPerPixel, devKind, NULL); bitsPerPixel, devKind, NULL);
return TRUE;
} }
return FALSE; 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);
}
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 void
ExaClose(ScrnInfoPtr pScrn) ExaClose(ScrnInfoPtr pScrn)
{ {
modesettingPtr ms = modesettingPTR(pScrn); modesettingPtr ms = modesettingPTR(pScrn);
struct exa_entity *exa = ms->exa;
exaDriverFini(pScrn->pScreen); exaDriverFini(pScrn->pScreen);
#if 0 dlclose(ms->driver);
drmBOUnreference(ms->fd, &ms->exa_bo);
#endif
} }
ExaDriverPtr void *
ExaInit(ScrnInfoPtr pScrn) ExaInit(ScrnInfoPtr pScrn)
{ {
modesettingPtr ms = modesettingPTR(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(); pExa = exaDriverAlloc();
if (!pExa) { if (!pExa) {
goto out_err; 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)); memset(pExa, 0, sizeof(*pExa));
pExa->exa_major = 2; pExa->exa_major = 2;
pExa->exa_minor = 4; pExa->exa_minor = 4;
pExa->memoryBase = 0; /* ms->exa_bo.virtual; */ pExa->memoryBase = 0;
pExa->memorySize = 0; /* ms->exa_bo.size; */ pExa->memorySize = 0;
pExa->offScreenBase = 0; pExa->offScreenBase = 0;
pExa->pixmapOffsetAlign = 8; pExa->pixmapOffsetAlign = 0;
pExa->pixmapPitchAlign = 32 * 4; pExa->pixmapPitchAlign = 1;
pExa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS; pExa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS;
pExa->maxX = 8191; /* FIXME */ pExa->maxX = 8191; /* FIXME */
pExa->maxY = 8191; /* FIXME */ pExa->maxY = 8191; /* FIXME */
@ -389,7 +814,30 @@ ExaInit(ScrnInfoPtr pScrn)
goto out_err; 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: out_err:
ExaClose(pScrn); ExaClose(pScrn);