summaryrefslogtreecommitdiff
path: root/src/gallium/state_trackers/xorg/xorg_driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/state_trackers/xorg/xorg_driver.c')
-rw-r--r--src/gallium/state_trackers/xorg/xorg_driver.c630
1 files changed, 436 insertions, 194 deletions
diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c
index 26cf2dd772..b02fe68f31 100644
--- a/src/gallium/state_trackers/xorg/xorg_driver.c
+++ b/src/gallium/state_trackers/xorg/xorg_driver.c
@@ -56,32 +56,38 @@
#include "xorg_tracker.h"
#include "xorg_winsys.h"
-static void AdjustFrame(int scrnIndex, int x, int y, int flags);
-static Bool CloseScreen(int scrnIndex, ScreenPtr pScreen);
-static Bool EnterVT(int scrnIndex, int flags);
-static Bool SaveHWState(ScrnInfoPtr pScrn);
-static Bool RestoreHWState(ScrnInfoPtr pScrn);
-
-
-static ModeStatus ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose,
- int flags);
-static void FreeScreen(int scrnIndex, int flags);
-static void LeaveVT(int scrnIndex, int flags);
-static Bool SwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
-static Bool ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc,
- char **argv);
-static Bool PreInit(ScrnInfoPtr pScrn, int flags);
+#ifdef HAVE_LIBKMS
+#include "libkms.h"
+#endif
+
+/*
+ * Functions and symbols exported to Xorg via pointers.
+ */
+
+static Bool drv_pre_init(ScrnInfoPtr pScrn, int flags);
+static Bool drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc,
+ char **argv);
+static Bool drv_switch_mode(int scrnIndex, DisplayModePtr mode, int flags);
+static void drv_adjust_frame(int scrnIndex, int x, int y, int flags);
+static Bool drv_enter_vt(int scrnIndex, int flags);
+static void drv_leave_vt(int scrnIndex, int flags);
+static void drv_free_screen(int scrnIndex, int flags);
+static ModeStatus drv_valid_mode(int scrnIndex, DisplayModePtr mode, Bool verbose,
+ int flags);
typedef enum
{
OPTION_SW_CURSOR,
-} modesettingOpts;
+ OPTION_2D_ACCEL,
+} drv_option_enums;
-static const OptionInfoRec Options[] = {
+static const OptionInfoRec drv_options[] = {
{OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_2D_ACCEL, "2DAccel", OPTV_BOOLEAN, {0}, FALSE},
{-1, NULL, OPTV_NONE, {0}, FALSE}
};
+
/*
* Exported Xorg driver functions to winsys
*/
@@ -89,28 +95,39 @@ static const OptionInfoRec Options[] = {
const OptionInfoRec *
xorg_tracker_available_options(int chipid, int busid)
{
- return Options;
+ return drv_options;
}
void
xorg_tracker_set_functions(ScrnInfoPtr scrn)
{
- scrn->PreInit = PreInit;
- scrn->ScreenInit = ScreenInit;
- scrn->SwitchMode = SwitchMode;
- scrn->AdjustFrame = AdjustFrame;
- scrn->EnterVT = EnterVT;
- scrn->LeaveVT = LeaveVT;
- scrn->FreeScreen = FreeScreen;
- scrn->ValidMode = ValidMode;
+ scrn->PreInit = drv_pre_init;
+ scrn->ScreenInit = drv_screen_init;
+ scrn->SwitchMode = drv_switch_mode;
+ scrn->AdjustFrame = drv_adjust_frame;
+ scrn->EnterVT = drv_enter_vt;
+ scrn->LeaveVT = drv_leave_vt;
+ scrn->FreeScreen = drv_free_screen;
+ scrn->ValidMode = drv_valid_mode;
}
+
+/*
+ * Internal function definitions
+ */
+
+static Bool drv_init_front_buffer_functions(ScrnInfoPtr pScrn);
+static Bool drv_close_screen(int scrnIndex, ScreenPtr pScreen);
+static Bool drv_save_hw_state(ScrnInfoPtr pScrn);
+static Bool drv_restore_hw_state(ScrnInfoPtr pScrn);
+
+
/*
- * Static Xorg funtctions
+ * Internal functions
*/
static Bool
-GetRec(ScrnInfoPtr pScrn)
+drv_get_rec(ScrnInfoPtr pScrn)
{
if (pScrn->driverPrivate)
return TRUE;
@@ -121,7 +138,7 @@ GetRec(ScrnInfoPtr pScrn)
}
static void
-FreeRec(ScrnInfoPtr pScrn)
+drv_free_rec(ScrnInfoPtr pScrn)
{
if (!pScrn)
return;
@@ -135,88 +152,21 @@ FreeRec(ScrnInfoPtr pScrn)
}
static void
-ProbeDDC(ScrnInfoPtr pScrn, int index)
+drv_probe_ddc(ScrnInfoPtr pScrn, int index)
{
ConfiguredMonitor = NULL;
}
static Bool
-CreateFrontBuffer(ScrnInfoPtr pScrn)
-{
- modesettingPtr ms = modesettingPTR(pScrn);
- unsigned handle, stride;
- struct pipe_texture *tex;
-
- ms->noEvict = TRUE;
-
- 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,
- 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;
-}
-
-static Bool
-crtc_resize(ScrnInfoPtr pScrn, int width, int height)
+drv_crtc_resize(ScrnInfoPtr pScrn, int width, int height)
{
modesettingPtr ms = modesettingPTR(pScrn);
- unsigned handle, stride;
PixmapPtr rootPixmap;
ScreenPtr pScreen = pScrn->pScreen;
if (width == pScrn->virtualX && height == pScrn->virtualY)
return TRUE;
- ErrorF("RESIZING TO %dx%d\n", width, height);
-
pScrn->virtualX = width;
pScrn->virtualY = height;
@@ -224,44 +174,25 @@ crtc_resize(ScrnInfoPtr pScrn, int width, int height)
* Remove the old framebuffer & texture.
*/
drmModeRmFB(ms->fd, ms->fb_id);
- pipe_texture_reference(&ms->root_texture, NULL);
-
+ if (!ms->destroy_front_buffer(pScrn))
+ FatalError("failed to destroy front buffer\n");
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;
+ pScrn->displayWidth = rootPixmap->devKind / (rootPixmap->drawable.bitsPerPixel / 8);
/* now create new frontbuffer */
- return CreateFrontBuffer(pScrn) && BindTextureToRoot(pScrn);
+ return ms->create_front_buffer(pScrn) && ms->bind_front_buffer(pScrn);
}
static const xf86CrtcConfigFuncsRec crtc_config_funcs = {
- crtc_resize
+ .resize = drv_crtc_resize
};
static Bool
-InitDRM(ScrnInfoPtr pScrn)
+drv_init_drm(ScrnInfoPtr pScrn)
{
modesettingPtr ms = modesettingPTR(pScrn);
@@ -281,18 +212,77 @@ InitDRM(ScrnInfoPtr pScrn)
return FALSE;
}
- if (!ms->api) {
- ms->api = drm_api_create();
+ return TRUE;
+}
+
+static Bool
+drv_init_resource_management(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+ /*
+ ScreenPtr pScreen = pScrn->pScreen;
+ PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
+ Bool fbAccessDisabled;
+ CARD8 *fbstart;
+ */
- if (!ms->api)
- return FALSE;
+ if (ms->screen || ms->kms)
+ return TRUE;
+
+ ms->api = drm_api_create();
+ if (ms->api) {
+ ms->screen = ms->api->create_screen(ms->api, ms->fd, NULL);
+
+ if (ms->screen)
+ return TRUE;
+
+ if (ms->api->destroy)
+ ms->api->destroy(ms->api);
+
+ ms->api = NULL;
}
+#ifdef HAVE_LIBKMS
+ if (!kms_create(ms->fd, &ms->kms))
+ return TRUE;
+#endif
+
+ return FALSE;
+}
+
+static Bool
+drv_close_resource_management(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+ int i;
+
+ if (ms->screen) {
+ assert(ms->ctx == NULL);
+
+ for (i = 0; i < XORG_NR_FENCES; i++) {
+ if (ms->fence[i]) {
+ ms->screen->fence_finish(ms->screen, ms->fence[i], 0);
+ ms->screen->fence_reference(ms->screen, &ms->fence[i], NULL);
+ }
+ }
+ ms->screen->destroy(ms->screen);
+ }
+ ms->screen = NULL;
+
+ if (ms->api && ms->api->destroy)
+ ms->api->destroy(ms->api);
+ ms->api = NULL;
+
+#ifdef HAVE_LIBKMS
+ if (ms->kms)
+ kms_destroy(&ms->kms);
+#endif
+
return TRUE;
}
static Bool
-PreInit(ScrnInfoPtr pScrn, int flags)
+drv_pre_init(ScrnInfoPtr pScrn, int flags)
{
xf86CrtcConfigPtr xf86_config;
modesettingPtr ms;
@@ -307,12 +297,12 @@ PreInit(ScrnInfoPtr pScrn, int flags)
pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
if (flags & PROBE_DETECT) {
- ProbeDDC(pScrn, pEnt->index);
+ drv_probe_ddc(pScrn, pEnt->index);
return TRUE;
}
/* Allocate driverPrivate */
- if (!GetRec(pScrn))
+ if (!drv_get_rec(pScrn))
return FALSE;
ms = modesettingPTR(pScrn);
@@ -349,7 +339,7 @@ PreInit(ScrnInfoPtr pScrn, int flags)
ms->fd = -1;
ms->api = NULL;
- if (!InitDRM(pScrn))
+ if (!drv_init_drm(pScrn))
return FALSE;
pScrn->monitor = pScrn->confScreen->monitor;
@@ -381,9 +371,9 @@ PreInit(ScrnInfoPtr pScrn, int flags)
/* Process the options */
xf86CollectOptions(pScrn, NULL);
- if (!(ms->Options = xalloc(sizeof(Options))))
+ if (!(ms->Options = xalloc(sizeof(drv_options))))
return FALSE;
- memcpy(ms->Options, Options, sizeof(Options));
+ memcpy(ms->Options, drv_options, sizeof(drv_options));
xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, ms->Options);
/* Allocate an xf86CrtcConfig */
@@ -398,18 +388,18 @@ PreInit(ScrnInfoPtr pScrn, int flags)
ms->SWCursor = TRUE;
}
- SaveHWState(pScrn);
+ drv_save_hw_state(pScrn);
- crtc_init(pScrn);
- output_init(pScrn);
+ xorg_crtc_init(pScrn);
+ xorg_output_init(pScrn);
if (!xf86InitialConfiguration(pScrn, TRUE)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
- RestoreHWState(pScrn);
+ drv_restore_hw_state(pScrn);
return FALSE;
}
- RestoreHWState(pScrn);
+ drv_restore_hw_state(pScrn);
/*
* If the driver can do gamma correction, it should call xf86SetGamma() here.
@@ -433,21 +423,23 @@ PreInit(ScrnInfoPtr pScrn, int flags)
xf86SetDpi(pScrn, 0, 0);
/* Load the required sub modules */
- if (!xf86LoadSubModule(pScrn, "fb")) {
+ if (!xf86LoadSubModule(pScrn, "fb"))
return FALSE;
- }
- xf86LoadSubModule(pScrn, "exa");
+ /* XXX: these aren't needed when we are using libkms */
+ if (!xf86LoadSubModule(pScrn, "exa"))
+ return FALSE;
#ifdef DRI2
- xf86LoadSubModule(pScrn, "dri2");
+ if (!xf86LoadSubModule(pScrn, "dri2"))
+ return FALSE;
#endif
return TRUE;
}
static Bool
-SaveHWState(ScrnInfoPtr pScrn)
+drv_save_hw_state(ScrnInfoPtr pScrn)
{
/*xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);*/
@@ -455,24 +447,45 @@ SaveHWState(ScrnInfoPtr pScrn)
}
static Bool
-RestoreHWState(ScrnInfoPtr pScrn)
+drv_restore_hw_state(ScrnInfoPtr pScrn)
{
/*xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);*/
return TRUE;
}
-static void xorgBlockHandler(int i, pointer blockData, pointer pTimeout,
- pointer pReadmask)
+static void drv_block_handler(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);
+ pScreen->BlockHandler = drv_block_handler;
+
+ if (ms->ctx) {
+ int j;
+
+ ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE, &ms->fence[XORG_NR_FENCES-1]);
+
+ if (ms->fence[0])
+ ms->ctx->screen->fence_finish(ms->ctx->screen, ms->fence[0], 0);
+
+ /* The amount of rendering generated by a block handler can be
+ * quite small. Let us get a fair way ahead of hardware before
+ * throttling.
+ */
+ for (j = 0; j < XORG_NR_FENCES - 1; j++)
+ ms->screen->fence_reference(ms->screen,
+ &ms->fence[j],
+ ms->fence[j+1]);
+
+ ms->screen->fence_reference(ms->screen,
+ &ms->fence[XORG_NR_FENCES-1],
+ NULL);
+ }
+
#ifdef DRM_MODE_FEATURE_DIRTYFB
{
@@ -482,7 +495,7 @@ static void xorgBlockHandler(int i, pointer blockData, pointer pTimeout,
if (num_cliprects) {
drmModeClip *clip = alloca(num_cliprects * sizeof(drmModeClip));
BoxPtr rect = REGION_RECTS(dirty);
- int i;
+ int i, ret;
/* XXX no need for copy? */
for (i = 0; i < num_cliprects; i++, rect++) {
@@ -493,7 +506,11 @@ static void xorgBlockHandler(int i, pointer blockData, pointer pTimeout,
}
/* TODO query connector property to see if this is needed */
- drmModeDirtyFB(ms->fd, ms->fb_id, clip, num_cliprects);
+ ret = drmModeDirtyFB(ms->fd, ms->fb_id, clip, num_cliprects);
+ if (ret) {
+ debug_printf("%s: failed to send dirty (%i, %s)\n",
+ __func__, ret, strerror(-ret));
+ }
DamageEmpty(ms->damage);
}
@@ -502,7 +519,7 @@ static void xorgBlockHandler(int i, pointer blockData, pointer pTimeout,
}
static Bool
-CreateScreenResources(ScreenPtr pScreen)
+drv_create_screen_resources(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
@@ -513,13 +530,13 @@ CreateScreenResources(ScreenPtr pScreen)
pScreen->CreateScreenResources = ms->createScreenResources;
ret = pScreen->CreateScreenResources(pScreen);
- pScreen->CreateScreenResources = CreateScreenResources;
+ pScreen->CreateScreenResources = drv_create_screen_resources;
- BindTextureToRoot(pScrn);
+ ms->bind_front_buffer(pScrn);
ms->noEvict = FALSE;
- AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ drv_adjust_frame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
#ifdef DRM_MODE_FEATURE_DIRTYFB
rootPixmap = pScreen->GetScreenPixmap(pScreen);
@@ -543,22 +560,25 @@ CreateScreenResources(ScreenPtr pScreen)
}
static Bool
-ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
VisualPtr visual;
- if (!InitDRM(pScrn))
+ if (!drv_init_drm(pScrn)) {
+ FatalError("Could not init DRM");
return FALSE;
+ }
- if (!ms->screen) {
- ms->screen = ms->api->create_screen(ms->api, ms->fd, NULL);
+ if (!drv_init_resource_management(pScrn)) {
+ FatalError("Could not init resource management (!pipe_screen && !libkms)");
+ return FALSE;
+ }
- if (!ms->screen) {
- FatalError("Could not init pipe_screen\n");
- return FALSE;
- }
+ if (!drv_init_front_buffer_functions(pScrn)) {
+ FatalError("Could not init front buffer manager");
+ return FALSE;
}
pScrn->pScreen = pScreen;
@@ -603,16 +623,22 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
fbPictureInit(pScreen, NULL, 0);
ms->blockHandler = pScreen->BlockHandler;
- pScreen->BlockHandler = xorgBlockHandler;
+ pScreen->BlockHandler = drv_block_handler;
ms->createScreenResources = pScreen->CreateScreenResources;
- pScreen->CreateScreenResources = CreateScreenResources;
+ pScreen->CreateScreenResources = drv_create_screen_resources;
xf86SetBlackWhitePixels(pScreen);
- ms->exa = xorg_exa_init(pScrn);
- ms->debug_fallback = debug_get_bool_option("XORG_DEBUG_FALLBACK", TRUE);
+ if (ms->screen) {
+ ms->exa = xorg_exa_init(pScrn, xf86ReturnOptValBool(ms->Options,
+ OPTION_2D_ACCEL, TRUE));
+ ms->debug_fallback = debug_get_bool_option("XORG_DEBUG_FALLBACK", TRUE);
- xorg_init_video(pScreen);
+ xorg_xv_init(pScreen);
+#ifdef DRI2
+ xorg_dri2_init(pScreen);
+#endif
+ }
miInitializeBackingStore(pScreen);
xf86SetBackingStore(pScreen);
@@ -631,7 +657,7 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pScreen->SaveScreen = xf86SaveScreen;
ms->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = CloseScreen;
+ pScreen->CloseScreen = drv_close_screen;
if (!xf86CrtcScreenInit(pScreen))
return FALSE;
@@ -644,17 +670,14 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
if (serverGeneration == 1)
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
-#if 1
-#ifdef DRI2
- driScreenInit(pScreen);
-#endif
-#endif
+ if (ms->winsys_screen_init)
+ ms->winsys_screen_init(pScrn);
- return EnterVT(scrnIndex, 1);
+ return drv_enter_vt(scrnIndex, 1);
}
static void
-AdjustFrame(int scrnIndex, int x, int y, int flags)
+drv_adjust_frame(int scrnIndex, int x, int y, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
@@ -670,23 +693,26 @@ AdjustFrame(int scrnIndex, int x, int y, int flags)
}
static void
-FreeScreen(int scrnIndex, int flags)
+drv_free_screen(int scrnIndex, int flags)
{
- FreeRec(xf86Screens[scrnIndex]);
+ drv_free_rec(xf86Screens[scrnIndex]);
}
static void
-LeaveVT(int scrnIndex, int flags)
+drv_leave_vt(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
modesettingPtr ms = modesettingPTR(pScrn);
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
int o;
+ if (ms->winsys_leave_vt)
+ ms->winsys_leave_vt(pScrn);
+
for (o = 0; o < config->num_crtc; o++) {
xf86CrtcPtr crtc = config->crtc[o];
- crtc_cursor_destroy(crtc);
+ xorg_crtc_cursor_destroy(crtc);
if (crtc->rotatedPixmap || crtc->rotatedData) {
crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap,
@@ -698,7 +724,7 @@ LeaveVT(int scrnIndex, int flags)
drmModeRmFB(ms->fd, ms->fb_id);
- RestoreHWState(pScrn);
+ drv_restore_hw_state(pScrn);
if (drmDropMaster(ms->fd))
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
@@ -711,7 +737,7 @@ LeaveVT(int scrnIndex, int flags)
* This gets called when gaining control of the VT, and from ScreenInit().
*/
static Bool
-EnterVT(int scrnIndex, int flags)
+drv_enter_vt(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
modesettingPtr ms = modesettingPTR(pScrn);
@@ -733,23 +759,26 @@ EnterVT(int scrnIndex, int flags)
*/
if (ms->SaveGeneration != serverGeneration) {
ms->SaveGeneration = serverGeneration;
- SaveHWState(pScrn);
+ drv_save_hw_state(pScrn);
}
- if (!CreateFrontBuffer(pScrn))
+ if (!ms->create_front_buffer(pScrn))
return FALSE;
- if (!flags && !BindTextureToRoot(pScrn))
+ if (!flags && !ms->bind_front_buffer(pScrn))
return FALSE;
if (!xf86SetDesiredModes(pScrn))
return FALSE;
+ if (ms->winsys_enter_vt)
+ ms->winsys_enter_vt(pScrn);
+
return TRUE;
}
static Bool
-SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+drv_switch_mode(int scrnIndex, DisplayModePtr mode, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
@@ -757,16 +786,21 @@ SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
}
static Bool
-CloseScreen(int scrnIndex, ScreenPtr pScreen)
+drv_close_screen(int scrnIndex, ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
modesettingPtr ms = modesettingPTR(pScrn);
if (pScrn->vtSema) {
- LeaveVT(scrnIndex, 0);
+ drv_leave_vt(scrnIndex, 0);
}
+
+ if (ms->winsys_screen_close)
+ ms->winsys_screen_close(pScrn);
+
#ifdef DRI2
- driCloseScreen(pScreen);
+ if (ms->screen)
+ xorg_dri2_close(pScreen);
#endif
pScreen->BlockHandler = ms->blockHandler;
@@ -780,14 +814,14 @@ CloseScreen(int scrnIndex, ScreenPtr pScreen)
}
#endif
- pipe_texture_reference(&ms->root_texture, NULL);
+ drmModeRmFB(ms->fd, ms->fb_id);
+ ms->destroy_front_buffer(pScrn);
if (ms->exa)
xorg_exa_close(pScrn);
+ ms->exa = NULL;
- if (ms->api && ms->api->destroy)
- ms->api->destroy(ms->api);
- ms->api = NULL;
+ drv_close_resource_management(pScrn);
drmClose(ms->fd);
ms->fd = -1;
@@ -798,9 +832,217 @@ CloseScreen(int scrnIndex, ScreenPtr pScreen)
}
static ModeStatus
-ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+drv_valid_mode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
{
return MODE_OK;
}
+
+/*
+ * Front buffer backing store functions.
+ */
+
+static Bool
+drv_destroy_front_buffer_ga3d(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+ pipe_texture_reference(&ms->root_texture, NULL);
+ return TRUE;
+}
+
+static Bool
+drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+ unsigned handle, stride;
+ struct pipe_texture *tex;
+ int ret;
+
+ ms->noEvict = TRUE;
+
+ 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))
+ goto err_destroy;
+
+ ret = drmModeAddFB(ms->fd,
+ pScrn->virtualX,
+ pScrn->virtualY,
+ pScrn->depth,
+ pScrn->bitsPerPixel,
+ stride,
+ handle,
+ &ms->fb_id);
+ if (ret) {
+ debug_printf("%s: failed to create framebuffer (%i, %s)",
+ __func__, ret, strerror(-ret));
+ goto err_destroy;
+ }
+
+ pScrn->frameX0 = 0;
+ pScrn->frameY0 = 0;
+ drv_adjust_frame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ pipe_texture_reference(&ms->root_texture, tex);
+ pipe_texture_reference(&tex, NULL);
+
+ return TRUE;
+
+err_destroy:
+ pipe_texture_reference(&tex, NULL);
+ return FALSE;
+}
+
+static Bool
+drv_bind_front_buffer_ga3d(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+ ScreenPtr pScreen = pScrn->pScreen;
+ PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
+ struct pipe_texture *check;
+
+ 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;
+}
+
+#ifdef HAVE_LIBKMS
+static Bool
+drv_destroy_front_buffer_kms(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+ ScreenPtr pScreen = pScrn->pScreen;
+ PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
+
+ /* XXX Do something with the rootPixmap.
+ * This currently works fine but if we are getting crashes in
+ * the fb functions after VT switches maybe look more into it.
+ */
+ (void)rootPixmap;
+
+ if (!ms->root_bo)
+ return TRUE;
+
+ kms_bo_unmap(ms->root_bo);
+ kms_bo_destroy(&ms->root_bo);
+ return TRUE;
+}
+
+static Bool
+drv_create_front_buffer_kms(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+ unsigned handle, stride;
+ struct kms_bo *bo;
+ unsigned attr[8];
+ int ret;
+
+ attr[0] = KMS_BO_TYPE;
+ attr[1] = KMS_BO_TYPE_SCANOUT;
+ attr[2] = KMS_WIDTH;
+ attr[3] = pScrn->virtualX;
+ attr[4] = KMS_HEIGHT;
+ attr[5] = pScrn->virtualY;
+ attr[6] = 0;
+
+ if (kms_bo_create(ms->kms, attr, &bo))
+ return FALSE;
+
+ if (kms_bo_get_prop(bo, KMS_PITCH, &stride))
+ goto err_destroy;
+
+ if (kms_bo_get_prop(bo, KMS_HANDLE, &handle))
+ goto err_destroy;
+
+ ret = drmModeAddFB(ms->fd,
+ pScrn->virtualX,
+ pScrn->virtualY,
+ pScrn->depth,
+ pScrn->bitsPerPixel,
+ stride,
+ handle,
+ &ms->fb_id);
+ if (ret) {
+ debug_printf("%s: failed to create framebuffer (%i, %s)",
+ __func__, ret, strerror(-ret));
+ goto err_destroy;
+ }
+
+ pScrn->frameX0 = 0;
+ pScrn->frameY0 = 0;
+ drv_adjust_frame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ ms->root_bo = bo;
+
+ return TRUE;
+
+err_destroy:
+ kms_bo_destroy(&bo);
+ return FALSE;
+}
+
+static Bool
+drv_bind_front_buffer_kms(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+ ScreenPtr pScreen = pScrn->pScreen;
+ PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
+ unsigned stride;
+ void *ptr;
+
+ if (kms_bo_get_prop(ms->root_bo, KMS_PITCH, &stride))
+ return FALSE;
+
+ if (kms_bo_map(ms->root_bo, &ptr))
+ goto err_destroy;
+
+ pScreen->ModifyPixmapHeader(rootPixmap,
+ pScreen->width,
+ pScreen->height,
+ pScreen->rootDepth,
+ pScrn->bitsPerPixel,
+ stride,
+ ptr);
+ return TRUE;
+
+err_destroy:
+ kms_bo_destroy(&ms->root_bo);
+ return FALSE;
+}
+#endif /* HAVE_LIBKMS */
+
+static Bool drv_init_front_buffer_functions(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+ if (ms->screen) {
+ ms->destroy_front_buffer = drv_destroy_front_buffer_ga3d;
+ ms->create_front_buffer = drv_create_front_buffer_ga3d;
+ ms->bind_front_buffer = drv_bind_front_buffer_ga3d;
+#ifdef HAVE_LIBKMS
+ } else if (ms->kms) {
+ ms->destroy_front_buffer = drv_destroy_front_buffer_kms;
+ ms->create_front_buffer = drv_create_front_buffer_kms;
+ ms->bind_front_buffer = drv_bind_front_buffer_kms;
+#endif
+ } else
+ return FALSE;
+
+ return TRUE;
+}
+
/* vim: set sw=4 ts=8 sts=4: */