xf86-video-intel: Branch 'intel-kernelmode' - src/drmmode_display.c src/drmmode_display.h src/i830_driver.c src/i830_exa.c src/i830.h src/i830_memory.c

Dave Airlie airlied at kemper.freedesktop.org
Wed May 7 23:23:24 PDT 2008


 src/drmmode_display.c |   70 +++++++++++++++++++++++++-----
 src/drmmode_display.h |    2 
 src/i830.h            |    3 -
 src/i830_driver.c     |    7 ++-
 src/i830_exa.c        |    5 +-
 src/i830_memory.c     |  113 ++++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 184 insertions(+), 16 deletions(-)

New commits:
commit 653dad1c13c929266a7bfb494d4b7276b5d83410
Author: Dave Airlie <airlied at linux.ie>
Date:   Thu May 8 16:21:56 2008 +1000

    drm: add support for resizing framebuffer in theory.

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index eff42c0..1551691 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -32,12 +32,21 @@
 #ifdef XF86DRM_MODE
 #include "i830.h"
 
+static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height);
+
 static Bool
 drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
 {
+	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+	drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[0]->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+	Bool ret;
+
+	ErrorF("resize called %d %d\n", width, height);
+	ret = drmmode_resize_fb(scrn, drmmode, width, height);
 	scrn->virtualX = width;
 	scrn->virtualY = height;
-	return TRUE;
+	return ret;
 }
 
 static void
@@ -555,18 +564,14 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, char *busId, char
 	if (!drmmode->mode_res)
 		return FALSE;
 
-	drmmode->mode_fb = drmModeGetFB(drmmode->fd, drmmode->mode_res->fbs[0]);
-	if (!drmmode->mode_fb)
-		return FALSE;
-
-	xf86CrtcSetSizeRange(pScrn, 320, 200, drmmode->mode_fb->width, drmmode->mode_fb->height);
+	xf86CrtcSetSizeRange(pScrn, 320, 200, drmmode->mode_res->max_width, drmmode->mode_res->max_height);
 	for (i = 0; i < drmmode->mode_res->count_crtcs; i++)
 		drmmode_crtc_init(pScrn, drmmode, i);
 
 	for (i = 0; i < drmmode->mode_res->count_outputs; i++)
 		drmmode_output_init(pScrn, drmmode, i);
 
-	xf86InitialConfiguration(pScrn, FALSE);
+	xf86InitialConfiguration(pScrn, TRUE);
 
 	return TRUE;
 }
@@ -577,17 +582,23 @@ Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, dri_bufmgr *bufm
 	return TRUE;
 }
 
-void drmmode_set_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int width, int height, int pitch, drmBO *bo)
+void drmmode_set_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height, int pitch, drmBO *bo)
 {
 	int ret;
 
-	ret = drmModeAddFB(drmmode->fd, width, height, pScrn->depth,
-			   pScrn->depth, pitch, bo->handle, &drmmode->fb_id);
+	ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth,
+			   scrn->depth, pitch, bo->handle, &drmmode->fb_id);
 
 	if (ret) {
 		ErrorF("Failed to add fb\n");
 	}
-	ErrorF("Add fb id %d\n", drmmode->fb_id);
+
+	drmmode->mode_fb = drmModeGetFB(drmmode->fd, drmmode->fb_id);
+	if (!drmmode->mode_fb)
+		return;
+
+
+	ErrorF("Add fb id %d %d %d\n", drmmode->fb_id, width, height);
 }
 
 Bool drmmode_is_rotate_pixmap(ScrnInfoPtr pScrn, pointer pPixData, dri_bo **bo)
@@ -607,9 +618,44 @@ Bool drmmode_is_rotate_pixmap(ScrnInfoPtr pScrn, pointer pPixData, dri_bo **bo)
 			return TRUE;
 		}
 	}
-	*bo = NULL;
 	return FALSE;
 
 }
+
+static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height)
+{
+	uint32_t handle;
+	int pitch;
+	int ret;
+
+	ErrorF("current width %d height %d\n", drmmode->mode_fb->width, drmmode->mode_fb->height);
+
+	if (drmmode->mode_fb->width == width)
+		return TRUE;
+
+	if (!drmmode->create_new_fb)
+		return FALSE;
+
+	handle = drmmode->create_new_fb(scrn, width, height, &pitch);
+	if (handle == 0)
+		return FALSE;
+
+	ErrorF("pitch is %d\n", pitch);
+	ret = drmModeReplaceFB(drmmode->fd, drmmode->fb_id, 
+			       width, height,
+			       scrn->depth, scrn->depth, pitch,
+			       handle);
+
+	if (ret)
+		return FALSE;
+
+	drmModeFreeFB(drmmode->mode_fb);
+	drmmode->mode_fb = drmModeGetFB(drmmode->fd, drmmode->fb_id);
+	if (!drmmode->mode_fb)
+		return;
+	
+	return TRUE;
+}
+
 #endif
 
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index 92b6143..dc68892 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -38,6 +38,8 @@ typedef struct {
   drmModeFBPtr mode_fb;
   int cpp;
   dri_bufmgr *bufmgr;
+
+  uint32_t (*create_new_fb)(ScrnInfoPtr pScrn, int width, int height, int *pitch);
 } drmmode_rec, *drmmode_ptr;
 
 typedef struct {
diff --git a/src/i830.h b/src/i830.h
index 68f9bb6..a05da9c 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -760,6 +760,7 @@ extern void I830DRI2Unlock(ScreenPtr pScrn);
 extern void I830InitBufMgr(ScrnInfoPtr pScrn);
 #endif
 
+void i830_update_front_offset(ScrnInfoPtr pScrn);
 unsigned long intel_get_pixmap_offset(PixmapPtr pPix);
 unsigned long intel_get_pixmap_pitch(PixmapPtr pPix);
 extern Bool I830AccelInit(ScreenPtr pScreen);
@@ -795,7 +796,7 @@ extern long I830CheckAvailableMemory(ScrnInfoPtr pScrn);
 Bool i830_allocate_2d_memory(ScrnInfoPtr pScrn);
 Bool i830_allocate_texture_memory(ScrnInfoPtr pScrn);
 Bool i830_allocate_3d_memory(ScrnInfoPtr pScrn);
-
+extern uint32_t i830_create_new_fb(ScrnInfoPtr pScrn, int width, int height, int *pitch);
 extern Bool I830IsPrimary(ScrnInfoPtr pScrn);
 
 extern Bool I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg,
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 953762b..35368a3 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -808,11 +808,12 @@ I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
    }
 }
 
-static void
+void
 i830_update_front_offset(ScrnInfoPtr pScrn)
 {
    ScreenPtr pScreen = pScrn->pScreen;
    I830Ptr pI830 = I830PTR(pScrn);
+   int pitch = pScrn->displayWidth * pI830->cpp;
 
    /* Update buffer locations, which may have changed as a result of
     * i830_bind_all_memory().
@@ -824,7 +825,7 @@ i830_update_front_offset(ScrnInfoPtr pScrn)
     */
    if (!pI830->starting) {
       if (!pScreen->ModifyPixmapHeader(pScreen->GetScreenPixmap(pScreen),
-				       -1, -1, -1, -1, -1,
+				       pScrn->virtualX, pScrn->virtualY, -1, -1, pitch,
 				       (pointer)(pI830->FbBase +
 						 pScrn->fbOffset)))
        FatalError("Couldn't adjust screen pixmap\n");
@@ -1648,6 +1649,8 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
 	   return FALSE;
        }
 
+       pI830->drmmode.create_new_fb = i830_create_new_fb;
+
        pI830->drmSubFD = pI830->drmmode.fd;
        xfree(bus_id);
    
diff --git a/src/i830_exa.c b/src/i830_exa.c
index 8b81b1d..3d60f51 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -560,14 +560,17 @@ static Bool I830EXAModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
 	/* this is the front buffer pixmap so set it up as such..*/
         driver_priv->flags |= I830_EXA_PIXMAP_IS_FRONTBUFFER;
 
+	ErrorF("FRONTBUFFER HANDLE CHANGING %p\n", driver_priv->bo);
 	/* get a reference to the front buffer handle */
+	if (driver_priv->bo)
+		dri_bo_unreference(driver_priv->bo);
 	driver_priv->bo =
 	    intel_ttm_bo_create_from_handle(pI830->bufmgr, "front",
 					    pI830->front_buffer->bo.handle);
+
 	miModifyPixmapHeader(pPixmap, width, height, depth,
 			     bitsPerPixel, devKind, NULL);
 
-
 	return TRUE;
     }
     return FALSE;
diff --git a/src/i830_memory.c b/src/i830_memory.c
index a3bda03..54811ef 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -2060,3 +2060,116 @@ I830CheckAvailableMemory(ScrnInfoPtr pScrn)
 
     return maxPages * 4;
 }
+
+#ifdef XF86DRI_MM
+i830_memory *
+i830_allocate_framebuffer_new(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox)
+{
+    unsigned int pitch = pScrn->displayWidth * pI830->cpp;
+    unsigned long minspace, avail;
+    int cacheLines, maxCacheLines;
+    int align;
+    long size, fb_height;
+    char *name;
+    int flags;
+    i830_memory *front_buffer = NULL;
+    Bool tiling;
+
+    flags = ALLOW_SHARING;
+
+    /* Clear everything first. */
+    memset(FbMemBox, 0, sizeof(*FbMemBox));
+
+    /* We'll allocate the fb such that the root window will fit regardless of
+     * rotation.
+     */
+    if (pScrn->virtualX > pScrn->virtualY)
+	fb_height = pScrn->virtualX;
+    else
+	fb_height = pScrn->virtualY;
+
+    FbMemBox->x1 = 0;
+    FbMemBox->x2 = pScrn->displayWidth;
+    FbMemBox->y1 = 0;
+    FbMemBox->y2 = fb_height;
+
+    /* Calculate how much framebuffer memory to allocate.  For the
+     * initial allocation, calculate a reasonable minimum.  This is
+     * enough for the virtual screen size, plus some pixmap cache
+     * space if we're using XAA.
+     */
+    minspace = pitch * pScrn->virtualY;
+    avail = pScrn->videoRam * 1024;
+    cacheLines = 0;
+
+    size = pitch * (fb_height + cacheLines);
+    size = ROUND_TO_PAGE(size);
+
+    name = "front buffer";
+
+    /* Front buffer tiling has to be disabled with G965 XAA because some of the
+     * acceleration operations (non-XY COLOR_BLT) can't be done to tiled
+     * buffers.
+     */
+    if (!pI830->useEXA && IS_I965G(pI830))
+	tiling = FALSE;
+    else
+	tiling = pI830->tiling;
+
+    if (pI830->use_drm_mode)
+      tiling = FALSE;
+
+    /* Attempt to allocate it tiled first if we have page flipping on. */
+    if (tiling && IsTileable(pScrn, pitch)) {
+	/* XXX: probably not the case on 965 */
+	if (IS_I9XX(pI830))
+	    align = MB(1);
+	else
+	    align = KB(512);
+	front_buffer = i830_allocate_memory_tiled(pScrn, name, size,
+						  pitch, align, flags,
+						  TILE_XMAJOR);
+    }
+
+    /* If not, attempt it linear */
+    if (front_buffer == NULL) {
+	front_buffer = i830_allocate_memory(pScrn, name, size, KB(64), flags);
+    }
+
+    if (front_buffer == NULL) {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate "
+		   "framebuffer. Is your VideoRAM set too low?\n");
+
+	return NULL;
+    }
+
+    return front_buffer;
+}
+
+uint32_t i830_create_new_fb(ScrnInfoPtr pScrn, int width, int height, int *pitch)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    i830_memory *old_buffer;
+
+    pScrn->virtualX = width;
+    pScrn->virtualY = height;
+    pScrn->displayWidth = (pScrn->virtualX + 63) & ~63;
+
+    *pitch = pScrn->displayWidth * pI830->cpp;
+
+    old_buffer = pI830->front_buffer;
+
+    pI830->front_buffer =
+	i830_allocate_framebuffer_new(pScrn, pI830, &pI830->FbMemBox);
+
+    ErrorF("old front size %08x, new front size %08x\n", old_buffer->bo.size, pI830->front_buffer->bo.size);
+    ErrorF("old front offset %08x, new front offset %08x\n", old_buffer->bo.offset, pI830->front_buffer->bo.offset);
+
+    i830_free_memory(pScrn, old_buffer);
+
+    i830_update_front_offset(pScrn);
+
+    return pI830->front_buffer->bo.handle;
+}
+
+#endif


More information about the xorg-commit mailing list