Mesa (master): st/xorg: Massivly redo root pixmap creation

Jakob Bornecrantz wallbraker at kemper.freedesktop.org
Mon Oct 19 21:09:17 UTC 2009


Module: Mesa
Branch: master
Commit: 846da0bfdae971cba84cd2ad9217c74c62e6bce9
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=846da0bfdae971cba84cd2ad9217c74c62e6bce9

Author: Jakob Bornecrantz <jakob at vmware.com>
Date:   Sun Oct 18 15:42:25 2009 +0200

st/xorg: Massivly redo root pixmap creation

---

 src/gallium/state_trackers/xorg/xorg_driver.c  |  122 ++++++++++++++++--------
 src/gallium/state_trackers/xorg/xorg_exa.c     |   44 +++++++++
 src/gallium/state_trackers/xorg/xorg_tracker.h |    9 ++
 3 files changed, 137 insertions(+), 38 deletions(-)

diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c
index ab6c3d7..24d3c23 100644
--- a/src/gallium/state_trackers/xorg/xorg_driver.c
+++ b/src/gallium/state_trackers/xorg/xorg_driver.c
@@ -144,20 +144,22 @@ static Bool
 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;
-    xorg_exa_set_displayed_usage(rootPixmap);
-    pScreen->ModifyPixmapHeader(rootPixmap,
-				pScrn->virtualX, pScrn->virtualY,
-				pScrn->depth, pScrn->bitsPerPixel,
-				pScrn->displayWidth * pScrn->bitsPerPixel / 8,
-				NULL);
-    ms->noEvict = FALSE;
 
-    handle = xorg_exa_get_pixmap_handle(rootPixmap, &stride);
+    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,
@@ -166,12 +168,39 @@ CreateFrontBuffer(ScrnInfoPtr pScrn)
 		 pScrn->bitsPerPixel,
 		 stride,
 		 handle,
-		 &ms->fb_id);
+                 &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;
 }
 
@@ -179,10 +208,9 @@ static Bool
 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;
@@ -192,13 +220,40 @@ crtc_resize(ScrnInfoPtr pScrn, int width, int height)
     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 = {
@@ -429,7 +484,6 @@ CreateScreenResources(ScreenPtr pScreen)
     modesettingPtr ms = modesettingPTR(pScrn);
     PixmapPtr rootPixmap;
     Bool ret;
-    unsigned handle, stride;
 
     ms->noEvict = TRUE;
 
@@ -437,29 +491,14 @@ CreateScreenResources(ScreenPtr pScreen)
     ret = pScreen->CreateScreenResources(pScreen);
     pScreen->CreateScreenResources = CreateScreenResources;
 
-    rootPixmap = pScreen->GetScreenPixmap(pScreen);
-
-    xorg_exa_set_displayed_usage(rootPixmap);
-    xorg_exa_set_shared_usage(rootPixmap);
-    if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, NULL))
-	FatalError("Couldn't adjust screen pixmap\n");
+    BindTextureToRoot(pScrn);
 
     ms->noEvict = FALSE;
 
-    handle = xorg_exa_get_pixmap_handle(rootPixmap, &stride);
-
-    drmModeAddFB(ms->fd,
-		 pScrn->virtualX,
-		 pScrn->virtualY,
-		 pScrn->depth,
-		 pScrn->bitsPerPixel,
-		 stride,
-		 handle,
-                 &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);
 
@@ -472,6 +511,8 @@ CreateScreenResources(ScreenPtr pScreen)
                   "Failed to create screen damage record\n");
        return FALSE;
     }
+#else
+    (void)rootPixmap;
 #endif
 
     return ret;
@@ -684,8 +725,11 @@ EnterVT(int scrnIndex, int flags)
 	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;
@@ -725,6 +769,8 @@ CloseScreen(int scrnIndex, ScreenPtr pScreen)
     }
 #endif
 
+    pipe_texture_reference(&ms->root_texture, NULL);
+
     if (ms->exa)
 	xorg_exa_close(pScrn);
 
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c
index a1c0721..ca25d90 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa.c
@@ -708,6 +708,50 @@ xorg_exa_get_texture(PixmapPtr pPixmap)
    return tex;
 }
 
+Bool
+xorg_exa_set_texture(PixmapPtr pPixmap, struct  pipe_texture *tex)
+{
+    struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
+
+    int mask = PIPE_TEXTURE_USAGE_PRIMARY | PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+
+    if (!priv)
+	return FALSE;
+
+    if (pPixmap->drawable.width != tex->width[0] ||
+	pPixmap->drawable.height != tex->height[0])
+	return FALSE;
+
+    pipe_texture_reference(&priv->tex, tex);
+    priv->tex_flags = tex->tex_usage & mask;
+
+    return TRUE;
+}
+
+struct pipe_texture *
+xorg_exa_create_root_texture(ScrnInfoPtr pScrn,
+			     int width, int height,
+			     int depth, int bitsPerPixel)
+{
+    modesettingPtr ms = modesettingPTR(pScrn);
+    struct exa_context *exa = ms->exa;
+    struct pipe_texture template;
+
+    memset(&template, 0, sizeof(template));
+    template.target = PIPE_TEXTURE_2D;
+    exa_get_pipe_format(depth, &template.format, &bitsPerPixel);
+    pf_get_block(template.format, &template.block);
+    template.width[0] = width;
+    template.height[0] = height;
+    template.depth[0] = 1;
+    template.last_level = 0;
+    template.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
+    template.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
+    template.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+
+    return exa->scrn->texture_create(exa->scrn, &template);
+}
+
 void
 xorg_exa_close(ScrnInfoPtr pScrn)
 {
diff --git a/src/gallium/state_trackers/xorg/xorg_tracker.h b/src/gallium/state_trackers/xorg/xorg_tracker.h
index 24e1a49..6130cf6 100644
--- a/src/gallium/state_trackers/xorg/xorg_tracker.h
+++ b/src/gallium/state_trackers/xorg/xorg_tracker.h
@@ -92,6 +92,7 @@ typedef struct _modesettingRec
     struct pipe_context *ctx;
     boolean d_depth_bits_last;
     boolean ds_depth_bits_last;
+    struct pipe_texture *root_texture;
 
     /* exa */
     struct exa_context *exa;
@@ -121,6 +122,14 @@ xorg_exa_set_displayed_usage(PixmapPtr pPixmap);
 int
 xorg_exa_set_shared_usage(PixmapPtr pPixmap);
 
+Bool
+xorg_exa_set_texture(PixmapPtr pPixmap, struct  pipe_texture *tex);
+
+struct pipe_texture *
+xorg_exa_create_root_texture(ScrnInfoPtr pScrn,
+			     int width, int height,
+			     int depth, int bpp);
+
 void *
 xorg_exa_init(ScrnInfoPtr pScrn);
 




More information about the mesa-commit mailing list