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