#include "xf86.h"
#include "xf86_OSproc.h"
#include "compiler.h"
-#include "xf86RAC.h"
#include "xf86PciInfo.h"
#include "xf86Pci.h"
-#include "xf86Resources.h"
#include "mipointer.h"
#include "micmap.h"
#include <X11/extensions/randr.h>
#include <pciaccess.h>
+#include "pipe/p_context.h"
#include "xorg_tracker.h"
#include "xorg_winsys.h"
{-1, NULL, OPTV_NONE, {0}, FALSE}
};
-/*
- * Functions that might be needed
- */
-
-static const char *exaSymbols[] = {
- "exaGetVersion",
- "exaDriverInit",
- "exaDriverFini",
- "exaOffscreenAlloc",
- "exaOffscreenFree",
- "exaWaitSync",
- NULL
-};
-
-static const char *fbSymbols[] = {
- "fbPictureInit",
- "fbScreenInit",
- NULL
-};
-
-static const char *ddcSymbols[] = {
- "xf86PrintEDID",
- "xf86SetDDCproperties",
- NULL
-};
-
/*
* Exported Xorg driver functions to winsys
*/
-void
-xorg_tracker_loader_ref_sym_lists()
-{
- LoaderRefSymLists(exaSymbols, fbSymbols, ddcSymbols, NULL);
-}
-
const OptionInfoRec *
xorg_tracker_available_options(int chipid, int busid)
{
CreateFrontBuffer(ScrnInfoPtr pScrn)
{
modesettingPtr ms = modesettingPTR(pScrn);
- ScreenPtr pScreen = pScrn->pScreen;
- PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
+ unsigned handle, stride;
+ struct pipe_texture *tex;
ms->noEvict = TRUE;
- pScreen->ModifyPixmapHeader(rootPixmap,
- pScrn->virtualX, pScrn->virtualY,
- pScrn->depth, pScrn->bitsPerPixel,
- pScrn->displayWidth * pScrn->bitsPerPixel / 8,
- NULL);
- ms->noEvict = FALSE;
+
+ tex = xorg_exa_create_root_texture(pScrn, pScrn->virtualX, pScrn->virtualY,
+ pScrn->depth, pScrn->bitsPerPixel);
+
+ if (!tex)
+ return FALSE;
+
+ if (!ms->api->local_handle_from_texture(ms->api, ms->screen,
+ tex,
+ &stride,
+ &handle))
+ return FALSE;
drmModeAddFB(ms->fd,
pScrn->virtualX,
pScrn->virtualY,
pScrn->depth,
pScrn->bitsPerPixel,
- pScrn->displayWidth * pScrn->bitsPerPixel / 8,
- xorg_exa_get_pixmap_handle(rootPixmap), &ms->fb_id);
+ stride,
+ handle,
+ &ms->fb_id);
pScrn->frameX0 = 0;
pScrn->frameY0 = 0;
AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ pipe_texture_reference(&ms->root_texture, tex);
+ pipe_texture_reference(&tex, NULL);
+ return TRUE;
+}
+
+static Bool
+BindTextureToRoot(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+ ScreenPtr pScreen = pScrn->pScreen;
+ struct pipe_texture *check;
+ PixmapPtr rootPixmap;
+
+ rootPixmap = pScreen->GetScreenPixmap(pScreen);
+
+ xorg_exa_set_displayed_usage(rootPixmap);
+ xorg_exa_set_shared_usage(rootPixmap);
+ xorg_exa_set_texture(rootPixmap, ms->root_texture);
+ if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, NULL))
+ FatalError("Couldn't adjust screen pixmap\n");
+
+ check = xorg_exa_get_texture(rootPixmap);
+ if (ms->root_texture != check)
+ FatalError("Created new root texture\n");
+
+ pipe_texture_reference(&check, NULL);
+
return TRUE;
}
crtc_resize(ScrnInfoPtr pScrn, int width, int height)
{
modesettingPtr ms = modesettingPTR(pScrn);
- //ScreenPtr pScreen = pScrn->pScreen;
- //PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
- //Bool fbAccessDisabled;
- //CARD8 *fbstart;
+ unsigned handle, stride;
+ PixmapPtr rootPixmap;
+ ScreenPtr pScreen = pScrn->pScreen;
if (width == pScrn->virtualX && height == pScrn->virtualY)
return TRUE;
pScrn->virtualX = width;
pScrn->virtualY = height;
+ /*
+ * Remove the old framebuffer & texture.
+ */
+ drmModeRmFB(ms->fd, ms->fb_id);
+ pipe_texture_reference(&ms->root_texture, NULL);
+
+
+ rootPixmap = pScreen->GetScreenPixmap(pScreen);
+ if (!pScreen->ModifyPixmapHeader(rootPixmap, width, height, -1, -1, -1, NULL))
+ return FALSE;
+
+ /* takes one ref */
+ ms->root_texture = xorg_exa_get_texture(rootPixmap);
+
+ if (!ms->api->local_handle_from_texture(ms->api, ms->screen,
+ ms->root_texture,
+ &stride,
+ &handle))
+ FatalError("Could not get handle and stride from texture\n");
+
+ drmModeAddFB(ms->fd,
+ pScrn->virtualX,
+ pScrn->virtualY,
+ pScrn->depth,
+ pScrn->bitsPerPixel,
+ stride,
+ handle,
+ &ms->fb_id);
+
/* HW dependent - FIXME */
pScrn->displayWidth = pScrn->virtualX;
- drmModeRmFB(ms->fd, ms->fb_id);
-
/* now create new frontbuffer */
- return CreateFrontBuffer(pScrn);
+ return CreateFrontBuffer(pScrn) && BindTextureToRoot(pScrn);
}
static const xf86CrtcConfigFuncsRec crtc_config_funcs = {
} else
ms->entityPrivate = NULL;
- if (xf86RegisterResources(ms->pEnt->index, NULL, ResNone)) {
- return FALSE;
- }
-
if (xf86IsEntityShared(pScrn->entityList[0])) {
if (xf86IsPrimInitDone(pScrn->entityList[0])) {
/* do something */
if (ms->fd < 0)
return FALSE;
- pScrn->racMemFlags = RAC_FB | RAC_COLORMAP;
pScrn->monitor = pScrn->confScreen->monitor;
pScrn->progClock = TRUE;
pScrn->rgbBits = 8;
return FALSE;
}
- xf86LoaderReqSymLists(fbSymbols, NULL);
-
xf86LoadSubModule(pScrn, "exa");
#ifdef DRI2
return TRUE;
}
+static void xorgBlockHandler(int i, pointer blockData, pointer pTimeout,
+ pointer pReadmask)
+{
+ ScreenPtr pScreen = screenInfo.screens[i];
+ modesettingPtr ms = modesettingPTR(xf86Screens[pScreen->myNum]);
+
+ pScreen->BlockHandler = ms->blockHandler;
+ pScreen->BlockHandler(i, blockData, pTimeout, pReadmask);
+ pScreen->BlockHandler = xorgBlockHandler;
+
+ ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE, NULL);
+
+#ifdef DRM_MODE_FEATURE_DIRTYFB
+ {
+ RegionPtr dirty = DamageRegion(ms->damage);
+ unsigned num_cliprects = REGION_NUM_RECTS(dirty);
+
+ if (num_cliprects) {
+ drmModeClip *clip = alloca(num_cliprects * sizeof(drmModeClip));
+ BoxPtr rect = REGION_RECTS(dirty);
+ int i;
+
+ for (i = 0; i < num_cliprects; i++, rect++) {
+ clip[i].x = rect->x1;
+ clip[i].y = rect->y1;
+ clip[i].width = rect->x2 - rect->x1;
+ clip[i].height = rect->y2 - rect->y1;
+ }
+
+ /* TODO query connector property to see if this is needed */
+ drmModeDirtyFB(ms->fd, ms->fb_id, clip, num_cliprects);
+
+ DamageEmpty(ms->damage);
+ }
+ }
+#endif
+}
+
static Bool
CreateScreenResources(ScreenPtr pScreen)
{
ret = pScreen->CreateScreenResources(pScreen);
pScreen->CreateScreenResources = CreateScreenResources;
- rootPixmap = pScreen->GetScreenPixmap(pScreen);
-
- if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, NULL))
- FatalError("Couldn't adjust screen pixmap\n");
+ BindTextureToRoot(pScrn);
ms->noEvict = FALSE;
- drmModeAddFB(ms->fd,
- pScrn->virtualX,
- pScrn->virtualY,
- pScrn->depth,
- pScrn->bitsPerPixel,
- pScrn->displayWidth * pScrn->bitsPerPixel / 8,
- xorg_exa_get_pixmap_handle(rootPixmap), &ms->fb_id);
-
AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+#ifdef DRM_MODE_FEATURE_DIRTYFB
+ rootPixmap = pScreen->GetScreenPixmap(pScreen);
+ ms->damage = DamageCreate(NULL, NULL, DamageReportNone, TRUE,
+ pScreen, rootPixmap);
+
+ if (ms->damage) {
+ DamageRegister(&rootPixmap->drawable, ms->damage);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Damage tracking initialized\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to create screen damage record\n");
+ return FALSE;
+ }
+#else
+ (void)rootPixmap;
+#endif
+
return ret;
}
return FALSE;
}
+ if (!ms->api)
+ ms->api = drm_api_create();
+
if (!ms->screen) {
ms->screen = ms->api->create_screen(ms->api, ms->fd, NULL);
fbPictureInit(pScreen, NULL, 0);
+ ms->blockHandler = pScreen->BlockHandler;
+ pScreen->BlockHandler = xorgBlockHandler;
ms->createScreenResources = pScreen->CreateScreenResources;
pScreen->CreateScreenResources = CreateScreenResources;
xf86SetBlackWhitePixels(pScreen);
ms->exa = xorg_exa_init(pScrn);
+ ms->debug_fallback = debug_get_bool_option("XORG_DEBUG_FALLBACK", TRUE);
+
+ xorg_init_video(pScreen);
miInitializeBackingStore(pScreen);
xf86SetBackingStore(pScreen);
xf86CrtcPtr crtc = output->crtc;
if (crtc && crtc->enabled) {
- crtc->funcs->mode_set(crtc, pScrn->currentMode, pScrn->currentMode, x,
- y);
+ crtc->funcs->set_mode_major(crtc, pScrn->currentMode,
+ RR_Rotate_0, x, y);
crtc->x = output->initial_x + x;
crtc->y = output->initial_y + y;
}
FreeRec(xf86Screens[scrnIndex]);
}
-/* HACK */
-void
-cursor_destroy(xf86CrtcPtr crtc);
-
static void
LeaveVT(int scrnIndex, int flags)
{
for (o = 0; o < config->num_crtc; o++) {
xf86CrtcPtr crtc = config->crtc[o];
- cursor_destroy(crtc);
+ crtc_cursor_destroy(crtc);
if (crtc->rotatedPixmap || crtc->rotatedData) {
crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap,
RestoreHWState(pScrn);
+ if (drmDropMaster(ms->fd))
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "drmDropMaster failed: %s\n", strerror(errno));
+
pScrn->vtSema = FALSE;
}
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
modesettingPtr ms = modesettingPTR(pScrn);
+ if (drmSetMaster(ms->fd)) {
+ if (errno == EINVAL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "drmSetMaster failed: 2.6.29 or newer kernel required for "
+ "multi-server DRI\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "drmSetMaster failed: %s\n", strerror(errno));
+ }
+ }
+
/*
* Only save state once per server generation since that's what most
* drivers do. Could change this to save state at each VT enter.
SaveHWState(pScrn);
}
- if (!flags) /* signals startup as we'll do this in CreateScreenResources */
- CreateFrontBuffer(pScrn);
+ if (!CreateFrontBuffer(pScrn))
+ return FALSE;
+
+ if (!flags && !BindTextureToRoot(pScrn))
+ return FALSE;
if (!xf86SetDesiredModes(pScrn))
return FALSE;
driCloseScreen(pScreen);
#endif
+ pScreen->BlockHandler = ms->blockHandler;
pScreen->CreateScreenResources = ms->createScreenResources;
+#ifdef DRM_MODE_FEATURE_DIRTYFB
+ if (ms->damage) {
+ DamageUnregister(&pScreen->GetScreenPixmap(pScreen)->drawable, ms->damage);
+ DamageDestroy(ms->damage);
+ ms->damage = NULL;
+ }
+#endif
+
+ pipe_texture_reference(&ms->root_texture, NULL);
+
if (ms->exa)
xorg_exa_close(pScrn);
+ if (ms->api && ms->api->destroy)
ms->api->destroy(ms->api);
- ms->api = NULL;
+ ms->api = NULL;
+
drmClose(ms->fd);
ms->fd = -1;